Change the opacity of an image in PHP

2019-02-17 17:50发布

问题:

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!

回答1:

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.



回答2:

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 );


回答3:

Have you tried setting alpha blending to true?

imagealphablending($newImage,true);