PHP Imagemagick конвертирует оттенки серого в RGB

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

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

Это прекрасно работает, за исключением изображений, которые были окрашены в оттенки серого. Цветовой профиль добавляется, но когда я открываю изображение в Photoshop, появляется сообщение: «Невозможно использовать встроенный профиль ICC, поскольку профиль ICC недействителен. Игнорирование профиля». В Photoshop изображение установлено в оттенках серого, а не в RGB, поэтому прикрепленный профиль RGB неверен. Мне нужно, чтобы это было RGB.

Я использую следующий код, чтобы добавить всю возможную информацию в попытке сделать изображение RGB:

<?php
$i = new Imagick();
$i->readimage('image.jpg');
$i->setimagetype(Imagick::IMGTYPE_TRUECOLOR);
$i->setimagecolorspace(Imagick::COLORSPACE_RGB);
$i->profileimage('icc', file_get_contents('AdobeRGB1998.icc'));
$i->writeimage($d);
$i->destroy();
?>

Кто-нибудь знает, как успешно установить изображение в RGB и прикрепить профиль?

Я пробовал разные методы и комбинации для «setImageProfile» и «profileImage», а также для цветового пространства и типа изображения, но результат всегда один и тот же.


person ar34z    schedule 25.06.2012    source источник
comment
Вы читаете в файле. Вы уверены, что он не содержит профиля, который с добавлением вашего профиля приведет к тому, что Adobe Photoshop сделает сообщение о недействительном профиле? А знаете ли вы, что конкретно означает уведомление вашей копии Adobe Photoshop?   -  person hakre    schedule 25.06.2012
comment
Файл, созданный с помощью GD, (всегда) не имеет цветового профиля. Я думаю, что уведомление в PS означает, что я прикрепил профиль, предназначенный для цветов, который не подходит для изображений в оттенках серого. Photoshop по умолчанию видит изображение в оттенках серого, даже без прикрепленного цветового профиля. Кроме того, когда изображение находится в режиме оттенков серого, в PS я могу прикрепить только цветовые профили с именами «Расширение точек 10%», «20%» и т. д. Если я изменю изображение на RGB, я могу прикрепить нужный мне цветовой профиль. Каким-то образом я должен сообщить PS, что это изображение RGB только с серыми пикселями или что-то в этом роде.   -  person ar34z    schedule 25.06.2012
comment
Я бы сказал, что при чтении набора изображений неправильный тип изображения. Возможно, вам потребуется создать новое изображение и добавить изображение из файла. Вы уже пробовали это?   -  person hakre    schedule 26.06.2012
comment
Вы имеете в виду создать пустое изображение, установить все свойства и добавить изображение, которое я действительно хочу изменить? Я попробую.   -  person ar34z    schedule 26.06.2012
comment
Да, я имею в виду это. Также проверьте параметры при записи файла.   -  person hakre    schedule 27.06.2012
comment
У меня не было времени заниматься этим, но мне удалось исправить это, «обманув» изображение. Я взял 1 пиксель и добавил к нему чуть больше цвета. Я отредактирую код в своем исходном сообщении.   -  person ar34z    schedule 06.08.2012
comment
@ ar34z: К вашему сведению, если вы нашли решение, вполне приемлемо ответить на свой вопрос и принять свой собственный ответ.   -  person Leigh    schedule 06.08.2012
comment
Спасибо, Ли. я сделал это   -  person ar34z    schedule 06.08.2012


Ответы (2)


@a34z говорит в комментарии:

"Каким-то образом я должен сообщить PS, что это изображение RGB с одними серыми пикселями или что-то в этом роде".

Фундаментальная ошибка — предполагать, что изображение RGB может содержать даже «серые» пиксели как таковые!

Изображения RGB имеют пиксели, которые всегда состоят из смеси 3 цветов: красный красный + зеленый зеленый + синий лю. Это 3 канала, которые доступны, не более. В RGB нет такого понятия, как серый канал.

Что делает изображение RGB выглядит серым для наших глаз, так это тот факт, что каждое из 3 числовых значений каналов равны или менее строго говоря, по крайней мере, «достаточно похожи». Конечно, есть также программное обеспечение, которое может анализировать значения цвета 3 каналов и сообщать вам, какие пиксели являются «серыми». Вывод гистограммы ImageMagick с радостью подскажет вам, какие оттенки серого вы бы назвали, и использует разные названия для этих оттенков серого. Но не обманывайтесь этим названием цвета: пиксель по-прежнему будет состоять из 3 цветов с одинаковой (или очень похожей) интенсивностью, и ImageMagick также сообщит эти значения.

Если вам действительно нужно чистое изображение в градациях серого (которое использует только один канал для уровня серого, а не три), то вам нужно преобразовать его в такой тип изображения.

Два изображения могут по-прежнему выглядеть одинаково (если преобразование было выполнено правильно, и если ваш монитор откалиброван, и если вы не слепы к красному-зеленому-слепому), но их внутренняя файловая структура отличается.

Изображениям RGB нужны профили ICC, которые работают с RGB (если есть), такие как sRGB. Для оттенков серого вы не можете использовать sRGB, там вы можете использовать DeviceGray или что-то в этом роде...

person Kurt Pfeifle    schedule 06.08.2012
comment
Да, я знаю, что изображение по-прежнему состоит из каналов RGB, но я ничего не могу поделать с тем, что Photoshop видит его как изображение в оттенках серого и говорит, что прикрепленный цветовой профиль недействителен. - person ar34z; 07.08.2012

Это сработало для меня, чтобы распознать его как изображение в истинном цвете. Предполагая, что $img - это объект Imagick, содержащий изображение в оттенках серого, я проверяю, действительно ли это оттенки серого, а затем редактирую 1 случайный пиксель и изменяю его значение красного, добавляя или вычитая 5 значений, в зависимости от того, красный больше 5 или нет.

<?php
if ($img->getImageType() == Imagick::IMGTYPE_GRAYSCALE)
{
    // Get the image dimensions
    $dim = $img->getimagegeometry();

    // Pick a random pixel
    $x = rand(0, $dim['width']-1);
    $y = rand(0, $dim['height']-1);

    // Define our marge
    $marge = 5;
    //$x = 0;
    //$y = 0;

    // Debug info
    echo "\r\nTransform greyscale to true color\r\n";
    echo "Pixel [$x,$y]\n";

    // Get the pixel from the image and get its color value
    $pixel = $img->getimagepixelcolor($x, $x);
    $color = $pixel->getcolor();
    array_pop($color); // remove alpha value

    // Determine old color for debug
    $oldColor   = 'rgb(' . implode(',',$color) . ')';
    // Set new red value
    $color['r'] = $color['r'] >= $marge ? $color['r']-$marge : $color['r'] + $marge;
    // Build new color string
    $newColor   = 'rgb(' . implode(',',$color) . ')';

    // Set the pixel's new color value
    $pixel->setcolor($newColor);

    echo "$oldColor -> $newColor\r\n\r\n";

    // Draw the pixel on the image using an ImagickDraw object on the given coordinates
    $draw = new ImagickDraw();
    $draw->setfillcolor($pixel);
    $draw->point($x, $y);
    $img->drawimage($draw);

    // Done, 
    unset($draw, $pixel);
}
// Do other stuff with $img here
?>

Надеюсь, это поможет кому-нибудь в будущем.

person ar34z    schedule 06.08.2012