Оптимизация размеров jpg
в rails paperclip

rails, paperclip, imagemagik, jpeg

В paperclip мы можем создать из одного изображения серию с различными размерами:

has_attached_file :file,
  styles: {
    :full   => ["720x720#", :jpg] ,
    :medium => ["240x240#", :jpg],
    :thumb  => ["120x120#", :jpg],
    :icon   => ["40x40#",   :jpg]
  }

Для этого paperclip использует команду imagemagik convert без каких-либо опций. Но JPEG — это lossy алгоритм сжатия, поэтому его размер сильно зависит от параметра JPEG-качества.

JPEG-качество

По умолчанию качество в convert определяется так:

For the JPEG and MPEG image formats, quality is 1 (lowest image quality and highest compression) to 100 (best quality but least effective compression). The default is to use the estimated quality of your input image if it can be determined, otherwise 92. When the quality is greater than 90, then the chroma channels are not downsampled. Use the -sampling-factor option to specify the factors for chroma downsampling.

(Все доступные параметры convert можно посмотреть здесь.)

Проблема в том, что небольшие миниатюры, такие как 120x120, как правило имеют много резких границ, а так как они часто выводятся на странице в относительно большом количестве, то весьма важно минимизировать их размер. Однако если просто задать заведомо низкое качество, например, 70:

has_attached_file :file,
  styles: {
    :full   => ["720x720#", :jpg] ,
    :medium => ["240x240#", :jpg],
    :thumb  => ["120x120#", :jpg],
    :icon   => ["40x40#",   :jpg]
  },
  convert_options: {
    :full   => "-quality 90",
    :medium => "-quality 80",
    :thumb  => "-quality 70", <----
    :icon   => "-quality 60"
  }

То мы получим некачественное изображение со множеством артефактов:

Вот увеличенное в три раза изображение, где видны цветовые аберрации:

Размер этого изображение — 1.6 кб.

Чтобы избавиться от них, можно просто повысить качество до 90:

:thumb  => "-quality 90"

Что, правда, увеличивает размер до 3.3 кб.

Субсэмплирование

Оптимизировать размер можно добавлением дополнительных опций convert.

Мои недостоверные эксперименты показали, что прогрессивное сжатие interlace Plane увеличивает размер. Опция strip влияет, только если у вас действительно есть какая-либо метаинформация в изображении. Для небольшого увеличения качества можно использовать фильтр filter Lanczos и FP-арифметику.

Действенная опция — это sampling-factor. На неё ссылается выше приведённая цитата. Например, сэмплирование 4:2:0 агрессивнее сжимает информацию об оттенках, но не уменьшает качество информации о яркости, что приводит к значительному уменьшению размера без заметного уменьшения перцептивного качества:

:thumb  => "-strip -sampling-factor 4:2:0 -quality 90"

Размер этого изображение уменьшается до 2.6 кб.

А для размера 3.3 кб теперь может быть задано качество 95:

Здесь JPEG-качество равно 95, а размер вновь равен 3.3 кб.

 

Все четыре изображения, приведённые в статье:


q=70, 1.6 кб

q=90, 3.3 кб

q=90, 2.6 кб

q=95, 3.3 кб

 

Подробнее о хрома-субсэмплировании см. вики.

 

Всем удачи в оптимизации графики]

 

shitpoet@gmail.com

 



 

free hit counters