¿Cómo encontrar todas las imágenes con un cierto tamaño de píxel usando la línea de comandos?

16

Estoy tratando de encontrar todas las imágenes JPG dentro de una carpeta con subcarpetas que tengan ancho o alto por debajo de 300px.

De esta manera quiero detectar miniaturas antiguas y eliminarlas.

Seguro que puedo encontrar todas las imágenes usando find:

find . -iname "*.jpg" -type f | ...

Pero, ¿qué sigue después de la tubería? ¿Qué paquete puedo usar para detectar los atributos de la imagen?

Mcbetz
fuente

Respuestas:

17

Puede usar identifydesde imagemagick, y puede usar el siguiente comando:

find . -iname "*.jpg" -type f -exec identify -format '%w %h %i' '{}' \; | awk '$1<300 || $2<300'

el uso de -exec <command> '{}' \;asegura que su nombre de archivo pueda tener espacios en ellos, alternativamente puede usar

find . -iname "*.jpg" -type f | xargs -I{} identify -format '%w %h %i' {} | awk '$1<300 || $2<300'

donde -I{}se encarga de lo mismo.

Lo que me gusta identifyes que puedes especificar el formato de salida; en este caso, '%w %h %i'que proporciona el ancho, la altura y la ruta completa de la imagen. Luego, la awkexpresión solo mantiene aquellas líneas para las cuales la imagen es más pequeña que el tamaño deseado.

Ejemplo de la salida:

64 64 ./thumbsup.jpg
100 150 ./photomin.jpg

Editar: si solo desea los nombres de archivo (por rmejemplo, para canalizar ), simplemente cambie $linela awkinstrucción a $3, solo imprimirá la tercera columna.

Gerhard Burger
fuente
3
La parte awk se puede acortar: | awk '$1<300||$2<300'o | awk '$1<300||$2<300{print $3}'(cuando solo se necesita la tercera columna).
har-wradim
@ har-wradim Gracias, buena sugerencia!
Gerhard Burger
77
Tuve que agregar una nueva línea ( '%w %h %i\n') para que funcione para mí.
qwr
Perdón por escribir una pregunta de 6 años, pero este es el único resultado que encuentro en Google que responde parcialmente a mi pregunta, básicamente lo que quiero es encontrar imágenes con o dentro de dimensiones específicas y luego copiarlas en otro directorio. Sé que cp se usa para copiar, pero no puedo integrar este comando con cp.
GhostOrder
@GhostOrder sigue la sugerencia de @ har-wradim para imprimir solo la tercera columna, luego agrega otra pipa con algo como esto| xargs -I {} mv {} /destination/directory/
Gerhard Burger
1

Creo que la respuesta aceptada es muy buena, pero quería agregar otra posible solución ...

Aunque uso las ImageMagickherramientas con mayor frecuencia ahora mismo, soy netpbmun viejo amigo para procesar imágenes. Puede ver el tamaño de cualquier formato de imagen con el comando:

anytopnm file | pamfile

Esto generará una salida similar a:

stdin:  PPM raw, 1650 by 1275  maxval 255

Para responder a la pregunta "¿qué sigue después de la tubería?", Uso while readmás seguido de lo que uso xargsporque es más flexible. Mi netpbmrespuesta a la pregunta se ve así:

find -iname \*.jpg | while read img; do \
  anytopnm "$img" | pamfile | \
    perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || rm -v "$img"; \
done
NateT
fuente
1

Esto funcionó para mí:

find . -iname "*.png" -type f -exec identify -format '%i %wx%h\n' '{}' \; | grep '75x75'

Esta es la muestra de salida:

./2520161636481000.png 75x75

./2620160819191100.png 75x75

./2420181545550700.png 75x75

osroflo
fuente
0

El identifycomando del imagemagickpaquete hace lo que quieres:

$ identify abc.jpg
abc.jpg JPEG 1952x3264 1952x3264+0+0 8-bit DirectClass 1.111MB 0.000u 0:00.000

Una vez más, deberá utilizar greppara ordenar el tamaño de la imagen.

Sin embargo, sospecho que a menos que tenga un rango muy amplio de tamaños de imagen, sería más fácil usarlo findpara eliminar archivos JPEG por debajo de un tamaño determinado:

find -iname '*.jpg' -size -10k -delete

(Vale la pena ejecutarlo sin -deletecomprobar primero que no encuentra las cosas que desea conservar; de lo contrario, no le preguntará antes de eliminarlo).

cronitis
fuente