Как сохранить изображение JPG в цветовом пространстве 4:2:0 с помощью Imagick?

Google Pagespeed может преобразовывать изображения RGB в цветовое пространство YUV 4:2:0. Я хотел бы сделать то же самое в PHP, используя imagick.

Кратко о том, почему желательно 4:2:0:

«Этот фильтр уменьшает дискретизацию цвета jpeg-изображений до 4:2:0. Человеческое зрение гораздо более чувствительно к изменениям яркости, чем к изменениям оттенка или насыщенности, а дискретизация цвета 4:2:0 позволяет нам сохранять данные о яркости, уменьшая количество данных оттенка и насыщенности на 3/4. Это может значительно уменьшить размер изображения, оказывая лишь небольшое влияние на восприятие».

Я попытался изменить цветовое пространство с помощью imagemagick на YUV, но это не работает! Белый фон переходит в зеленый, а остальные цвета неправильные, плюс инвертированная яркость.

Следующий код бесполезен, но он показывает несколько вещей, которые я пробовал.

С форматом Google, созданным mod_pagespeed, результирующие изображения отлично выглядят в браузере. Это то, чего я надеюсь достичь, изображения для Интернета.

    $image_info = getimagesize($source_file);
    $im = new Imagick();
    $im->readImage($source_file);
    $profiles = $im->getImageProfiles('*', false);
    $has_icc_profile = (array_search('icc', $profiles) !== false);
    if ($has_icc_profile === false) {
        $icc_srgb = file_get_contents(Mage::getBaseDir('var') . DS . 'metodo' . DS . 'demo_data' . DS . 'AdobeRGB1998.icc');
        $im->profileImage('icc', $icc_srgb);
        unset($icc_srgb);
    }
    //$im->setImageColorspace(1);
    $im->setInterlaceScheme(Imagick::INTERLACE_PLANE);
    $im->setImageCompressionQuality(85);
    //$im->stripImage(); 
    $im->setImageColorspace(11);
    $im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
    //$im->negateImage(false, Imagick::CHANNEL_ALL);
    $im->stripImage();
    $im->writeImage($fileName);

person Henry's Cat    schedule 25.11.2014    source источник
comment
4:2:0 — это не цветовое пространство, а тип подвыборки цветности. Вероятно, вам следует обратить внимание на Imagick::setSamplingFactors. Однако в документации по PHP отсутствует какое-либо объяснение того, каким должно быть содержимое единственного аргумента этого метода, и я действительно понятия не имею...   -  person Plenka    schedule 25.11.2014


Ответы (2)


Меня заинтриговало отсутствие документации по методу Imagick::setSamplingFactors (см. мой комментарий), поэтому Я пытался понять это.

С помощью метода Imagick::identifyImage стало понятно, что библиотека Imagick использует не нотацию 4:2:0 для субдискретизации цветности, а что-то вроде '1x1,1x1,1x1'. На http://www.ftgimp.com/help/C/filters/jpeg.html (20180608: больше не доступен, заархивировано здесь), стало ясно, что '1x1,1x1,1x1' переводится в 4:4:4, а '2x2,1x1,1x1' в 4:2:0. Поскольку для метода Imagick::setSamplingFactors в качестве аргумента требуется массив, я попробовал следующее, и оно сработало успешно:

$img = new Imagick($source_file)
$img->setSamplingFactors(array('2x2', '1x1', '1x1'));
$im->writeImage($fileName);
person Plenka    schedule 26.11.2014
comment
Хороший ответ - документацию по PHP может редактировать любой. Вы хотите поместить этот ответ там? - person Danack; 26.11.2014
comment
Это приближается!!! Я был действительно в восторге от вашего вдохновенного ответа, прямо сейчас у меня всего «еще несколько попыток», чтобы заставить это работать. Это будет работать!!! Я попытался в своем коде уменьшить размер файлов таким образом - и пошел на идентификацию -verbose, чтобы увидеть, что происходит. Большое вам спасибо за дополнительный ответ на этот вопрос, я уверен, что вы правы, но пока нет зеленой галочки !!! - person Henry's Cat; 26.11.2014
comment
@ Данак, не уверен, что я достаточно осведомлен. Этот вопрос вызвал у меня интерес, поэтому я откопал setSamplingFactors. Как я уже сказал, меня заинтриговало отсутствие документации, чтобы копнуть глубже, но все, что я знаю, содержится в этом ответе. Для меня слишком быстро освоить теорию, чтобы предоставить надлежащую документацию. Вольфи, надеюсь, это твой прорыв. :) - person Plenka; 26.11.2014

Возможно, технически это не ответ, но его слишком неудобно форматировать как комментарий, и это может помочь найти ответ.

Вы можете сделать что-то вроде того, что может дать некоторое представление о том, как использовать параметры и что они делают:

convert input.jpg -colorspace YUV out.jpg
convert input.jpg -colorspace YUV -sampling-factor 4:2:2 out442.jpg
convert input.jpg -colorspace YUV -sampling-factor 4:2:0 out420.jpg

затем вы можете увидеть полученные файлы для различных настроек. Кажется, что выходные файлы файлов довольно хорошо коррелируют с выборкой, и выборка IM по умолчанию составляет 4: 4: 4, поскольку она соответствует размеру, когда я не предоставляю никаких -sampling-factor:

ls -l out*
-rw-r--r--  1 mark  staff  105563 26 Nov 10:23 out.jpg
-rw-r--r--  1 mark  staff   77230 26 Nov 10:23 out410.jpg
-rw-r--r--  1 mark  staff   81755 26 Nov 10:24 out411.jpg
-rw-r--r--  1 mark  staff   82835 26 Nov 10:23 out420.jpg
-rw-r--r--  1 mark  staff  105563 26 Nov 10:25 out444.jpg

Эта ссылка может помочь.

person Mark Setchell    schedule 26.11.2014