Question Moyen rapide d'obtenir les dimensions de l'image (pas de taille de fichier)


je recherche un vite façon d'obtenir la hauteur et la largeur d'une image en pixels. Il devrait gérer au moins JPG, PNG et TIFF, mais le plus sera le mieux. Je souligne vite parce que mes images sont assez grosses (jusqu’à 250 Mo) et il faut tellement de temps pour obtenir la taille avec ImageMagick identify car il lit évidemment les images dans leur ensemble d’abord.

De préférence, je recherche un moyen qui fonctionne bien dans Ruby, ou même dans Rails 3.

Je connais la théorie (divers formats d'image, leurs en-têtes et leurs différences, etc.). En effet, je demande une sorte de bibliothèque capable de résoudre mon problème de manière assez générique.

Je viens de trouver http://imagesize.rubyforge.org ce qui semble prometteur bien que le développement semble être mort.


108
2018-01-12 14:41


origine


Réponses:


  • le file commande imprime les dimensions de plusieurs formats d'image (par exemple, PNG, GIF, JPEG, mais pas PPM, WEBP) et lit uniquement l'en-tête.

  • exiv2 vous donne des dimensions pour de nombreux formats, y compris JPEG, TIFF, PNG, GIF, WEBP, même si aucun en-tête EXIF ​​n'est présent. On ne sait pas si elle lit la totalité des données pour cela. Voir la page de manuel d'exiv2 pour tous les formats d'image pris en charge.

  • le identify commande (à partir d'ImageMagick) imprime beaucoup d'informations d'image pour une grande variété d'images. Il semble se limiter à lire la partie en-tête (voir les commentaires).

  • head -n1 vous donnera les dimensions pour les formats PPM, PGM.

Pour les formats populaires sur le Web, les deux exiv2 et identify fera le travail. Selon le cas d'utilisation, vous devrez peut-être écrire votre propre script qui combine / analyse les sorties de plusieurs outils.


157
2018-01-12 15:18



Je ne suis pas sûr d'avoir php installé, mais cette fonction PHP est très pratique

 php -r "print_r(getimagesize('http://www.google.com/images/logos/ps_logo2.png'));"

26
2018-01-12 14:52



Vous pouvez utiliser les images de ImageMagick identifier fonction. Voici comment vous le faites en bash (Note $ 0 est le chemin de l’image):

width=$(identify -format "%w" "$0")> /dev/null
height=$(identify -format "%h" "$0")> /dev/null

Et cela cache également des messages d'erreur potentiels. Implémentations modernes de identify ne lisez que l'en-tête, pas l'image entière, donc c'est rapide. Pas sûr comment il se compare à d'autres méthodes cependant.


9
2017-10-12 00:37



https://joseluisbz.wordpress.com/2013/08/06/obtaining-size-or-dimension-of-images/ (BMP, PNG, GIF, JPG, TIF ou WMF)

Ici pour deux formats PNG et JPG.

Mon code provient d'une classe conçue pour mon usage, que vous pouvez modifier en fonction de vos besoins.

Veuillez vérifier ces fonctions / méthodes en utilisant PHP:

  public function ByteStreamImageString($ByteStream,&$Formato,&$Alto,&$Ancho) {
    $Alto = 0;
    $Ancho = 0;
    $Formato = -1;
    $this->HexImageString = "Error";
    if (ord($ByteStream[0])==137 && ord($ByteStream[1])==80 && ord($ByteStream[2])==78){
      $Formato = 1; //PNG
      $Alto = $this->Byte2PosInt($ByteStream[22],$ByteStream[23]);
      $Ancho = $this->Byte2PosInt($ByteStream[18],$ByteStream[19]);
    }
    if (ord($ByteStream[0])==255 && ord($ByteStream[1])==216
        && ord($ByteStream[2])==255 && ord($ByteStream[3])==224){
      $Formato = 2; //JPG
      $PosJPG = 2;
      while ($PosJPG<strlen($ByteStream)){
        if (sprintf("%02X%02X", ord($ByteStream[$PosJPG+0]),ord($ByteStream[$PosJPG+1]))=="FFC0"){
          $Alto = $this->Byte2PosInt($ByteStream[$PosJPG+5],$ByteStream[$PosJPG+6]);
          $Ancho = $this->Byte2PosInt($ByteStream[$PosJPG+7],$ByteStream[$PosJPG+8]);
        }
        $PosJPG = $PosJPG+2+$this->Byte2PosInt($ByteStream[$PosJPG+2],$ByteStream[$PosJPG+3]);
      }
    }
    if ($Formato > 0){
      $this->HexImageString = "";
      $Salto = 0;
      for ($i=0;$i < strlen($ByteStream); $i++){
        $Salto++;
        $this->HexImageString .= sprintf("%02x", ord($ByteStream[$i]));
        if ($Salto==64){
          $this->HexImageString .= "\n";
          $Salto = 0;
        }
      }
    }
  }


  private function Byte2PosInt($Byte08,$Byte00) {
    return ((ord($Byte08) & 0xFF) << 8)|((ord($Byte00) & 0xFF) << 0);
  }

Utiliser le code PHP:

      $iFormato = NULL;//Format PNG or JPG
      $iAlto = NULL; //High
      $iAncho = NULL;//Wide
      ByteStreamImageString($ImageJPG,$iFormato,$iAlto,$iAncho);//The Dimensions will stored in  iFormato,iAlto,iAncho

Maintenant, ces fonctions / méthodes utilisant JAVA:

  private void ByteStreamImageString(byte[] ByteStream,int[] Frmt,int[] High,int[] Wide) {
    High[0] = 0;
    Wide[0] = 0;
    Frmt[0] = -1;
    this.HexImageString = "Error";
    if ((int)(ByteStream[0]&0xFF)==137 && (int)(ByteStream[1]&0xFF)==80 &&(int)(ByteStream[2]&0xFF)==78){
      Frmt[0] = 1; //PNG
      High[0] = this.Byte2PosInt(ByteStream[22],ByteStream[23]);
      Wide[0] = this.Byte2PosInt(ByteStream[18],ByteStream[19]);
    }
    if ((int)(ByteStream[0]&0xFF)==255 && (int)(ByteStream[1]&0xFF)==216
        &&(int)(ByteStream[2]&0xFF)==255 && (int)(ByteStream[3]&0xFF)==224){
      Frmt[0] = 2; //JPG
      int PosJPG = 2;
      while (PosJPG<ByteStream.length){
        if (String.format("%02X%02X", ByteStream[PosJPG+0],ByteStream[PosJPG+1]).equals("FFC0")){
          High[0] = this.Byte2PosInt(ByteStream[PosJPG+5],ByteStream[PosJPG+6]);
          Wide[0] = this.Byte2PosInt(ByteStream[PosJPG+7],ByteStream[PosJPG+8]);
        }
        PosJPG = PosJPG+2+this.Byte2PosInt(ByteStream[PosJPG+2],ByteStream[PosJPG+3]);
      }
    }
    if (Frmt[0] > 0){
      this.HexImageString = "";
      int Salto = 0;
      for (int i=0;i < ByteStream.length; i++){
        Salto++;
        this.HexImageString += String.format("%02x", ByteStream[i]);
        if (Salto==64){
          this.HexImageString += "\n";
          Salto = 0;
        }
      }
    }
  }


  private Integer Byte2PosInt(byte Byte08, byte Byte00) {
    return new Integer (((Byte08 & 0xFF) << 8)|((Byte00 & 0xFF) << 0));
  }

En utilisant le code Java:

        int[] iFormato = new int[1]; //Format PNG or JPG
        int[] iAlto = new int[1]; //High
        int[] iAncho = new int[1]; //Wide
        ByteStreamImageString(ImageJPG,iFormato,iAlto,iAncho); //The Dimensions will stored in  iFormato[0],iAlto[0],iAncho[0]

4
2017-07-17 17:36



C'est les dimensions en pixels que vous voulez (largeur et hauteur), je suppose?

Je pense que la plupart des formats de fichiers ont des informations d'en-tête définissant les dimensions, de sorte que le logiciel lisant le fichier puisse savoir combien d'espace il doit réserver avant de commencer à lire le fichier. Certains formats de fichiers de type "brut" peuvent être simplement un flux d'octets avec un octet de "fin de ligne" à la fin de chaque ligne horizontale de pixels (auquel cas le logiciel doit lire la première ligne et diviser la taille du flux d'octets) par la longueur de la ligne pour obtenir la hauteur).

Je ne pense pas que vous puissiez le faire d'une manière "générique", car vous devez comprendre le format de fichier (ou utiliser une bibliothèque bien sûr) pour savoir comment le lire. Vous pouvez probablement trouver du code qui, dans la plupart des cas, donne une estimation approximative des dimensions sans lire le fichier en entier, mais je pense que certains types de fichiers peuvent vous obliger à lire le fichier en entier pour vous assurer de ses dimensions. Je m'attends à ce que la plupart des formats d'image centrés sur le Web aient un en-tête avec de telles informations afin que le navigateur puisse créer les dimensions de la boîte avant le chargement de l'image entière.

Je suppose qu'une bonne bibliothèque aurait des méthodes pour obtenir les dimensions des fichiers qu'elle gère et que ces méthodes seraient implémentées aussi efficacement que possible.

Mettre à jour: imageinfo semble faire ce que vous voulez. (Je n'ai pas testé)


1
2018-01-12 15:03



Si vous avez des informations EXIF ​​dans les images, vous pouvez simplement lire l'en-tête EXIF.


0
2018-01-12 14:45



-ping est une option qui semble avoir été introduite à cet effet.

Cependant, à partir d'ImageMagick 6.7.7, je n'observe pas de ralentissement, même pour tous les gros fichiers, par exemple:

head -c 100000000 /dev/urandom > f.gray
# I don't recommend that you run this command as it eats a lot of memory.
convert -depth 8 -size 20000x10000 f.gray f.png
identify f.png

Pouvez-vous produire un exemple d'image d'entrée pour laquelle il est encore lent?


0
2017-09-28 15:50