Recomendación para comprimir archivos JPG con ImageMagick


246

Quiero comprimir un archivo de imagen JPG con ImageMagick pero no puedo obtener mucha diferencia de tamaño. Por defecto, el tamaño de salida es mayor que la entrada. No sé por qué, pero después de agregar algunas opciones de perfil + y establecer la calidad, puedo obtener un tamaño más pequeño pero similar al original.

La imagen de entrada es 255kb, la imagen procesada es 264kb (usando + perfil para eliminar perfiles y configurando la calidad al 70%). ¿Hay alguna forma de comprimir esa imagen al menos a 150 kb? ¿Es eso posible? ¿Qué opciones de ImageMagick puedo usar?


3
Al volver a comprimir un JPEG siempre se producirá una imagen degradada, incluso si es más grande. Sería mejor si pudiera comenzar con el original antes de guardarlo la primera vez.
Mark Ransom

Lo sé, pero desafortunadamente no tengo la imagen original, todo lo que tengo es un gran archivo jpg, pero creo que puedo lograr un buen equilibrio entre calidad y tamaño
Javis Perez

Respuestas:


440

Yo uso siempre:

  • calidad en 85
  • progresivo (compresión comprobada)
  • un desenfoque gaussiano muy pequeño para optimizar el tamaño (0.05 o 0.5 de radio) depende de la calidad y el tamaño de la imagen, esto optimiza notablemente el tamaño del jpeg.
  • Tira cualquier comentario o etiqueta exif

en imagemagick debería ser

convert -strip -interlace Plane -gaussian-blur 0.05 -quality 85% source.jpg result.jpg

o en la versión más nueva:

magick source.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% result.jpg

Espero que esto sea útil.

Enlace fuente: http://www.yuiblog.com/blog/2008/12/05/imageopt-4/

De @Fordi en los comentarios (no olvides aprobar su comentario si lo deseas): si no te gusta el desenfoque, úsalo en su -sampling-factor 4:2:0lugar. Lo que esto hace es reducir la resolución del canal de croma a la mitad, sin interferir con la resolución de luminancia a la que se adhieren los ojos. Si desea una mejor fidelidad en la conversión, puede obtener una ligera mejora sin un aumento en el tamaño del archivo al especificar -define jpeg:dct-method=float, es decir, usar la transformación de coseno discreto de coma flotante más precisa, en lugar de la versión entera rápida predeterminada.


2
¡Gracias! este código me llevó la imagen a 170kb, ahora puedo ir y experimentar con su código gracias, también he encontrado la opción -define: extensión = MAX_SIZE_IN_KB que realmente ayuda, ¡gracias!
Javis Perez

36
Si está haciendo un montón de archivos, también puede hacerlo mogrify -strip -interlace Plane -gaussian-blur 0.05 -quality 85% *.jpg. Asegúrese de tener una copia de seguridad antes de ejecutar ese comando. Se escribirá en su lugar.
Richard Ayotte

3
-stripLo hice por mí. Gracias
Nigel Angel

38
Tengo imágenes muy borrosas. Parece contraproducente desenfocar intencionalmente la imagen para ahorrar espacio. ¿No tendría más sentido usar un% de menor calidad? El proceso de cambio de calidad es bastante bueno para ahorrar espacio mientras se mantiene la calidad aparente de la imagen. Puse un desenfoque gaussiano de 0.05 en mi imagen y ahorró algo de espacio, pero parecía una mierda. Me decidí a usar mogrify -strip -quality 75% *.jpg. Strip es genial. 0 pérdida de calidad y grandes ahorros de espacio. Y la calidad al 75% apenas se distingue del 100%, pero ocupa la mitad del espacio.
Buttle Butkus

80
Si no le gusta el desenfoque, use -sampling-factor 4: 2: 0 en su lugar. Lo que esto hace es reducir la resolución del canal de croma a la mitad, sin interferir con la resolución de luminancia a la que se adhieren los ojos. Si desea una mejor fidelidad en la conversión, puede obtener una ligera mejora sin un aumento en el tamaño del archivo especificando -define jpeg: dct-method = float, es decir, use la transformación de coseno discreto de punto flotante más precisa, en lugar del rápido predeterminado versión entera
Fordi

67

Estoy usando las pautas de optimización de imagen de Google Pagespeed Insights , y para ImageMagick recomiendan lo siguiente:

-muestreo-factor 4: 2: 0
-strip
-quality 85 [puede variar, uso el rango 60-80, un número menor aquí significa un archivo más pequeño]
-interlace
-colorspace RGB

Comando en ImageMagick:

convert image.jpg -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG -colorspace RGB image_converted.jpg

Con estas opciones obtengo hasta un 40% de ahorro en tamaño JPEG sin mucha pérdida visible.


16

Solo digo para aquellos que usan la clase Imagick en PHP:

$im -> gaussianBlurImage(0.8, 10);      //blur
$im -> setImageCompressionQuality(85);  //set compress quality to 85

14

Una vez que necesitaba cambiar el tamaño de las fotos de la cámara para desarrollarlas:

  • Tamaño de archivo original: 2800 kB
  • Resolución: 3264x2448

Mando:

mogrify -quality "97%" -resize 2048x2048 -filter Lanczos -interlace Plane -gaussian-blur 0.05 
  • Tamaño del archivo de resultados 753 kB
  • Resolución 2048x2048

y no puedo ver ningún cambio en pantalla completa con mi monitor de resolución 1920x1080. La resolución 2048 es la mejor para desarrollar fotos de 10 cm con una calidad máxima de 360 ​​ppp. No quiero desnudarlo.

editar: noté que incluso obtengo resultados mucho mejores sin desenfoque. Sin desenfoque, el tamaño del archivo es del 50% del original, pero la calidad es mejor (al hacer zoom).


No es necesario agregar "-filter Lanczos". Está configurado por defecto imagemagick.org/script/command-line-options.php#filter
Ilya Prokin

como se ha dicho anteriormente, es inútil reducir la resolución de la imagen para hacer el archivo más pequeño. ¡Baja la calidad JPEG en su lugar! Puede probarlo usted mismo: compare dos imágenes, una con 97% de JPEG y otra convertida a, digamos, 68%, ¡y realmente le resultará difícil ver que los píxeles sean diferentes incluso si observa un zoom del 100%! La configuración de la cámara y del teléfono es ridículamente alta solo para que quieras comprar nuevos teléfonos con mayor almacenamiento y discos duros más grandes para tus PC ... photo.stackexchange.com/questions/30243/…
McVitas

10

Agregaría una nota lateral útil y una sugerencia general para minimizar JPG y PNG.

En primer lugar, ImageMagick lee (o mejor "adivina" ...) el nivel de compresión jpeg de entrada y, por lo tanto, si no agrega -quality NNnada, la salida debe usar el mismo nivel que la entrada. A veces podría ser una característica importante. De lo contrario, el nivel predeterminado es -quality 92(ver www.imagemagick.org )

La sugerencia es sobre una herramienta gratuita realmente increíble ImageOptim , también para el proceso por lotes.
Puede obtener jpgs más pequeños (y pngs también, especialmente después del uso del ImageAlpha [proceso no por lotes] gratuito o el Pngyu gratuito si necesita un proceso por lotes).
No solo, estas herramientas son para Mac y Win y como línea de comando (sugiero instalar usando Brew y luego buscar en las fórmulas Brew).


Solía pngquant para Linux. Se hizo referencia en la página ImageAlpha. Gracias por la pista
Alexander Ryhlitsky

8

Agregué -adaptive-resize 60%al comando sugerido, pero con -quality 60%.

convert -strip -interlace Plane -gaussian-blur 0.05 -quality 60% -adaptive-resize 60% img_original.jpg img_resize.jpg

Estos fueron mis resultados

  • img_original.jpg = 13,913KB
  • img_resized.jpg = 845KB

No estoy seguro de si esa conversión destruye mi imagen demasiado, pero honestamente no pensé que mi conversión parecía una mierda. Era un panorama de gran angular y no me importaba la obstrucción meticulosa.


5

@JavisPerez: ¿hay alguna forma de comprimir esa imagen a 150 kb como mínimo? ¿Es eso posible? ¿Qué opciones de ImageMagick puedo usar?

Consulte los siguientes enlaces donde hay una opción en ImageMagick para especificar el tamaño de archivo de salida deseado para escribir en archivos JPG.

http://www.imagemagick.org/Usage/formats/#jpg_write http://www.imagemagick.org/script/command-line-options.php#define

-define jpeg:extent={size} As of IM v6.5.8-2 you can specify a maximum output filesize for the JPEG image. The size is specified with a suffix. For example "400kb".

convert image.jpg -define jpeg:extent=150kb result.jpg

Perderá algo de calidad al descomprimir y volver a comprimir, además de cualquier pérdida debido a la disminución del valor de calidad de la entrada.


4

Experimenté un poco aquí y el chico hace que el desenfoque gausiano sea diferente. El comando final que utilicé fue:

mogrify * -sampling-factor 4: 2: 0 -strip -quality 88 -interlace Plane -define jpeg: dct-method = float -colorspace RGB -gaussian-blur 0.05

Sin el desenfoque gausiano a 0.05 era de alrededor de 261 kb, con alrededor de 171 KB para la imagen que estaba probando. La diferencia visual en un monitor de 1440p con una imagen compleja grande no se nota hasta que se acerca mucho.


Tenga en cuenta que el desenfoque gaussiano funciona mal con imágenes pequeñas, ¡pero imprescindible para las grandes!
Antonin GAVREL

4

Aquí hay una solución completa para aquellos que usan Imagick en PHP:

$im = new \Imagick($filePath);
$im->setImageCompression(\Imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(85);
$im->stripImage();
$im->setInterlaceScheme(\Imagick::INTERLACE_PLANE);

// Try between 0 or 5 radius. If you find radius of 5 
// produces too blurry  pictures decrease to 0 until you 
// find a good balance between size and quality. 
$im->gaussianBlurImage(0.05, 5);



// Include this part if you also want to specify a maximum size for the images

$size = $im->getImageGeometry();
$maxWidth = 1920;
$maxHeight = 1080;


// ----------
// |        |
// ----------
if($size['width'] >= $size['height']){
  if($size['width'] > $maxWidth){
    $im->resizeImage($maxWidth, 0, \Imagick::FILTER_LANCZOS, 1);
  }
}


// ------
// |    |
// |    |
// |    |
// |    |
// ------
else{
  if($size['height'] > $maxHeight){
    $im->resizeImage(0, $maxHeight, \Imagick::FILTER_LANCZOS, 1);
  }
}

0

Si la imagen tiene grandes dimensiones es difícil obtener buenos resultados sin cambiar el tamaño, a continuación se muestra un cambio de tamaño del 60 por ciento que, para la mayoría de los propósitos, no destruye demasiado la imagen.

Lo uso con buenos resultados para imágenes en escala de grises (convierto de PNG):

ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60%   -gaussian-blur 0.05 -colorspace Gray -quality 20  {}.jpg

Lo uso para las páginas escaneadas en blanco y negro para obtener imágenes en escala de grises (los argumentos adicionales limpian las sombras de las páginas anteriores):

ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60%   -gaussian-blur 0.05 -colorspace Gray -quality 20 -density 300 -fill white -fuzz 40% +opaque "#000000" -density 300 {}.jpg 

Lo uso para imágenes en color:

ls ./*.png | xargs -L1 -I {} convert {} -strip -interlace JPEG -sampling-factor 4:2:0 -adaptive-resize 60%   -gaussian-blur 0.05 -colorspace RGB -quality 20  {}.jpg 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.