Как остановить GD2 от вымывания цветов при изменении размера изображения?

Я разработал сайт сообщества для обмена фотографиями, используя CodeIgniter 1.7. Размер фотографий, загружаемых участниками, автоматически изменяется в ряде форматов, для которых я использую класс CodeIgniter Image Manipulation. Этот класс встроен в инфраструктуру и, по сути, представляет собой оболочку для нескольких библиотек для работы с изображениями, таких как GD, GD2, ImageMagick и NETPBM. На моем хосте я могу использовать только GD2, поэтому этот вопрос будет о нем.

К моей проблеме. Вот пример фотографии с измененным размером на моем сайте. Обратите внимание, что оригинал был очень большим, шириной более 3000 пикселей:

http://www.jungledragon.com/image/195/female_impala_close-up.html

А теперь взгляните на то же изображение, тоже измененное, только чуть больше на Flickr:

http://www.flickr.com/photos/fledder/3763538865/in/set-72157621744113979

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

введите здесь описание изображения

Хотя это все еще не идеально, оно, по крайней мере, приближается к уровню резкости изображения Flickr. Остается проблема в том, что цвета размываются, как будто снижается их насыщенность. Это происходит уже до фильтра повышения резкости, поэтому должно быть в GD2.

Этот вопрос для меня жизненно важен, но я не знаю, где искать. Я нашел несколько потоков .NET, в которых говорится о подвыборке цветности, но я не знаю, что делать с этой информацией в моей настройке. Я ищу любое решение, которое работает в рамках ограничений моей установки.

Обновление: исходный файл в том виде, в котором я загрузил его на свой сайт и на Flickr:

http://www.jungledragon.com/img/DSC07275.jpg

Обновление 2: я в шоке. В хорошем смысле. Мне потребовалось много усилий, чтобы установить ImageMagick, но после переключения на него (что было связано с установкой «imagemagick» в качестве библиотеки для использования в классе манипулирования изображениями Code Igniter, результат тестового изображения выглядит следующим образом:

введите здесь описание изображения

Изменение размера ImageMagick происходит именно так, как задумано. Цвета сохранены, резкость есть. Да, я отключил свою пользовательскую процедуру повышения резкости, так как она больше не нужна из-за ImageMagick. Кроме того, процесс намного быстрее и требует меньше памяти. И вот еще одна замечательная часть: я не могу этого объяснить, но я абсолютно ничего не сделал, чтобы указать ImageMagick использовать определенный цветовой профиль, который был предложен пользователем @Alix. Пока что в моем тестировании похоже, что информация о цвете учитывается со встроенным профилем или без него. Вывод просто является уменьшенной версией ввода. Действительно ли ImageMagick такой умный или я сплю?


person Fer    schedule 24.04.2011    source источник
comment
Это похоже на проблему с профилем. Имеются ли фотографии с профилем ICC? Можно ли увидеть реальный исходный файл (не версию Flickr)? Есть ли способ попробовать это с ImageMagick, хотя бы временно, чтобы увидеть, есть ли разница?   -  person Pekka    schedule 25.04.2011
comment
Изображение Flickr действительно поставляется со встроенным профилем: IEC 61966-2.1 Default RGB colour space - sRGB не совсем уверен, что нужно сделать, но это то, что вам нужно искать.   -  person Pekka    schedule 25.04.2011
comment
Я обновил вопрос, включив ссылку на исходный файл. Спасибо за подсказку, надеюсь, это сузит круг моих поисков. Я не могу переключиться на ImageMagick в моей текущей конфигурации, но если окажется, что это единственно возможное решение, я буду искать договоренности в этой области. На данный момент я надеюсь, что это можно решить в GD2.   -  person Fer    schedule 25.04.2011
comment
К исходному изображению прикреплен профиль Adobe RGB (1998) ICC. Хм. У тебя есть Фотошоп? Можете ли вы попробовать преобразовать изображение в sRGB и снова загрузить его? Боюсь, я не думаю, что GD сможет справиться с профилем, он ничего о них не знает, поэтому вам придется скармливать ему правильные данные. ImageMagick знает концепцию профилей, по крайней мере, на базовом уровне, отсюда и мой вопрос.   -  person Pekka    schedule 25.04.2011
comment
Я только что попробовал как удалить профиль в Photoshop, так и переключиться на профиль с совершенно другим цветовым оттенком. На экране они выглядят совсем иначе. Пока я их не загружу. Кажется, это не имеет значения, все смягчено, как скриншот в вопросе.   -  person Fer    schedule 25.04.2011
comment
@Ferdy, значит, переключение на sRGB не помогло? Вы пытались сохранить его полностью без профиля (используя флажок в диалоговом окне «Сохранить как»), у меня нет под рукой Photoshop, или я бы попробовал сам.   -  person Pekka    schedule 25.04.2011
comment
Изображение на вашем сайте выглядит ближе к оригиналу, чем на Flickr.   -  person OZ_    schedule 25.04.2011
comment
@OZ_ не для меня! Flickr и оригинальное изображение выглядят почти одинаково в моей системе, изображение GD заметно отличается   -  person Pekka    schedule 25.04.2011
comment
Пекка, пользователи будут смотреть картинки в браузерах, а не в фотошопе, поэтому вам может быть интересно посмотреть, как это выглядит в моем браузере (Opera): img841.imageshack.us/img841/6217/compareb.png   -  person OZ_    schedule 25.04.2011
comment
@ _OZ: интересное наблюдение. Я бы сказал, что все, что вы используете для просмотра оригинала, не соответствует цветовому профилю. Это действительно приведет к приглушенным цветам, которые вы видите. Тем не менее, странно, что вы видите полную насыщенность изображения на Flickr. Что вы использовали для просмотра оригинала?   -  person Fer    schedule 27.04.2011


Ответы (4)


Мне удалось дополнительно проверить это с помощью Imagick:

Тест Imagick sRGB

Левая половина изображения была обработана с помощью Imagick и цветового профиля sRGB_IEC61966-2-1_no_black_scaling.icc, правая половина не имеет связанного цветового профиля и показывает точно так же при обработке с помощью Imagick или GD; вот код, который я использовал:

header('Content-type: image/jpeg');

$image = new Imagick('/path/to/DSC07275.jpg');

if (($srgb = file_get_contents('http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc')) !== false)
{
    $image->profileImage('icc', $srgb);
    $image->setImageColorSpace(Imagick::COLORSPACE_SRGB);
}

$image->thumbnailImage(1024, 0);

echo $image;

Вот сравнение нескольких профилей sRGB, доступных на сайте color.org:

Сравнение sRGB

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


РЕДАКТИРОВАТЬ: по-видимому, Imagick поставляется со встроенным профилем sRGB, поэтому вам не нужно загружать его с веб-сайта Консорциума цветов изображения, следующий код должен обрабатывать все сценарии:

header('Content-type: image/jpeg');

$image = new Imagick('/path/to/DSC07275.jpg');
$version = $image->getVersion();
$profile = 'http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc';

if ((is_array($version) === true) && (array_key_exists('versionString', $version) === true))
{
    $version = preg_replace('~ImageMagick ([^-]*).*~', '$1', $version['versionString']);

    if (is_file(sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version)) === true)
    {
        $profile = sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version);
    }
}

if (($srgb = file_get_contents($profile)) !== false)
{
    $image->profileImage('icc', $srgb);
    $image->setImageColorSpace(Imagick::COLORSPACE_SRGB);
}

$image->thumbnailImage(1024, 0);

echo $image;
person Alix Axel    schedule 25.04.2011
comment
Вау! Я преклоняюсь перед теми усилиями, которые потребовались, чтобы дать такой ответ. Я попытаюсь применить это на практике, если смогу организовать ImageMagick в своей среде. Большое спасибо! Один небольшой вопрос: интересно, как ваш код (3-й профиль) работает для изображений, у которых нет встроенного профиля? - person Fer; 25.04.2011
comment
@Ferdy: На самом деле, я понятия не имею (пока)! : P Я пытаюсь портировать свою собственную оболочку GD для использования Imagick, и я обязательно изучу все эти детали, когда смогу ее протестировать, надеюсь, завтра или около того я смогу обновить этот ответ более полной информацией. :) - person Alix Axel; 25.04.2011
comment
@ Аликс. Круто, похоже, ты идешь по тому же маршруту, впереди меня. Излишне говорить, что мне очень интересны ваши успехи и наблюдения! - person Fer; 25.04.2011
comment
@Ferdy: у меня возникли проблемы с пониманием некоторых поведений Imagick, и я хотел бы опубликовать свой вопрос здесь, в StackOverflow, вы не возражаете, если я использую вашу фотографию в качестве тестового примера? - person Alix Axel; 25.04.2011
comment
Я считаю, что если вы используете scaleImage() или resizeImage() вместо thumbnailImage(), он сохранит цветовой профиль без необходимости вводить его вручную. Это относится к imagemagick в командной строке, я предполагаю, что это также относится к классу Imagick. - person Chad von Nau; 12.09.2013
comment
@AlixAxel Мне нужно было только сохранить профиль, а не навязывать другой, но ваш ответ поставил меня на правильный путь. Я оставил свой комментарий, чтобы сэкономить немного времени другим людям в такой же ситуации. - person Chad von Nau; 14.09.2013
comment
Хорошо сделано. Просто обратите внимание, чтобы не использовать stripImage, который удаляет цветовой профиль и изменяет результат цвета. - person Ricardo Martins; 17.07.2015
comment
Хороший ответ, но все знают, что несколько означает 5-9, а несколько - 1-4. - person pishpish; 27.04.2016

К исходному изображению прикреплен профиль Adobe RGB (1998) ICC. Я думаю, что GD, не зная о профилях, неправильно интерпретирует данные изображения. Вот связанная ошибка PHP, подтверждающая это.

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

Если вам нужно постоянное решение проблемы на стороне сервера, я думаю, вам понадобится библиотека обработки изображений, которая может работать с профилями. Честно говоря, я не знаю, как ImageMagick справляется с такими вещами, но, по крайней мере, он знаком с базовой концепцией цветовых профилей.

По теме: Сравнение sRGB и Adobe RGB

person Pekka    schedule 24.04.2011
comment
Моя идея решения заключалась бы в том, что пользователям не нужно каким-либо особым образом подготавливать свои изображения перед загрузкой. Как и Фликр. Поэтому подготовка изображения не требуется. Тем не менее, у вас есть очень полезный ответ. Я все еще надеюсь на решение GD2 и пока оставлю вопрос открытым. Если решение не придет, я изучу ImageMagick и отмечу ваш ответ как ответ. Спасибо! - person Fer; 25.04.2011
comment
@ Ферди, пожалуйста. Боюсь, я не думаю, что для этого будет решение GD2, но я могу ошибаться. Вот кто-то с такой же проблемой: bugs.php.net/bug.php?id=53598 - person Pekka; 25.04.2011
comment
Вы, вероятно, правы. Доказательств того, что это действительно связано с профилями, становится все больше. Я приму это как факт, но мне все еще нужно решение :) - person Fer; 25.04.2011
comment
Я сейчас передумал. В моем тестовом изображении был цветовой профиль Adobe RGB, что действительно было ошибкой с моей стороны, чтобы правильно экспортировать его в Интернет из Lightroom. Я тестировал фотографии других участников и не вижу разницы в цвете. Поэтому возникает вопрос, сколько пользователей не экспортируют с использованием sRGB или без цветового профиля? Если этот процент невелик, я, возможно, смогу жить с этим. Что вы думаете? - person Fer; 25.04.2011
comment
@ Ферди хороший вопрос! Если изображение получено с вашей камеры или из Lightroom с прикрепленным профилем, я полагаю, что это не совсем исключено среди профессиональных фотографов. Но я действительно не знаю. Может быть, спросить на photography.stackexchange.com? - person Pekka; 25.04.2011
comment
Хорошее предложение, я разместил там вопросы о статистике: photo.stackexchange.com/questions/11265/ - person Fer; 25.04.2011

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

Я использую онлайн-инструмент для продажи фотографий, который передискретизирует все мои изображения с помощью GD. У меня были проблемы с изображениями, которые выглядели странно даже при загрузке с правильным преобразованием sRGB и включенным профилированием ICC при просмотре на моем мониторе с широкой гаммой.

Я обнаружил, что проблема заключается в том, что GD удаляет все метаданные и профили ICC из исходных файлов. Тогда браузеры, не видя ни одного профиля, отображают их некорректно. Это незначительно на мониторе со стандартной гаммой, но очень заметно на мониторе с широкой гаммой.

Если у вас возникли проблемы с этим, вы можете проверить мою теорию, используя Firefox и изменив настройку в about:config. Измените значение «gfx.color_management.mode» со значения по умолчанию «2» на «1». Этот параметр заставит Firefox считать любое изображение без профиля ICC sRGB и отображать его как таковое. После этого изображения должны выглядеть так, как вы ожидаете, и идентичны Photoshop/Lightroom/и т. д. Почему все браузеры не используют этот здравый смысл по умолчанию, мне непонятно.

К сожалению, моя корзина настроена только на использование PHP GD, поэтому в настоящее время я не могу получить хорошие результаты. Я бы очень хотел, чтобы GD был обновлен, чтобы оставлять профили ICC прикрепленными или иметь возможность добавлять простой профиль sRGB при экспорте.

Подробнее здесь: http://www.gballard.net/psd/go_live_page_profile/embeddedJPEGprofiles.html#

person Sean    schedule 10.12.2012

Я нашел этот скрипт:

https://github.com/slavicv/jpeg-icc/blob/master/class.jpeg_icc.php

Этот сценарий копирует цветовой профиль из исходного изображения в новое изображение. Таким образом, после изменения размера вы можете добавить цветовой профиль из исходного изображения. Этот скрипт не нуждается в Imagick, чтобы добиться цели.

person Gerda Havertong    schedule 04.05.2013