/*
Функция накладывает логотип $logo, имеющий
альфа-канал $alpha, на картинку $img со смещением
по координатам $base_x и $base_y
$alpha - grayscale картинка с разрешением,
аналогичным $logo, в которой черный цвет означает абсолютную
непрозрачность, белый - абсолютная прозрачность, остальные
цвета - различную степень полупрозрачности.
*/
function imagecopyalpha(&$img, $logo, $alpha, $base_x, $base_y)
{
$width = imagesx($alpha);
$height = imagesy($alpha);
$base_width = imagesx($img);
$base_height = imagesy($img);
for ($x = 0; $x < $width; $x++, $base_x++) {
if ($base_x < 0) continue;
if ($base_x >= $base_width) break;
for ($y = 0; $y < $height; $y++, $base_y++) {
if ($base_y < 0) continue;
if ($base_y >= $base_height) break;
/*
узнаем цвет пикселя картинки, на которую нужно наложить логотип
*/
$img_color = imagecolorat($img, $base_x, $base_y);
/*
цвет пикселя для логотипа
*/
$logo_color = imagecolorat($logo, $x, $y);
/*
узнаем значение "альфа-канала" для текущего пиксела логотипа
(в нашем случае это синяя составляющая картинки $alpha)
и нормализуем его, чтобы оно лежало в пределах от 0 до 1
(0 - абсолютная непрозрачность, 1 - абсолютная прозрачность
*/
$a = (imagecolorat($alpha, $x, $y) & 0xff) / 255.0;
/*
а вот тут начинается самое интересное - наложение логотипа
на исходное изображение с учетом нашего "альфа-канала".
Результирующий цвет пикселя вычисляется по очевидной формуле:
result_color = base_color * alpha + (1 - alpha) * logo_color
*/
$r = (int) ((($img_color >> 16) & 0xff) * $a + (1.0 - $a) * (($logo_color >> 16) & 0xff));
$g = (int) ((($img_color >> 8) & 0xff) * $a + (1.0 - $a) * (($logo_color >> 8) & 0xff));
$b = (int) (($img_color & 0xff) * $a + (1.0 - $a) * ($logo_color & 0xff));
$new_color = ($r << 16) | ($g << 8) | $b;
imagesetpixel($img, $base_x, $base_y, $new_color);
}
$base_y -= $height;
}
}