Почему setImageInterlaceScheme() не делает jpeg прогрессивным?

Я использую php Gmagick для изменения изображений. Следующий код работает, как и ожидалось, за исключением того, что изображения не являются прогрессивными. Почему? Согласно документам GraphicsMagick, так и должно быть. Для справки: исходное изображение имеет размер 666 x 1000.

    $img = new Gmagick();
    $img->setSize(900, 900)
        ->readImageBlob($image->getBytes())
        ->setImageInterlaceScheme(Gmagick::INTERLACE_PLANE)
        ->setImageResolution(96, 96)
        ->setImageFormat('jpeg')
        ->setCompressionQuality(70)
        ->resizeImage(900, 1351, Gmagick::FILTER_UNDEFINED, 1);

Обратите внимание, что

$img->getImageInterlaceScheme() === Gmagick::INTERLACE_PLANE

возвращает true после его установки.

Изменить

Я пробовал константы INTERLACE_LINE и INTERLACE_PLANE. Ни один из них, кажется, не влияет на вывод.


person Isius    schedule 04.12.2013    source источник
comment
Вы уже нашли решение для этого? У меня такая же проблема.   -  person atodd    schedule 14.01.2014
comment
Еще нет. Я отправил отчет об ошибке в качестве последнего средства. bugs.php.net/bug.php?id=66444   -  person Isius    schedule 15.01.2014


Ответы (4)


Оригинальный автор создал ошибку на php.net (https://bugs.php.net/bug.php?id=66444), где в итоге был опубликован правильный ответ. Вам нужно использовать недокументированный метод:

->setInterlaceScheme(Gmagick::INTERLACE_LINE)

Вместо:

->setImageInterlaceScheme(Gmagick::INTERLACE_LINE)

Это сработало для меня! Для справки: я использую PHP 5.4.20 с gmagick 1.1.7RC2 поверх GraphicsMagick 1.3.18.

person Jonathan    schedule 25.03.2014
comment
Вы только что спасли мой день. Функция setInterlaceScheme работает, а функция setImageInterlaceScheme — нет. С другой стороны, чтобы получить чересстрочную схему, getImageInterlaceScheme работает, а getInterlaceScheme — нет. Это странно. - person user3032481; 23.12.2018

Документация, на которую вы указываете, гласит:

Используйте Line для создания изображения чересстрочного PNG или GIF или прогрессивного JPEG.

Итак, я думаю, вам следует установить чересстрочную развертку на line.

->setImageInterlaceScheme(Gmagick::INTERLACE_LINE)

Примечание. Я не уверен, что INTERLACE_LINE является фактическим значением. Я предположил, что это было основано на вашем коде. В общем, попробуйте вариант line.

person JSuar    schedule 23.12.2013
comment
Хороший улов! Я пробовал как INTERLACE_LINE, так и INTERLACE_PLANE. Ни один из них не производит прогрессивный JPEG. Я отредактировал вопрос. - person Isius; 24.12.2013
comment
Попробуйте установить для него значение none, а затем отдельно установить для него плоскость или линию, чтобы параметр чересстрочной развертки не применялся, когда применяются все остальные параметры. - person JSuar; 28.12.2013
comment
Пробовал это. Без изменений. - person Isius; 28.12.2013
comment
Я подтвердил, что опция Line работает с утилитой graphicsmagick gm, работающей с JPEG. Линия устанавливает для поля чересстрочной развертки значение Линия. При любом другом значении для него будет установлено значение «Нет». Подтвердили ли вы выходное изображение с помощью другого инструмента только для подтверждения текущего значения чересстрочной развертки? - person JSuar; 28.12.2013
comment
Да, сэр, с помощью нескольких инструментов я подтвердил, что изображение не чересстрочное. Я начинаю задаваться вопросом, не реализован ли setImageInterlaceScheme полностью или, возможно, должным образом. - person Isius; 29.12.2013
comment
Только что проверил источник, и он, кажется, реализован. Он основан на MagickSetImageInterlaceScheme. Возможно, значения чередования отображаются неправильно. Не уверена. - person JSuar; 29.12.2013

Пробовали ли вы звонить setImageInterlaceScheme перед чем-либо еще? я не могу найти код, но возможно когда вы читаете биты, он уже составляет изображение, и тогда переплетения не имеют места.

$img
    ->setImageInterlaceScheme(Gmagick::INTERLACE_PLANE)
    ->readImageBlob($image->getBytes())
    ->setSize(900, 900) 
    ->setImageResolution(96, 96)
    ->setImageFormat('jpeg')
    ->setCompressionQuality(70)
    ->resizeImage(900, 1351, Gmagick::FILTER_UNDEFINED, 1);

Конечно, interlaceScheme должен быть INTERLACE_PLANE, как вы можете прочитать в документах, которые вы уже знаете http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace

person Carlos Robles    schedule 27.12.2013
comment
Да, я пробовал много разных комбинаций заказа. Без изменений. - person Isius; 28.12.2013
comment
Кроме того, setImageInterlaceScheme необходимо вызывать после существования объекта изображения. То есть после readImageBlob в данном случае. - person Isius; 28.12.2013
comment
хорошо знать! нигде не нашел информацию о порядке звонков. - person Carlos Robles; 28.12.2013

Я наконец нашел ответ на этот вопрос (используя PHP IMagick) после нескольких недель борьбы.

Оказывается, вам нужно установить формат изображения «pjpeg», а не просто jpeg.

Я понятия не имею, почему при этом мои изображения правильно определяются как прогрессивные и постепенно отображаются в браузере.

Я предполагаю, что это будет то же самое для «GMagick».

$im->setImageFormat('pjpeg')
person Gordo    schedule 11.02.2014
comment
Жалко... Вы хоть пробовали? Я не мог найти упоминания об этом нигде в документации IMagick и просто попробовал это по прихоти, и это сработало. - person Gordo; 12.02.2014
comment
Ага. Когда я попробовал это, он просто не производил изображения вообще. Так же, как если бы я попробовал любой другой неподдерживаемый формат файла. - person Isius; 12.02.2014