Zalecenie dotyczące kompresji plików JPG za pomocą ImageMagick

246

Chcę skompresować plik obrazu JPG za pomocą ImageMagick, ale nie mogę uzyskać dużej różnicy w rozmiarze. Domyślnie rozmiar wyjściowy jest większy niż wejście. Nie wiem dlaczego, ale po dodaniu niektórych opcji + profilu i ustaleniu jakości mogę uzyskać mniejszy rozmiar, ale nadal podobny do oryginału.

Obraz wejściowy to 255 kb, przetworzony obraz to 264 kb (użycie + profilu do usunięcia profili i ustawienie jakości na 70%). Czy jest jakiś sposób na skompresowanie tego obrazu co najmniej do 150 KB? Czy to jest możliwe? Z jakich opcji ImageMagick mogę korzystać?

Javis Perez
źródło
3
Ponowna kompresja pliku JPEG zawsze spowoduje pogorszenie obrazu, nawet jeśli jest większy. Byłoby lepiej, gdybyś mógł zacząć od oryginału, zanim zostanie zapisany za pierwszym razem.
Mark Ransom
Wiem, ale niestety nie mam oryginalnego obrazu, wszystko, co mam, to duży plik jpg, ale myślę, że mogę uzyskać dobrą równowagę między jakością a rozmiarem
Javis Perez

Odpowiedzi:

440

Używam zawsze:

  • jakość w 85
  • progresywna (skompresowana kompresja)
  • bardzo małe rozmycie gaussowskie w celu optymalizacji rozmiaru (0,05 lub 0,5 promienia) zależy od jakości i rozmiaru obrazu, co w szczególności optymalizuje rozmiar pliku JPEG.
  • Usuń dowolny komentarz lub tag exif

w imagemagick powinno być

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

lub w nowszej wersji:

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

mam nadzieję, że to się przyda.

Link do źródła: http://www.yuiblog.com/blog/2008/12/05/imageopt-4/

Od @Fordi w komentarzach (nie zapomnij pochwalić jego komentarza, jeśli chcesz): Jeśli nie lubisz rozmycia, użyj -sampling-factor 4:2:0zamiast tego. Powoduje to zmniejszenie rozdzielczości kanału chrominancji do połowy, bez pogarszania rozdzielczości luminancji, na którą zapadają się twoje oczy. Jeśli chcesz uzyskać lepszą wierność konwersji, możesz uzyskać niewielką poprawę bez zwiększania rozmiaru pliku, określając -define jpeg:dct-method=float- to znaczy użyj dokładniejszej zmiennoprzecinkowej dyskretnej transformacji kosinusowej, a nie domyślnej wersji szybkiej liczby całkowitej.

Felipe Buccioni
źródło
2
Dziękuję Ci! ten kod dał mi obraz do 170kb, teraz mogę przejść i eksperymentować z twoim kodem dziękuję, również znalazłem opcję -define: scope = MAX_SIZE_IN_KB, która naprawdę pomaga, dziękuję!
Javis Perez
36
Jeśli robisz wiele plików, możesz to zrobić mogrify -strip -interlace Plane -gaussian-blur 0.05 -quality 85% *.jpg. Upewnij się, że masz kopię zapasową przed uruchomieniem tego polecenia. To napisze na miejscu.
Richard Ayotte
3
-stripzrobił to dla mnie. Dzięki
Nigel Angel
38
Mam bardzo rozmyte obrazy. Celowe rozmycie obrazu w celu zaoszczędzenia miejsca wydaje się bezproduktywne. Czy nie ma większego sensu stosowanie niższej jakości%? Proces zmiany jakości jest całkiem dobry w oszczędzaniu miejsca przy zachowaniu pozornej jakości obrazu. Nałożyłem rozmycie 0,05 gaussa na mój obraz i zaoszczędził trochę miejsca, ale wyglądał jak kompletna bzdura. Postanowiłem używać mogrify -strip -quality 75% *.jpg. Strip jest świetne. 0 utrata jakości i duże oszczędności miejsca. A jakość przy 75% jest ledwo odróżnialna od 100%, ale zajmuje połowę miejsca.
Buttle Butkus,
80
Jeśli nie lubisz rozmycia, użyj zamiast tego współczynnika -sampling 4: 2: 0. Powoduje to zmniejszenie rozdzielczości kanału chrominancji do połowy, bez pogarszania rozdzielczości luminancji, na którą zapadają się twoje oczy. Jeśli chcesz uzyskać lepszą wierność konwersji, możesz uzyskać niewielką poprawę bez zwiększania rozmiaru pliku, określając -define jpeg: dct-method = float - to znaczy użyj dokładniejszej dyskretnej transformacji zmiennoprzecinkowej cosinus, zamiast domyślnego szybkiego wersja całkowita.
Fordi
67

Korzystam ze wskazówek dotyczących optymalizacji obrazu Google Pagespeed Insights , a dla ImageMagick zalecają:

-sampling-factor 4: 2: 0
-strip
-quality 85 [może się różnić, używam zakres 60-80, niższa liczba tutaj oznacza mniejszy plik]
-interlace
-colorspace RGB

Polecenie w ImageMagick:

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

Dzięki tym opcjom uzyskuję do 40% oszczędności rozmiaru JPEG bez widocznych strat.

irina
źródło
16

Tylko dla tych, którzy używają klasy Imagick w PHP:

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

źródło
14

Kiedyś musiałem zmienić rozmiar zdjęć z aparatu w celu opracowania:

  • Oryginalny rozmiar pliku: 2800 kB
  • Rozdzielczość: 3264 x 2448

Komenda:

mogrify -quality "97%" -resize 2048x2048 -filter Lanczos -interlace Plane -gaussian-blur 0.05 
  • Rozmiar pliku wynikowego 753 kB
  • Rozdzielczość 2048x2048

i nie widzę żadnych zmian na pełnym ekranie z moim monitorem o rozdzielczości 1920x1080. Rozdzielczość 2048 jest najlepsza do tworzenia zdjęć 10 cm przy maksymalnej jakości 360 dpi. Nie chcę tego rozbierać.

edycja: Zauważyłem, że uzyskuję nawet znacznie lepsze wyniki bez rozmycia. Bez rozmycia rozmiar pliku to 50% oryginału, ale jakość jest lepsza (podczas powiększania).

tuipveus
źródło
Nie musisz dodawać „-filter Lanczos”. Jest ustawiony domyślnie imagemagick.org/script/command-line-options.php#filter
Ilya Prokin
jak powiedziano powyżej - nie ma sensu obniżać rozdzielczości obrazu, aby zmniejszyć plik. Zamiast tego obniż jakość JPEG! Możesz to przetestować sam - porównaj dwa obrazy, jeden z 97% JPEG, a drugi przekonwertowany na powiedzmy 68%, a naprawdę trudno będzie zobaczyć inne piksele, nawet jeśli spojrzysz na 100% zoom! Zdjęcie aparatu i ustawienia telefonu jest absurdalnie wysoki prostu chcę, aby kupić nowe telefony z większym przechowywania i większych dysków twardych dla komputerów ... photo.stackexchange.com/questions/30243/...
McVitas
10

Dodałbym przydatną notatkę dodatkową i ogólną sugestię, aby zminimalizować JPG i PNG.

Przede wszystkim ImageMagick odczytuje (lub lepiej „zgadnij” ...) wejściowy poziom kompresji jpeg, więc jeśli w ogóle nie dodasz -quality NN, dane wyjściowe powinny używać tego samego poziomu co dane wejściowe. Czasami może być ważną funkcją. W przeciwnym razie domyślnym poziomem jest -quality 92(patrz www.imagemagick.org )

Sugestia dotyczy naprawdę niesamowitego bezpłatnego narzędzia ImageOptim , również do procesu wsadowego.
Możesz uzyskać mniejsze pliki jpg (i pngs, zwłaszcza po użyciu bezpłatnego ImageAlpha [nie proces wsadowy] lub darmowego Pngyu, jeśli potrzebujesz procesu wsadowego).
Nie tylko te narzędzia są przeznaczone dla komputerów Mac i Win oraz jako wiersz poleceń (sugeruję instalację przy użyciu Brew, a następnie wyszukiwanie w formułach Brew).

Steve
źródło
Użyłem pngquant dla Linuksa. Odwołano się do niego na stronie ImageAlpha. Dzięki za podpowiedź
Alexander Ryhlitsky
8

Dodałem -adaptive-resize 60%do sugerowanego polecenia, ale z -quality 60%.

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

To były moje wyniki

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

Nie jestem pewien, czy ta konwersja zbyt mocno niszczy mój obraz, ale szczerze mówiąc, nie sądziłem, że moja konwersja wyglądała jak gówno. To była panorama szerokokątna i nie dbałem o drobiazgową przeszkodę.

C.shin
źródło
5

@JavisPerez - Czy jest jakiś sposób na skompresowanie tego obrazu przynajmniej do 150 KB? Czy to jest możliwe? Z jakich opcji ImageMagick mogę korzystać?

Zobacz poniższe łącza, w których w ImageMagick dostępna jest opcja określająca pożądany rozmiar pliku wyjściowego do zapisu w plikach 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

Utracisz pewną jakość poprzez dekompresję i ponowną kompresję oprócz wszelkich strat spowodowanych obniżeniem wartości jakości na wejściu.

fmw42
źródło
4

Czy trochę eksperymentowałem tutaj, a chłopak robi, że Gausowskie rozmycie robi coś całkiem innego. Ostatnim poleceniem, którego użyłem było:

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

Bez rozmycia gausowskiego przy 0,05 było to około 261 kb, z tym było to około 171 kB dla obrazu, na którym testowałem. Różnica wizualna na monitorze 1440p z dużym złożonym obrazem jest zauważalna dopiero po przybliżeniu.

Ironbelly Studios
źródło
Pamiętaj, że rozmycie gaussowskie źle działa z małymi obrazami, ale musi mieć duże!
Antonin GAVREL
4

Oto kompletne rozwiązanie dla osób używających Imagick w 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
źródło
0

Jeśli obraz ma duże wymiary, trudno jest uzyskać dobre wyniki bez zmiany rozmiaru, poniżej znajduje się 60-procentowy rozmiar, który w większości przypadków nie niszczy zbyt dużej części obrazu.

Używam tego z dobrym wynikiem dla obrazów w skali szarości (konwertuję z 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

Używam tego do zeskanowanych stron czarno-białych, aby uzyskać obrazy w skali szarości (dodatkowe argumenty oczyszczają cienie z poprzednich stron):

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 

Używam tego do kolorowych obrazów:

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
źródło