Как помешать GD2 размывать цвета при изменении размеров изображений? - PullRequest
34 голосов
/ 25 апреля 2011

Я разработал сайт сообщества по обмену фотографиями с использованием 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

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

enter image description here

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

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

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

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

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

enter image description here

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

Ответы [ 4 ]

25 голосов
/ 25 апреля 2011

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

Imagick sRGB Test

Левая половина изображения была обработана с помощью 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 Comparison

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


EDIT : По-видимому, Imagick поставляется с профилем sRGB в комплекте, поэтому вам не нужно загружать его с веб-сайта Консорциума Image Color, следующий код должен обрабатывать все сценарии:

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;
6 голосов
/ 25 апреля 2011

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

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

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

Связанный: Сравнение sRGB и Adobe RGB

4 голосов
/ 10 декабря 2012

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

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

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

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

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

Больше информации здесь: http://www.gballard.net/psd/go_live_page_profile/embeddedJPEGprofiles.html#

3 голосов
/ 04 мая 2013

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

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

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

...