Existe-t-il une commande Shell qui renvoie la taille en pixels d'une image?
J'essaie de produire un gif animé à partir de différents gifs de différentes tailles en utilisant convert
(par exemple convert -delay 50 1.gif 2.gif -loop 0 animated.gif
).
Le problème est que la conversion chevauche simplement les images en utilisant la taille de la première image comme taille du gif animé, et comme elles ont des tailles différentes, le résultat est un peu compliqué, avec des morceaux des anciennes images affichés sous les nouvelles.
trouvé une solution: identify
, qui fait partie du paquet imagemagick, fait exactement ce dont j'ai besoin
$ identify color.jpg
> color.jpg JPEG 1980x650 1980x650+0+0 8-bit DirectClass 231KB 0.000u 0:00.000
Plutôt que d'analyser la sortie de identify
à l'œil nu ou à l'aide d'utilitaires de texte, vous pouvez utiliser son -format
option pour afficher la largeur et la hauteur dans le format qui vous convient le mieux. Par exemple:
$ identify -format '%w %h' img.png
100 200
$ identify -format '%wx%h' img.png
100x200
Une liste des propriétés d'image que vous pouvez afficher peut être trouvée sur cette page , mais pour la question ici, il semble que tout ce dont vous avez besoin soit %w
et %h
, qui donnent respectivement la largeur et la hauteur de l'image en pixels.
La flexibilité offerte par -format
m'a été utile pour trouver les plus grandes images en termes de pixels, en affichant %[fx:w*h]
pour un certain nombre d'images et le tri de la sortie.
Vous voudrez peut-être spécifier le -ping
option si vous traitez de nombreuses images, en utilisant des échappements plus compliqués et que vous voulez vous assurer que le programme ne perd pas de temps à charger les images entières. Avec des évasions simples, -ping
devrait être la valeur par défaut. Plus d'informations sur le choix entre -ping
et +ping
peut être trouvé ici .
vous pouvez simplement utiliser la commande "fichier" pour obtenir les informations dont vous avez besoin:
~# file cha_2.png
cha_2.png: PNG image data, 656 x 464, 8-bit/color RGB, non-interlaced
tilisez identify
pour voir les tailles:
$ identify color.jpg
> color.jpg JPEG 1980x650 1980x650+0+0 8-bit DirectClass 231KB 0.000u 0:00.000
Extraire la valeur via cut | sed
, du champ 3:
identify ./color.jpg | cut -f 3 -d " " | sed s/x.*// #width
identify ./color.jpg | cut -f 3 -d " " | sed s/.*x// #height
Affecter à la variable:
W=`identify ./color.jpg | cut -f 3 -d " " | sed s/x.*//` #width
H=`identify ./color.jpg | cut -f 3 -d " " | sed s/.*x//` #height
echo $W
> 1980
echo $H
> 650
display
et file
sont tous deux assez lents et ont le potentiel de mettre à genoux des systèmes même assez performants traitant de nombreux fichiers multiples. Un petit test:
$ du -h *.png --total | tail -n 1
9.2M total
$ ls -l *.png | wc -l
107
$ /usr/bin/time file *.png
--> 0.37user 0.26system 0:06.93elapsed 9%CPU (0avgtext+0avgdata 37232maxresident)k
22624inputs+0outputs (9major+2883minor)pagefaults 0swaps
$ /usr/bin/time identify *.png
--> 0.56user 0.22system 0:06.77elapsed 11%CPU (0avgtext+0avgdata 25648maxresident)k
34256inputs+0outputs (119major+2115minor)pagefaults 0swaps
En lisant uniquement les octets nécessaires, cette opération peut être considérablement accélérée.
$ /usr/bin/time ./pngsize *.png
--> 0.00user 0.00system 0:00.03elapsed 12%CPU (0avgtext+0avgdata 1904maxresident)k
0inputs+0outputs (0major+160minor)pagefaults 0swaps
Voici pngsize:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <err.h>
#define oops(syscall) { printf("error processing %s: ", argv[i]); \
fflush(0); perror(syscall"()"); continue; }
int main(int argc, char **argv) {
int fd, i;
uint32_t h, w;
if (argc < 2) { printf("%s <pngfile> [pngfile ...]\n", argv[0]); exit(0); }
for (i = 1; i < argc; i++) {
if (argc > 2) printf("%s: ", argv[i]);
if ((fd = open(argv[i], O_RDONLY)) == -1) oops("open");
if (lseek(fd, 16, SEEK_SET) == -1) oops("lseek");
if (read(fd, &w, 4) < 1) oops("read");
if (read(fd, &h, 4) < 1) oops("read");
printf("%dx%d\n", htonl(w), htonl(h));
if (close(fd) == -1) oops("close");
}
return 0;
}
Cette méthode est beaucoup plus rapide que d'utiliser une bibliothèque qui charge le PNG vers l'avant, vers l'arrière et latéralement juste pour obtenir la taille de l'image: P (Considérez attentivement le code avant en lui fournissant un répertoire plein de PNG arbitraires bien sûr.)
Le code utilise inet.h pour htonl () à de - endian - ize l'ordre des octets d'en-tête.
Vous pouvez également essayer GraphicsMagick , qui est un fork bien maintenu d'ImageMagick utilisé par ex. Flickr et Etsy:
$ gm identify a.jpg
a.jpg JPEG 480x309+0+0 DirectClass 8-bit 25.2K 0.000u 0:01
C'est plus rapide que l'identification d'ImageMagick (dans mes tests environ deux fois).
C'était un extrait utile (je n'ai pas écrit) qui renvoie les dimensions pour chaque png et jpg dans le dossier:
file ./* | Perl -ne '@m = /^.*.jpg|^.*.png|[0-9][0-9]*[ ]?x[ ]?[0-9][0-9]*/g; print "@m\n"'
Pour ceux comme moi qui veulent la taille en mégapixels:
Perl -le "printf \"=> fileName = %s size = %.2f Mpix\n\", \"$fileName\", $(identify -format '%w*%h/10**6' $fileName)"