How do I resize pngs with transparency in PHP?

Viewed 64847

I'm attempting to resize pngs with transparent backgrounds in PHP and the code samples I've found online don't work for me. Here's the code I'm using, advice will be much appreciated!

$this->image = imagecreatefrompng($filename);

imagesavealpha($this->image, true);
$newImage = imagecreatetruecolor($width, $height);

// Make a new transparent image and turn off alpha blending to keep the alpha channel
$background = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
imagecolortransparent($newImage, $background);
imagealphablending($newImage, false);
imagesavealpha($newImage, true);

imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height,  $this->getWidth(), $this->getHeight());
$this->image = $newImage;  
imagepng($this->image,$filename);


Update By 'not working' I meant to say the background color changes to black when I resize pngs.

11 Answers

From what I can tell, you need to set the blending mode to false, and the save alpha channel flag to true before you do the imagecolorallocatealpha()

<?php
/**
 * https://stackoverflow.com/a/279310/470749
 * 
 * @param resource $image
 * @param int $newWidth
 * @param int $newHeight
 * @return resource
 */
public function getImageResized($image, int $newWidth, int $newHeight) {
    $newImg = imagecreatetruecolor($newWidth, $newHeight);
    imagealphablending($newImg, false);
    imagesavealpha($newImg, true);
    $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
    imagefilledrectangle($newImg, 0, 0, $newWidth, $newHeight, $transparent);
    $src_w = imagesx($image);
    $src_h = imagesy($image);
    imagecopyresampled($newImg, $image, 0, 0, 0, 0, $newWidth, $newHeight, $src_w, $src_h);
    return $newImg;
}
?>

UPDATE : This code is working only on background transparent with opacity = 0. If your image have 0 < opacity < 100 it'll be black background.

using imagescale is better compared to imagecopyresampled. No empty image resource required for the resized image, requires only two arguments compared to the ten required by imagecopyresampled. Also produces better quality with smaller sizes. If using PHP 5.5.18 or earlier, or PHP 5.6.2 or earlier, you should provide the height which is the 3rd argument as the aspect ratio calculation was incorrect.

$this->image =   imagecreatefrompng($filename);
$scaled = imagescale($this->image, $width);
imagealphablending($scaled, false);
imagesavealpha($scaled, true);
imagepng($scaled, $filename);

The filling of the new image with a transparent colour is also required (as Dycey coded but I'm guessing forgot to mention :)), not just the 'strategic' saving by itself.

IIRC, you also need to be sure PNGs are 24bit, ie truecolor, and not 8bit to avoid buggy behaviour.

You can simply resize the image with imagescale()
This code works fine for me:

$image = imagescale($image, 720, -1, IMG_BICUBIC);
imagepng($image);
Related