Recomendação para compactar arquivos JPG com o ImageMagick

246

Quero compactar um arquivo de imagem JPG com o ImageMagick, mas não consigo fazer muita diferença no tamanho. Por padrão, o tamanho da saída é maior que a entrada. Não sei por que, mas depois de adicionar algumas opções de perfil + e definir a qualidade, posso obter um tamanho menor, mas ainda semelhante ao original.

A imagem de entrada é 255kb, a imagem processada é 264kb (usando o perfil + para remover perfis e definindo a qualidade para 70%). Existe alguma maneira de comprimir essa imagem em 150kb, pelo menos? Isso é possível? Quais opções do ImageMagick posso usar?

Javis Perez
fonte
3
Recomprimir um JPEG sempre resultará em uma imagem degradada, mesmo que seja maior. Seria melhor se você pudesse começar com o original antes que ele fosse salvo pela primeira vez.
Mark Ransom
Eu sei, mas infelizmente eu não tenho a imagem original, tudo que eu tenho é um arquivo jpg grande, mas eu acho que posso conseguir um bom equilíbrio entre a qualidade eo tamanho
Javis Perez

Respostas:

440

Eu sempre uso:

  • qualidade em 85
  • progressivo (compressão comprobada)
  • um borrão gausssiano muito pequeno para otimizar o tamanho (0,05 ou 0,5 de raio) depende da qualidade e tamanho da imagem; isso otimiza notavelmente o tamanho do jpeg.
  • Retire qualquer comentário ou tag exif

no imagemagick deve ser

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

ou na versão mais recente:

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

espero que isso seja útil.

Link da fonte: http://www.yuiblog.com/blog/2008/12/05/imageopt-4/

De @Fordi nos comentários (não esqueça de deixar o comentário dele, se quiser): Se você não gosta de desfocar, use -sampling-factor 4:2:0. O que isso faz é reduzir a resolução do canal de croma para metade, sem mexer com a resolução de luminância em que seus olhos se agarram. Se você deseja uma melhor fidelidade na conversão, pode obter uma pequena melhoria sem aumentar o tamanho do arquivo especificando -define jpeg:dct-method=float- ou seja, use a transformação de cosseno discreto de ponto flutuante mais precisa, em vez da versão inteira rápida padrão.

Felipe Buccioni
fonte
2
Obrigado! esse código me deu a imagem para 170kb, agora eu posso experimentar o seu código, obrigado, também encontrei a opção -define: extensão = MAX_SIZE_IN_KB que realmente ajuda, obrigado!
Javis Perez
36
Se você estiver criando um monte de arquivos, também pode fazer mogrify -strip -interlace Plane -gaussian-blur 0.05 -quality 85% *.jpg. Verifique se você possui um backup antes de executar esse comando. Ele irá escrever no lugar.
Richard Ayotte
3
-stripfez isso por mim. Graças
Nigel Anjo
38
Eu tenho imagens muito embaçadas. Parece contraproducente desfocar intencionalmente a imagem para economizar espaço. Não faria mais sentido usar apenas uma% de qualidade inferior? O processo de mudança de qualidade é muito bom para economizar espaço, mantendo a qualidade aparente da imagem. Coloquei um borrão gaussiano de 0,05 na minha imagem e ele economizou espaço, mas parecia uma porcaria total. Eu decidi usar mogrify -strip -quality 75% *.jpg. Strip é ótimo. 0 perda de qualidade e grande economia de espaço. E a qualidade de 75% mal se distingue de 100%, mas ocupa metade do espaço.
Buttle Butkus
80
Se você não gosta de desfoque, use -sampling-factor 4: 2: 0. O que isso faz é reduzir a resolução do canal de croma para metade, sem mexer com a resolução de luminância em que seus olhos se agarram. Se você deseja uma melhor fidelidade na conversão, pode obter uma leve melhoria sem aumentar o tamanho do arquivo especificando -define jpeg: dct-method = float - ou seja, use a transformação de cosseno discreto de ponto flutuante mais precisa, em vez da rápida padrão versão inteira.
Fordi
67

Estou usando as diretrizes de otimização de imagem do Google Pagespeed Insights e, para o ImageMagick, eles recomendam o seguinte:

-sampling-factor 4: 2: 0
-strip -quality
85 [pode variar, eu uso o intervalo 60-80, número menor aqui significa arquivo menor]
-interlace
-colorspace RGB

Comando no ImageMagick:

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

Com essas opções, economizo até 40% no tamanho JPEG sem muita perda visível.

irina
fonte
16

Só para quem usa a classe Imagick no PHP:

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

fonte
14

Uma vez eu precisei redimensionar as fotos da câmera para o desenvolvimento:

  • Tamanho do arquivo original: 2800 kB
  • Resolução: 3264x2448

Comando:

mogrify -quality "97%" -resize 2048x2048 -filter Lanczos -interlace Plane -gaussian-blur 0.05 
  • Tamanho do arquivo resultado 753 kB
  • Resolução 2048x2048

e não consigo ver nenhuma alteração na tela cheia com meu monitor de resolução 1920x1080. A resolução 2048 é a melhor para o desenvolvimento de fotos de 10 cm com qualidade máxima de 360 ​​dpi. Eu não quero tirar isso.

edit: notei que até obtive resultados muito melhores sem desfocar. Sem desfocar o tamanho do arquivo é 50% do original, mas a qualidade é melhor (ao aplicar zoom).

tuipveus
fonte
Você não precisa adicionar "-filter Lanczos". É definido por padrão imagemagick.org/script/command-line-options.php#filter
Ilya Prokin
como foi dito acima - é inútil diminuir a resolução da imagem para diminuir o arquivo. Reduza a qualidade JPEG! Você pode testá-lo você mesmo - compare duas imagens, uma com 97% de JPEG e outra convertida para, digamos, 68% e você terá muita dificuldade em ver pixels diferentes, mesmo se você observar o zoom de 100%! Da câmera e configurações do telefone é ridiculamente alta apenas para fazer você quer comprar novos telefones com maior armazenamento e unidades de disco rígido maiores para seus PCs ... photo.stackexchange.com/questions/30243/...
McVitas
10

Eu acrescentaria uma nota lateral útil e uma sugestão geral para minimizar JPG e PNG.

Primeiro, o ImageMagick lê (ou melhor, "adivinhar" ...) o nível de compactação do JPEG de entrada e, se você não adicionar -quality NN, a saída deve usar o mesmo nível da entrada. Às vezes, pode ser uma característica importante. Caso contrário, o nível padrão é -quality 92(consulte www.imagemagick.org )

A sugestão é sobre uma ferramenta gratuita realmente incrível ImageOptim , também para processo em lote.
Você pode obter jpgs menores (e pngs também, especialmente após o uso do ImageAlpha gratuito [sem processo em lote] ou do Pngyu gratuito, se precisar do processo em lote).
Além disso, essas ferramentas são para Mac e Win e como linha de comando (sugiro instalar usando o Brew e pesquisar nas fórmulas do Brew).

Steve
fonte
Eu usei pngquant para Linux. Foi referenciado na página ImageAlpha. Obrigado pela dica
Alexander Ryhlitsky
8

Eu adicionei -adaptive-resize 60%ao comando sugerido, mas com -quality 60%.

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

Estes foram os meus resultados

  • img_original.jpg = 13.913 KB
  • img_resized.jpg = 845 KB

Não tenho certeza se essa conversão destrói muito minha imagem, mas sinceramente não acho que minha conversão pareça uma porcaria. Era um panorama de grande angular e eu não ligava para obstruções meticulosas.

C.shin
fonte
5

@JavisPerez - Existe alguma maneira de comprimir essa imagem em 150kb, pelo menos? Isso é possível? Quais opções do ImageMagick posso usar?

Consulte os links a seguir, onde há uma opção no ImageMagick para especificar o tamanho do arquivo de saída desejado para gravar em arquivos 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

Você perderá alguma qualidade ao descompactar e recomprimir, além de qualquer perda devido à redução do valor de qualidade da entrada.

fmw42
fonte
4

Fiz algumas experiências aqui e menino, esse desfoque gausiano é bem diferente. O comando final que usei foi:

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

Sem o desfoque gausiano em 0,05, ele estava em torno de 261kb, e em torno de 171KB para a imagem em que eu estava testando. A diferença visual em um monitor 1440p com uma imagem grande e complexa não é perceptível até você aumentar o zoom.

Ironbelly Studios
fonte
Observe que o desfoque gaussiano funciona mal com imagens pequenas, mas é obrigatório para as grandes!
Antonin GAVREL
4

Aqui está uma solução completa para quem usa o Imagick no 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);
  }
}
emanuelbsilva
fonte
0

Se a imagem tiver grandes dimensões, é difícil obter bons resultados sem redimensionar, abaixo está um redimensionamento de 60% que, na maioria das finalidades, não destrói muito a imagem.

Eu uso isso com bom resultado para imagens em escala de cinza (eu converto 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

Eu uso isso para páginas em preto e branco digitalizadas, para obter imagens em escala de cinza (os argumentos extras limpam as sombras das 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 

Eu uso isso para imagens coloridas:

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 
Eduard Florinescu
fonte