Search code examples
phppngtransparencyphp-gd

Why solution to fix png transparency issue of GD does not work?


I have this code (simplified) on render png:

$this->image = imagecreatefrompng($this->file);
header("Content-Type: {$this->imageInfo['mime']}");
imagepng($this->image);

After I got black background, I was looked for some solutions, which didn't work. Easier one:

$this->image = imagecreatefrompng($this->file);
imagealphablending($targetImage, false);
imagesavealpha($targetImage, true);
header("Content-Type: {$this->imageInfo['mime']}");
imagepng($this->image);exit();

People claims that it works, but I still have black background, so I tried other one:

$this->image = imagecreatefrompng($this->file);
$targetImage = imagecreatetruecolor($this->imageInfo[0], $this->imageInfo[1]);
imagealphablending($targetImage, false);
$color = imagecolorallocatealpha($targetImage, 0, 0, 0, 127);
imagefill($targetImage, 0, 0, $color);
imagecolortransparent($targetImage, $color);
imagesavealpha($targetImage, true);
imagecopyresampled($targetImage, $this->image, 0, 0, 0, 0, $this->imageInfo[0], $this->imageInfo[1], $this->imageInfo[0], $this->imageInfo[1]);
header("Content-Type: {$this->imageInfo['mime']}");
imagepng($this->image);exit();

Result is the the same in all modern browsers. How it is possible, any idea? Code is part of class which work with all types of images and all functions works correctly.


Solution

  • Seems like you want to send the png file as is, so why convert it using GD first? I would just use readfile() and output the file:

    header("Content-Type: {$this->imageInfo['mime']}");
    readfile($this->file);
    exit();
    

    For your other tests:

    You want to output $targetImage instead of $this->image at the end, otherwise nothing fancy will happen. Also I think you need to enable alpha blending before imagecopyresampled instead of disabling it, to avoid black borders.

    $this->image = imagecreatefrompng($this->file);
    $targetImage = imagecreatetruecolor($this->imageInfo[0], $this->imageInfo[1]);
    
    $color = imagecolorallocatealpha($targetImage, 0, 0, 0, 127);
    imagefill($targetImage, 0, 0, $color);
    imagecolortransparent($targetImage, $color);
    imagealphablending($targetImage, true);
    imagecopyresampled($targetImage, $this->image, 0, 0, 0, 0, $this->imageInfo[0], $this->imageInfo[1], $this->imageInfo[0], $this->imageInfo[1]);
    header("Content-Type: {$this->imageInfo['mime']}");
    imagepng($targetImage);
    exit();