Use mogrify para cambiar el tamaño de los archivos grandes mientras ignora los pequeños
10
Estoy ejecutando el siguiente comando:
mogrify -resize '400x400>' *.png
Observe el ">". Supuestamente ignorará los archivos más pequeños, pero aunque no los redimensiona, los edita (la fecha de modificación y el tamaño del archivo cambian).
¿Hay alguna manera de hacerlo realmente solo dejando los archivos más pequeños solos? Me gustaría evitar varios miles de operaciones de escritura innecesarias.
Creo que mogrifyreescribe sistemáticamente el archivo, por lo que su única esperanza es filtrar la lista primero, como lo sugiere jippie . Así es como puede hacerlo (sin probar): imprima una lista de archivos de imagen con una indicación de tamaño, mantenga solo los nombres cuyo tamaño asociado esté dentro del rango y procese esa lista.
Para cada archivo, imprima una línea con el ancho, un espacio, la altura, un espacio y el nombre del archivo. Dependiendo de su versión de identify, \nagregar una nueva línea final puede ser necesario (ImageMagick 6.6.0) o superfluo pero inofensivo (GraphicsMagick 1.1.11).
( awk) En cada línea, si el ancho ( $1) y la altura ( $2) coinciden con las condiciones requeridas, entonces:
Elimine todo el texto hasta el segundo carácter de espacio. Esto elimina el ancho y la altura.
Imprima lo que queda de la línea, que es el nombre del archivo.
Reemplazar nuevas líneas por caracteres nulos.
Llame xargs -0para ejecutar el mogrifycomando en los nombres de archivo. (No podemos usar plain xargsporque no puede manejar entradas que contienen espacios en blanco o \'").
Los nombres de los archivos pueden contener cualquier carácter, excepto las nuevas líneas.
¿Puedes explicar ese guión? Específicamente la parte "sub". Está imprimiendo los nombres de archivo sin espacio o insertando una nueva línea. mogrify: no se puede abrir el archivo `22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951. No tengo idea de dónde viene ese "308 400". Debo mencionar que los archivos tienen espacios en sus nombres Gracias.
Mike
Me estoy volviendo loco: no puedo abrir el archivo `340 271 22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951. Ejecuté el comando usando 200x200 en dos archivos de muestra. Veo que 308x400 es del tamaño de uno de los archivos
Mike
2
@ Mike Ah, lo tengo. Algunas versiones de identifyponen automáticamente una nueva línea después de cada registro, otras necesitan tener una explícitamente. Agregue \nal final del argumento a -format(vea mi edición).
Gilles 'SO- deja de ser malvado'
8
Me enfrenté al mismo problema que describiste. Aquí está mi solución:
#!/bin/bash
files=*.jpg
minimumWidth=640
minimumHeight=640for f in $filesdo
imageWidth=$(identify -format "%w""$f")
imageHeight=$(identify -format "%h""$f")if["$imageWidth"-gt "$minimumWidth"]||["$imageHeight"-gt "$minimumHeight"];then
mogrify -resize ''"$minimumWidth"x"$minimumHeight"'' $ffidone
Lo probé en varias imágenes JPEG en una máquina virtualizada CentOS 6.5. El script solo redimensionó y comprimió las imágenes cuyo ancho o alto era mayor que 640 píxeles. Esto lo hizo funcionar para imágenes con dimensiones como 800 x 600 (horizontal, redimensionándolo a 640 x 480) y dimensiones como 600 x 800 (vertical, redimensionándolo a 480 x 640).
PD: Una nota sobre el 400x400parámetro: mogrifyprocesará el archivo incluso si sus dimensiones son iguales o menores que 400x400, pero cambiará de tamaño solo si sus dimensiones son mayores que 400x400. Es por eso que el tiempo y el tamaño de modificación de los archivos cambian (en mi caso, mogrifyestos archivos fueron aún más grandes de lo que eran).
saldrá 1si la imagen es más grande que 400x400y 0si es igual o más pequeña que 400x400...
Suponiendo nombres de archivos sanos (sin líneas nuevas / espacios / pestañas, etc.) que podría usar identifypara imprimir nombres de imágenes precedidos por cualquiera de los dos , 1:o 0:procese la salida eliminando líneas que comienzan con 0:y eliminando el inicio 1:del resto de líneas para que solo queden los nombres de archivo. por línea, luego canalice esa lista a mogrify ... @-( se agregó la @sintaxisimagemagick v6.5.2 ):
De lo contrario, findpodría imprimir solo los archivos con un tamaño> 400x400 y luego canalizar el resultado a xargs+ mogrify(es menos eficiente ya que ejecuta un shell para cada archivo pero debería funcionar con todo tipo de nombres de archivo):
Teniendo en cuenta mis habilidades limitadas y el hecho de que los tamaños de las imágenes son tan irregulares, necesito un método más simple. Prefiero procesarlos a todos con mogrify.
Aquí está mi opinión al respecto, incorporando ideas de @ArionKrause y @don_crissti:
#!/bin/bash
# adapted from http://unix.stackexchange.com/a/157594/110635
# and http://unix.stackexchange.com/a/220619/110635
W=1024
H=768
SIZE_TEST="%[fx:(h>$H && w>$W)]"'\n'
for f in $*; do
if [ $(identify -format "$SIZE_TEST" "$f") = 1 ]; then
echo "Resize: $f"
mogrify -resize ''"$W"x"$H"'' "$f"
else
echo "Do not resize: $f"
fi
done
(Necesitaba esto porque mi procesador por lotes favorito Phatch no funciona con Ubuntu 16.04).
identify
ponen automáticamente una nueva línea después de cada registro, otras necesitan tener una explícitamente. Agregue\n
al final del argumento a-format
(vea mi edición).Me enfrenté al mismo problema que describiste. Aquí está mi solución:
Lo probé en varias imágenes JPEG en una máquina virtualizada CentOS 6.5. El script solo redimensionó y comprimió las imágenes cuyo ancho o alto era mayor que 640 píxeles. Esto lo hizo funcionar para imágenes con dimensiones como 800 x 600 (horizontal, redimensionándolo a 640 x 480) y dimensiones como 600 x 800 (vertical, redimensionándolo a 480 x 640).
PD: Una nota sobre el
400x400
parámetro:mogrify
procesará el archivo incluso si sus dimensiones son iguales o menores que 400x400, pero cambiará de tamaño solo si sus dimensiones son mayores que 400x400. Es por eso que el tiempo y el tamaño de modificación de los archivos cambian (en mi caso,mogrify
estos archivos fueron aún más grandes de lo que eran).fuente
También puede usar el
fx
operador para filtrar imágenes en función de la altura / anchura, p. Ej.saldrá
1
si la imagen es más grande que400x400
y0
si es igual o más pequeña que400x400
...Suponiendo nombres de archivos sanos (sin líneas nuevas / espacios / pestañas, etc.) que podría usar
identify
para imprimir nombres de imágenes precedidos por cualquiera de los dos ,1:
o0:
procese la salida eliminando líneas que comienzan con0:
y eliminando el inicio1:
del resto de líneas para que solo queden los nombres de archivo. por línea, luego canalice esa lista amogrify ... @-
( se agregó la@
sintaxisimagemagick v6.5.2
):De lo contrario,
find
podría imprimir solo los archivos con un tamaño> 400x400 y luego canalizar el resultado axargs
+mogrify
(es menos eficiente ya que ejecuta un shell para cada archivo pero debería funcionar con todo tipo de nombres de archivo):Si eres
zsh
usuario, mira también esta respuesta .fuente
¿Qué tal si usas Identificar para encontrar el tamaño de tu imagen y decidir desde un pequeño script si quieres editarlo o no?
No debería ser demasiado difícil editar el formato de salida para usarlo en un script simple.
fuente
Yo uso tal script PHP, usa ImageMagick:
Escala todas las imágenes en el directorio actual más grande que 3000 en algún borde.
Ejecutar comando:
php scale.php
Ophp scale.php 2000
fuente
Aquí está mi opinión al respecto, incorporando ideas de @ArionKrause y @don_crissti:
(Necesitaba esto porque mi procesador por lotes favorito Phatch no funciona con Ubuntu 16.04).
fuente
Mis funciones para redimensionar y optimizar
fuente