Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Image Functions : imagealphablending

imagealphablending

Set the blending mode for an image (PHP 4 >= 4.0.6, PHP 5)
bool imagealphablending ( resource image, bool blendmode )


Code Examples / Notes » imagealphablending

www.deebster.com

Your target image resource not must be paletted if you want to use blending.
This means using ImageCreateTrueColor() rather than ImageCreate().
(If your source is e.g. a jpeg and you've used ImageCreateFromJPEG(), the above is irrelevant.)


webmaster

When saving images for use in transparent overlays like the logo addition mentioned above I've found that it is not succesful with PNG-24, only GIF and PNG-8.  I've had great success with PNG-8's.

roonlyycolowercanesejo

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
## BEGIN of function alpha_blending -------------------------------------------
function
alpha_blending ($dest, $source, $dest_x, $dest_y) {

## lets blend source pixels with source alpha into destination =)
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; ## 7 to 8 bits.
$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;

## source pixel 100% opaque (alpha == 0)
if ($a_s == 0) {
$r_d = $r_s; $g_d = $g_s; $b_d = $b_s;
}
## source pixel 100% transparent (alpha == 255)
else if ($a_s > 253) {
## using source alpha only, we have to mix (100-"some") percent
## of source with "some" percent of destination.
} 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);
}
}
}
## END of function alpha_blending -------------------------------------------



## let's start loading images as usual...
$source = imagecreatefrompng ('logo.png');
$dest = imagecreatefromjpg ('photo.jpg');
## alpha blend $source into $dest starting at 10, 5.
alpha_blending ($dest, $source, 10, 5);

## here you'll have to save "$dest" or send it to the browser...
##

imagedestroy ($source);
imagedestroy ($dest);

?>
eof =p


boo

Notice that AlphaBlending is ON by default.
So, only use this function if you don't want to use AlphaBlending.


joe

Note that alpha blending must be enabled to render antialiased text in true color mode.
For OLDER versions of PHP and/or GD (e.g. which comes with Debian woody) alpha blending is DISABLED by default and it is ENABLED for NEWER versions.


raisul kabir ruman

In the previous message, I found it is working perfect. But, it can be done a lot easily, as is described by the first message by "barnabas at kendall dot NOSPAM dot net". Though, it don't work totally, instead of using imageAlphaBlending, you have to use imageSaveAlpha
So, I found the corrected and smalled code would be
<?php
$im_a = @imagecreatefrompng("a.png");
$im_c = @imagecreatefrompng("c.png");
imageSaveAlpha($im_c, true);
imagecopy($im_c,$im_a,0,0,0,0,200,200);
header("Content-type: image/png");
imagepng($im_c);
?>


barnabas

If you are trying to copy a transparant image on to another image, you might assume that you should apply the ImageAlphaBlending function to the image that has the transparancy, the source image. In reality, you must apply the ImageAlphaBlending function to the destination image. Basically it's saying, "make the specified image respect transparancy".
Here's a real world example. Suppose you want to put your logo on the upper left corner of a photograph. Your logo is a PNG with transparancy, and the photo is a JPEG. Here's what you would do:
<?php
$photoImage = ImageCreateFromJPEG('photo.jpg');
ImageAlphaBlending($photoImage, true);
$logoImage = ImageCreateFromPNG('logo.png');
$logoW = ImageSX($logoImage);
$logoH = ImageSY($logoImage);
ImageCopy($photoImage, $logoImage, 0, 0, 0, 0, $logoW, $logoH);
ImageJPEG($photoImage); // output to browser
ImageDestroy($photoImage);
ImageDestroy($logoImage);
?>


tcarter

If you are saving an image as PNG with transparency then saving it as a PNG-8 will give it transparency in the same way GIF has, but that won't work with this function.
For this function to work the image needs to have an alpha channel (obviously really when you think about it), so make sure you save as PNG-24


dscharrer

If imagealphablending os set to true and you want to merge two images, you are left with no transparency. If it is set to false, only the transparency of the second image is respected, causing no parts of the first image to be shown. To solve this use the following function:
<?
//Merge multiple images and keep transparency
//$i is and array of the images to be merged:
// $i[1] will be overlayed over $i[0]
// $i[2] will be overlayed over that
// ...
//the function returns the resulting image ready for saving
function imagemergealpha($i) {
//create a new image
$s = imagecreatetruecolor(imagesx($i[0]),imagesy($i[1]));

//merge all images
imagealphablending($s,true);
$z = $i;
while($d = each($z)) {
 imagecopy($s,$d[1],0,0,0,0,imagesx($d[1]),imagesy($d[1]));
}

//restore the transparency
imagealphablending($s,false);
$w = imagesx($s);
$h = imagesy($s);
for($x=0;$x<$w;$x++) {
 for($y=0;$y<$h;$y++) {
  $c = imagecolorat($s,$x,$y);
  $c = imagecolorsforindex($s,$c);
  $z = $i;
  $t = 0;
  while($d = each($z)) {
   $ta = imagecolorat($d[1],$x,$y);
   $ta = imagecolorsforindex($d[1],$ta);
   $t += 127-$ta['alpha'];
  }
  $t = ($t > 127) ? 127 : $t;
  $t = 127-$t;
  $c = imagecolorallocatealpha($s,$c['red'],$c['green'],$c['blue'],$t);
  imagesetpixel($s,$x,$y,$c);
 }
}
imagesavealpha($s,true);
return $s;
}
?>


jaypeesorenatgeemail

I rewrote the code given below to skip calculations and pixel setting when not needed (full opaque or full transparent pixels), as the content of my overlays is generally mostly transparent. Reduced processing time from ~0.17s to ~0.06s on 216x145px images.
function alphaOverlay($destImg, $overlayImg, $imgW, $imgH)
{
for($y=0;$y<$imgH;$y++)
{
for($x=0;$x<$imgW;$x++)
{
$ovrARGB = imagecolorat($overlayImg, $x, $y);
$ovrA = ($ovrARGB >> 24) << 1;
$ovrR = $ovrARGB >> 16 & 0xFF;
$ovrG = $ovrARGB >> 8 & 0xFF;
$ovrB = $ovrARGB & 0xFF;

$change = false;
if($ovrA == 0)
{
$dstR = $ovrR;
$dstG = $ovrG;
$dstB = $ovrB;
$change = true;
}
elseif($ovrA < 254)
{
$dstARGB = imagecolorat($destImg, $x, $y);
$dstR = $dstARGB >> 16 & 0xFF;
$dstG = $dstARGB >> 8 & 0xFF;
$dstB = $dstARGB & 0xFF;

$dstR = (($ovrR * (0xFF-$ovrA)) >> 8) + (($dstR * $ovrA) >> 8);
$dstG = (($ovrG * (0xFF-$ovrA)) >> 8) + (($dstG * $ovrA) >> 8);
$dstB = (($ovrB * (0xFF-$ovrA)) >> 8) + (($dstB * $ovrA) >> 8);
$change = true;
}
if($change)
{
$dstRGB = imagecolorallocatealpha($destImg, $dstR, $dstG, $dstB, 0);
imagesetpixel($destImg, $x, $y, $dstRGB);
}

}
}
return $destImg;
}


jeppe dot dyrby

I have create a little function for putting a watermark on any picture.
Watermark can be png, with transparency, and the watermark can be placed anywhere on the image, using simple strings such as 'bottom-left', or 'center'.
<?
function imagelogo (&$dst_image, $src_image, $dst_w, $dst_h, $src_w, $src_h, $position='bottom-left') {
imagealphablending($dst_image,true);
imagealphablending($src_image,true);
if ($position == 'random') {
$position = rand(1,8);
}
switch ($position) {
case 'top-right':
case 'right-top':
case 1:
imagecopy($dst_image, $src_image, ($dst_w-$src_w), 0, 0, 0, $src_w, $src_h);
break;
case 'top-left':
case 'left-top':
case 2:
imagecopy($dst_image, $src_image, 0, 0, 0, 0, $src_w, $src_h);
break;
case 'bottom-right':
case 'right-bottom':
case 3:
imagecopy($dst_image, $src_image, ($dst_w-$src_w), ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'bottom-left':
case 'left-bottom':
case 4:
imagecopy($dst_image, $src_image, 0 , ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'center':
case 5:
imagecopy($dst_image, $src_image, (($dst_w/2)-($src_w/2)), (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
case 'top':
case 5:
imagecopy($dst_image, $src_image, (($dst_w/2)-($src_w/2)), 0, 0, 0, $src_w, $src_h);
break;
case 'bottom':
case 6:
imagecopy($dst_image, $src_image, (($dst_w/2)-($src_w/2)), ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'left':
case 7:
imagecopy($dst_image, $src_image, 0, (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
case 'right':
case 8:
imagecopy($dst_image, $src_image, ($dst_w-$src_w), (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
}
}
// example:
imagelogo($image, $watermark, imagesx($image), imagesy($image), imagesx($watermark), imagesy($watermark), 'random');
?>


jakub argasiƱski

I have been looking around for a while to find a script which does the following: generates image with text using specified font with given color, but with totally transparent background (by alpha-channnel, not via color transparency). Finally, I have created the script by myself. It's just a rough idea how to do it.
<?php
$tekst = "This is a test message\nza¿ó³æ gê¶l± ja¼ñ!\nZA¯Ó£Æ GʦL¡ JA¬Ñ?";
$h = 9;
$size = imageTTFBBox($h, 0, "arial.ttf", $tekst);
$image = imageCreateTrueColor(abs($size[2]) + abs($size[0]), abs($size[7]) + abs($size[1]));
imageSaveAlpha($image, true);
ImageAlphaBlending($image, false);
$tlo = imagecolorallocatealpha($image, 220, 220, 220, 127);
imagefill($image, 0, 0, $tlo);
$napis = imagecolorallocate($image, 220, 220, 220);
imagettftext($image, $h, 0, 0, abs($size[5]), $napis, "arial.ttf", $tekst);
imagepng($image, "output.png");
imagedestroy($image);
?>
<html>
<head>
</head>
<body bgcolor="#808080">
<img src="output.png" alt="">
</body>
</html>


ashita

For "webmaster at nweurosport dot com" :
Currently IE does not support 24 (+8 alpha) bit PNG-s (nor any kind of transparent images). Mozilla and Opera handle them correctly.


luke dot stanley

"If imagealphablending os set to true and you want to merge two images, you are left with no transparency. If it is set to false, only the transparency of the second image is respected, causing no parts of the first image to be shown. To solve this use the following function:"
dscharrer at gmail dot com offered this without a use example, so here is one:
<?
$flag = imagecreatefrompng('a.png');
$mask = imagecreatefrompng('b.png');
imagealphablending($flag, 1);
imagealphablending($mask, 1);
$i= array($flag, $mask); // here is the array of images, using the above specified $flag and $mask images
$s = imagemergealpha($i);
header("Content-type: image/png");
imagepng($s);
//Merge multiple images and keep transparency
//$i is and array of the images to be merged:
// $i[1] will be overlayed over $i[0]
// $i[2] will be overlayed over that
// ...
//the function returns the resulting image ready for saving
function imagemergealpha($i) {
//create a new image
$s = imagecreatetruecolor(imagesx($i[0]),imagesy($i[1]));

//merge all images
imagealphablending($s,true);
$z = $i;
while($d = each($z)) {
 imagecopy($s,$d[1],0,0,0,0,imagesx($d[1]),imagesy($d[1]));
}

//restore the transparency
imagealphablending($s,false);
$w = imagesx($s);
$h = imagesy($s);
for($x=0;$x<$w;$x++) {
 for($y=0;$y<$h;$y++) {
  $c = imagecolorat($s,$x,$y);
  $c = imagecolorsforindex($s,$c);
  $z = $i;
  $t = 0;
  while($d = each($z)) {
  $ta = imagecolorat($d[1],$x,$y);
  $ta = imagecolorsforindex($d[1],$ta);
  $t += 127-$ta['alpha'];
  }
  $t = ($t > 127) ? 127 : $t;
  $t = 127-$t;
  $c = imagecolorallocatealpha($s,$c['red'],$c['green'],$c['blue'],$t);
  imagesetpixel($s,$x,$y,$c);
 }
}
imagesavealpha($s,true);
return $s;
}
?>


Change Language


Follow Navioo On Twitter
gd_info
getimagesize
image_type_to_extension
image_type_to_mime_type
image2wbmp
imagealphablending
imageantialias
imagearc
imagechar
imagecharup
imagecolorallocate
imagecolorallocatealpha
imagecolorat
imagecolorclosest
imagecolorclosestalpha
imagecolorclosesthwb
imagecolordeallocate
imagecolorexact
imagecolorexactalpha
imagecolormatch
imagecolorresolve
imagecolorresolvealpha
imagecolorset
imagecolorsforindex
imagecolorstotal
imagecolortransparent
imageconvolution
imagecopy
imagecopymerge
imagecopymergegray
imagecopyresampled
imagecopyresized
imagecreate
imagecreatefromgd2
imagecreatefromgd2part
imagecreatefromgd
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromstring
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
imagecreatetruecolor
imagedashedline
imagedestroy
imageellipse
imagefill
imagefilledarc
imagefilledellipse
imagefilledpolygon
imagefilledrectangle
imagefilltoborder
imagefilter
imagefontheight
imagefontwidth
imageftbbox
imagefttext
imagegammacorrect
imagegd2
imagegd
imagegif
imagegrabscreen
imagegrabwindow
imageinterlace
imageistruecolor
imagejpeg
imagelayereffect
imageline
imageloadfont
imagepalettecopy
imagepng
imagepolygon
imagepsbbox
imagepsencodefont
imagepsextendfont
imagepsfreefont
imagepsloadfont
imagepsslantfont
imagepstext
imagerectangle
imagerotate
imagesavealpha
imagesetbrush
imagesetpixel
imagesetstyle
imagesetthickness
imagesettile
imagestring
imagestringup
imagesx
imagesy
imagetruecolortopalette
imagettfbbox
imagettftext
imagetypes
imagewbmp
imagexbm
iptcembed
iptcparse
jpeg2wbmp
png2wbmp
eXTReMe Tracker