Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the opacity of an image in PHP

I am trying to change the opacity of an image using GD, Almost all the solutions that I found are similar to the code below, where you create a white transparent background and merge it with your image.

But this doesn't make the image transparent, the image just gets brighter, you can't actually look through it.

So my question is, how to change the opacity of an image so that you can look through it? Or am i doing something wrong with this code?

//Create an image with a white transparent background color
$newImage = ImageCreateTruecolor(300, 300);
$bg        = ImageColorAllocateAlpha($newImage, 255, 255, 255, 127);
ImageFill($newImage, 0, 0, $bg);

//Get the image
$source = imagecreatefrompng('my_image.png');

$opacity = 50;    

//Merge the image with the background
ImageCopyMerge($newImage,
               $source,
               0, 0, 0, 0,
               300,
               300,
               $opacity);

header('Content-Type: image/png');
imagepng($newImage);
imagedestroy($newImage);

Thank you!

like image 993
RobertHegeraad Avatar asked Jan 22 '13 21:01

RobertHegeraad


2 Answers

You just need to use imagefilter with IMG_FILTER_COLORIZE

$image = imagecreatefrompng('my_image.png');
$opacity = 0.5;
imagealphablending($image, false); // imagesavealpha can only be used by doing this for some reason
imagesavealpha($image, true); // this one helps you keep the alpha. 
$transparency = 1 - $opacity;
imagefilter($image, IMG_FILTER_COLORIZE, 0,0,0,127*$transparency); // the fourth parameter is alpha
header('Content-type: image/png');
imagepng($image);

imagealphablending, I think, is for drawing purposes so you don't want to use it. I may be wrong. We should both look it up :)

If you want to use percentage, you can calculate $opacity accordingly.

like image 115
toraman Avatar answered Nov 11 '22 03:11

toraman


There is no direct way to change opacity using DG function (actually there is). But it can be done using pixel-by-pixel manipulation:

/**
 * @param resource $imageSrc Image resource. Not being modified.
 * @param float $opacity Opacity to set from 0 (fully transparent) to 1 (no change)
 * @return resource Transparent image resource
 */
function imagesetopacity( $imageSrc, $opacity )
{
    $width  = imagesx( $imageSrc );
    $height = imagesy( $imageSrc );

    // Duplicate image and convert to TrueColor
    $imageDst = imagecreatetruecolor( $width, $height );
    imagealphablending( $imageDst, false );
    imagefill( $imageDst, 0, 0, imagecolortransparent( $imageDst ));
    imagecopy( $imageDst, $imageSrc, 0, 0, 0, 0, $width, $height );

    // Set new opacity to each pixel
    for ( $x = 0; $x < $width; ++$x )
        for ( $y = 0; $y < $height; ++$y ) {
            $pixelColor = imagecolorat( $imageDst, $x, $y );
            $pixelOpacity = 127 - (( $pixelColor >> 24 ) & 0xFF );
            if ( $pixelOpacity > 0 ) {
                $pixelOpacity = $pixelOpacity * $opacity;
                $pixelColor = ( $pixelColor & 0xFFFFFF ) | ( (int)round( 127 - $pixelOpacity ) << 24 );
                imagesetpixel( $imageDst, $x, $y, $pixelColor );
            }
        }

    return $imageDst;
}

$source = imagecreatefrompng( 'my_image.png' );
$newImage = imagesetopacity( $source, 0.5 );
imagedestroy( $source );

header( 'Content-Type: image/png' );
imagepng( $newImage );
imagedestroy( $newImage );
like image 6
Finesse Avatar answered Nov 11 '22 04:11

Finesse