Не так давно, взял за идею попробовать повторить урок колорированния фото как в уроке на сайте: http://www.photoshop-master.ru Но что самое интересное, решил я это сделать не в фотошопе, а с помощью PHP и библиотеки GD, которая предназначена для работы с изображениями.
Если разглядеть данный урок, то можно заметить, что все изменения фотографии придаются простыми режимами наложения. Так что теперь надо было бы найти алгоритмы этих самых режимов наложения. В уроке их используется четыре:
Исключение (Exclusion)
Перекрытие (Overlay)
Мягкий свет (Soft Light)
Жесткий свет (Hard Light)
Здесь, $bottom_color – цвет пикселя, на который происходит наложение, а $top_color – цвет пикселя, который налаживается.
Но теперь возникла проблема придания изображению, которое налаживается, прозрачности. Здесь все решилось подбором другого цвета. Например, вместо цвета #0000ff, как в уроке, был использован цвет #1b007e, вместо #ffcc99 – #c1a991, вместо #000000 – #404040. Что из всего этого получилось можно увидеть ниже. А теперь перейдем непосредственно к самому коду (прикрепляю комментарии, чтобы было понятнее):
Может не точно попал в цвет, но, согласитесь, очень похоже.
Если разглядеть данный урок, то можно заметить, что все изменения фотографии придаются простыми режимами наложения. Так что теперь надо было бы найти алгоритмы этих самых режимов наложения. В уроке их используется четыре:
- Исключение (Exclusion)
- Перекрытие (Overlay)
- Мягкий свет (Soft Light)
- Жесткий свет (Hard Light)
Исключение (Exclusion)
$color = 255-(((255-$bottom_color)*(255-$top_color)/255)+($bottom_color*$top_color/255));
Перекрытие (Overlay)
$color = $bottom_color<128?(2*$bottom_color*$top_color)/255:255-(2*(255-$bottom_color)*(255-$top_color)/255);
Мягкий свет (Soft Light)
$color = (255-2*$top_color)*pow(($bottom_color/255),2)+2*$top_color*($bottom_color/255);
Жесткий свет (Hard Light)
$color = $top_color<128?(2*$bottom_color*$top_color)/255:255-((2*(255-$bottom_color)*(255-$top_color))/255);
Здесь, $bottom_color – цвет пикселя, на который происходит наложение, а $top_color – цвет пикселя, который налаживается.
Но теперь возникла проблема придания изображению, которое налаживается, прозрачности. Здесь все решилось подбором другого цвета. Например, вместо цвета #0000ff, как в уроке, был использован цвет #1b007e, вместо #ffcc99 – #c1a991, вместо #000000 – #404040. Что из всего этого получилось можно увидеть ниже. А теперь перейдем непосредственно к самому коду (прикрепляю комментарии, чтобы было понятнее):
// 1. Получаем размеры загруженного изображения $uploadfile
$size = getimagesize($uploadfile);
// 2. Создаем новое изображение из нашего загруженного
$source = imagecreatefromjpeg($uploadfile);
//3. Создаем изображение true color с шириной и высотой как у нашей оригинальной картинки
$im = imagecreatetruecolor($size[0], $size[1]);
//4. Запускаем цикл с перебором каждого пикселя по ширине
for ($x = 0; $x < $size[0]; $x++) {
//5. Запускаем вложенный цикл с перебором каждого пикселя по высоте
for ($y = 0; $y < $size[1]; $y++) {
//6. Получаем индекс цвета изображения-оригинала и переводим его в RGB
$colors = imagecolorsforindex($source, imagecolorat($source, $x, $y));
//7. Присваиваем переменным значения каналов red, green и blue
$r = $colors['red'];
$g = $colors['green'];
$b = $colors['blue'];
//8. Дублируем каналы. Это надо для финального шага, как в уроке фотошоп
$r_dub = $r;
$g_dub = $g;
$b_dub = $b;
//9. Налаживаем цвет #1b007e (R=27 G=0 B=126) на пиксель с изображения-оригинала
//Режим наложения Исключение (Exclusion)
//Присваиваем новые значения каналов red, green и blue переменным
$r = ceil(255 - (((255 - $r) * (255 - 27) / 255) + ($r * 27 / 255)));
$g = ceil(255 - (((255 - $g) * (255 - 0) / 255) + ($g * 0 / 255)));
$b = ceil(255 - (((255 - $b) * (255 - 126) / 255) + ($b * 126 / 255)));
//10. Налаживаем цвет #c1a991 (193, 169, 145), режим наложения Перекрытие (Overlay)
if ($r <= 128) { $r = intval((2 * $r * 193) / 255); }
else { $r = intval(255 - ((2 * (255 - $r) * (255 - 193)) / 255)); }
if ($g <= 128) { $g = intval((2 * $g * 169) / 255); }
else { $g = intval(255 - ((2 * (255 - $g) * (255 - 169)) / 255)); }
if ($b <= 128) { $b = intval((2 * $b * 145) / 255); }
else { $b = intval(255 - ((2 * (255 - $b) * (255 - 145)) / 255)); }
//11. Налаживаем цвет #404040 (64, 64, 64), режим наложения Мягкий свет (Soft Light)
$r = intval((255 - 2 * 64) * pow(($r / 255),2) + 2 * 64 * ($r / 255));
$g = intval((255 - 2 * 64) * pow(($g / 255),2) + 2 * 64 * ($g / 255));
$b = intval((255 - 2 * 64) * pow(($b / 255),2) + 2 * 64 * ($b / 255));
//12. Налаживаем пиксель изображения-оригинала на ранее обработанный пиксель
//Режим наложения Жесткий свет (Hard Light)
if ($r_dub < 128) { $r = intval((2 * $r * $r_dub) / 255); }
else { $r = intval(255 - ((2 * (255 - $r) * (255 - $r_dub)) / 255)); }
if ($g_dub < 128) { $g = intval((2 * $g * $g_dub) / 255); }
else { $g = intval(255 - ((2 * (255 - $g) * (255 - $g_dub)) / 255)); }
if ($b_dub < 128) { $b = intval((2 * $b * $b_dub) / 255); }
else { $b = intval(255 - ((2 * (255 - $b) * (255 - $b_dub)) / 255)); }
//13. Возвращаем идентификатор цвета для изображения из наших каналов
$color = imagecolorallocate($im, $r,$g,$b);
//14. Устанавливаем полученный цвет для нужного пикселя в изображении $im
imagesetpixel($im, $x, $y, $color);
}
}
//15. Сохраняем полученное изображение $im в файл $uploadfile с качеством 100%
imagejpeg($im, $uploadfile, 100);
//16. Уничтожаем изображение $im
imagedestroy($im);
Вот такой незамысловатый код. Возможно, он несет большую нагрузку, но писался исключительно в ознакомительных целях. И, в конце концов, посмотрим результат его выполнения:Может не точно попал в цвет, но, согласитесь, очень похоже.
Комментариев нет:
Отправить комментарий