Roy Conejo says:
I' had to "per-pixel alpha blend" an image into a solid background, as seen on the very concise example from "barnabas at kendall dot NOSPAM dot net": an alpha blended .png logo on a .jpg photograph. The problem was... it doesn't worked out at all here (why? T_T).
Note that I'm using just the source alpha to determine how much colour from source and destination will be present on the final pixel... and that I've to multiply the alpha value (0 - 127) by 2 because I need it to be 8 bits for the calculations.
I think the code is pretty fast, no decimals, no rounding, no unnecesary coding. Bound checking or clipping could be implemented if you really need to.
I hope it helps someone on my same situation ^.^
<?php
function
alpha_blending ($dest, $source, $dest_x, $dest_y) {
for ($y = 0; $y < imagesy($source); $y++) {
for ($x = 0; $x < imagesx($source); $x++) {
$argb_s = imagecolorat ($source ,$x ,$y);
$argb_d = imagecolorat ($dest ,$x+$dest_x ,$y+$dest_y);
$a_s = ($argb_s >> 24) << 1; $r_s = $argb_s >> 16 & 0xFF;
$g_s = $argb_s >> 8 & 0xFF;
$b_s = $argb_s & 0xFF;
$r_d = $argb_d >> 16 & 0xFF;
$g_d = $argb_d >> 8 & 0xFF;
$b_d = $argb_d & 0xFF;
if ($a_s == 0) {
$r_d = $r_s; $g_d = $g_s; $b_d = $b_s;
}
else if ($a_s > 253) {
} else {
$r_d = (($r_s * (0xFF-$a_s)) >> 8) + (($r_d * $a_s) >> 8);
$g_d = (($g_s * (0xFF-$a_s)) >> 8) + (($g_d * $a_s) >> 8);
$b_d = (($b_s * (0xFF-$a_s)) >> 8) + (($b_d * $a_s) >> 8);
}
$rgb_d = imagecolorallocatealpha ($dest, $r_d, $g_d, $b_d, 0);
imagesetpixel ($dest, $x, $y, $rgb_d);
}
}
}
$source = imagecreatefrompng ('logo.png');
$dest = imagecreatefromjpg ('photo.jpg');
alpha_blending ($dest, $source, 10, 5);
imagedestroy ($source);
imagedestroy ($dest);
?>
eof =p