PHP-GD: Resize Transparent Image PNG & GIF

Published by Miaz Akemapa

Book minded!!!

Reader Comments

  1. I’ve been trying to use to maintain transparency with GIFs and PNGs. It does not seem to work for either GIF or PNG however, sorry to say.

  2. I’ve been trying to use this code to maintain transparency with GIFs and PNGs.

    It does not seem to work for either GIF or PNG however, I am sorry to report.

  3. Pingback: Anonymous
  4. I tried this with no luck as well. I could not use imagecopyresampled, and had to use the following instead:
    imagecolortransparent($newImg, $transparent);
    imagecopyresized($newImg, $im, 0, 0, 0, 0, $nWidth, $nHeight, $imgInfo[0], $imgInfo[1]);

    This works for the transparency, but the image quality is poor (resize is worse than resample). Any ideas why I can’t use resample?

    1. Thanks! that fixed it.

      while trying to find the problem i noticed the actual image was transparent, the php created image was transparent then i resized imagecopyresampled() to be smaller than my full image and it is that function that is losing the transparency of the copied image:

      [php]
      $bgImageURL = ‘blue-bg.gif’;
      $bgImage = imagecreatetruecolor(156,40);
      imagealphablending($bgImage, false);//needed
      //imagesavealpha($bgImage,true); //not needed
      $transparent = imagecolorallocatealpha($bgImage, 255, 255, 255,127);//needed
      //imagecolortransparent($bgImage,$transparent); //not needed
      imagefilledrectangle($bgImage, 0, 0, 156, 40, $transparent);//needed
      $srcimage = @imagecreatefromgif($bgImageURL);
      imagecopyresized($bgImage, $srcimage, 0, 0, 0, 0, 146, 30, 1000, 250);
      //imagecopyresampled($bgImage,$srcimage,0,0,0,0, 146,30,1000,250);//loses transparency
      header(‘content-type: image/gif’);
      imagegif($bgImage);
      [/php]

      likely sounds like a bug in later versions
      i am running PHP Version 5.2.6 & GD Version: bundled (2.0.34 compatible)

  5. Thank you Miaz,

    I am creating an image resize feature for WordPress and I had ssiues with PNG’s always having a balck background when resized.

    I use a part of you code and resized PNG images now appear as they should. I have not yet tested it for GIF’s but I’m sure your code will work as it works for PNG’s.

    You can take a look a look at a WordPress post that has a transparent PNG here:
    http://www.karavadra.net/wordpress/contact-form-for-wordpress
    and if you finf this post in the arhcives or search results then you will see a resized transparent version.

    Thank you again.

  6. Hello, nice script thanks for sharing, just a small error in the usage script

    $image = “some/dir/image.png”; // File image location
    should be
    $img = “some/dir/image.png”; // File image location

    i need it to keep the same ratio as the original image, i’ll try to modify it later, but any suggestion is welcome ^_^

  7. Excelent!! I found some errors in the script (resizeimage.php is imageresize.php)

    The only code working on the network!

    Excelente!! Encontre un par de errores en el script (resizeimage.php se llama imageresize.php)

    El unico codigo que funciona en la red!!

    Saludos!!!

  8. I don’t know if all problems are solved, but here are my changes based on the initial script, to make everything (PNG, GIF) work well:

    $new_image = imagecreatetruecolor($width, $height);

    // Preserve transparency
    $transparent_index = imagecolortransparent($this->image);
    if ($transparent_index >= 0) { // GIF
    imagepalettecopy($this->image, $new_image);
    imagefill($new_image, 0, 0, $transparent_index);
    imagecolortransparent($new_image, $transparent_index);
    imagetruecolortopalette($new_image, true, 256);
    }
    else // PNG
    {
    imagealphablending($new_image, false);
    imagesavealpha($new_image,true);
    $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
    imagefilledrectangle($new_image, 0, 0, $width,$height, $transparent);
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());

  9. Oh man! I’ve been trying to find a fix for this for months and months for our WordPress blog.
    The fix offered at the top didn’t do it, Benjamin’s fix did the trick. I think the problem is that GIF and PNG8 have different pallette numbers for the transparent, which wasn’t being considered by earlier fixes?
    Sooo pleased to see this problem dealt with once and for all.

  10. Can someone PLEASE take a look at my code and see what is wrong with it? Working on it for 2 days an no progress… PNG ends up with a black background no matter what I do.

    image_type = $image_info[2];
    if( $this->image_type == IMAGETYPE_JPEG ) {

    $this->image = imagecreatefromjpeg($filename);
    } elseif( $this->image_type == IMAGETYPE_GIF ) {

    $this->image = imagecreatefromgif($filename);
    } elseif( $this->image_type == IMAGETYPE_PNG ) {
    $this->image = imagecreatefrompng($filename);
    }
    }
    function save($filename, $image_type=IMAGETYPE_JPEG, $compression=100, $permissions=null) { // compression originally 75

    if( $image_type == IMAGETYPE_JPEG ) {
    imagejpeg($this->image,$filename,$compression);
    } elseif( $image_type == IMAGETYPE_GIF ) {

    imagegif($this->image,$filename);
    } elseif( $image_type == IMAGETYPE_PNG ) {
    imagepng($this->image,$filename);
    }
    if( $permissions != null) {

    chmod($filename,$permissions);
    }
    }
    function output($image_type=IMAGETYPE_JPEG) {

    if( $image_type == IMAGETYPE_JPEG ) {
    imagejpeg($this->image);
    } elseif( $image_type == IMAGETYPE_GIF ) {

    imagegif($this->image);
    } elseif( $image_type == IMAGETYPE_PNG ) {

    imagepng($this->image);
    }
    }
    function getWidth() {

    return imagesx($this->image);
    }
    function getHeight() {

    return imagesy($this->image);
    }
    function resizeToHeight($height) {

    $ratio = $height / $this->getHeight();
    $width = $this->getWidth() * $ratio;
    $this->resize($width,$height);
    }

    function resizeToWidth($width) {
    $ratio = $width / $this->getWidth();
    $height = $this->getheight() * $ratio;
    $this->resize($width,$height);
    }

    function scale($scale) {
    $width = $this->getWidth() * $scale/100;
    $height = $this->getheight() * $scale/100;
    $this->resize($width,$height);
    }

    function resize($width,$height) {
    $new_image = imagecreatetruecolor($width, $height);

    // Preserve transparency
    $transparent_index = imagecolortransparent($this->image);
    if ($transparent_index >= 0) { // GIF
    imagepalettecopy($this->image, $new_image);
    imagefill($new_image, 0, 0, $transparent_index);
    imagecolortransparent($new_image, $transparent_index);
    imagetruecolortopalette($new_image, true, 256);
    }
    else // PNG
    {
    imagealphablending($new_image, false);
    imagesavealpha($new_image,true);
    $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
    imagefilledrectangle($new_image, 0, 0, $width,$height, $transparent);
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());

    $this->image = $new_image;
    }

    /* added by kwh */

    function rotate($degrees) {
    $new_image = imagerotate($this->image, $degrees, 0);
    $this->image = $new_image;
    }

    function imageCreateTransparent($x, $y) {
    $imageOut = imagecreate($x, $y);
    $colourBlack = imagecolorallocate($imageOut, 0, 0, 0);
    imagecolortransparent($imageOut, $colourBlack);
    return $imageOut;
    }

    }
    ?>

  11. This is complete code, that working with PNG, GIF, JPG images. sorry for my bad english XD.

    function imageResize($way, $max_new_width, $max_new_height, $save = null){

    $imgInfo = getimagesize($way);

    switch($imgInfo[2])
    {
    case(1):
    $main = imagecreatefromgif($way);
    break;

    case(2):
    $main = imagecreatefromjpeg($way);
    break;

    case(3):
    $main = imagecreatefrompng($way);
    break;

    default:
    trigger_error(‘NEPODPOROVANY FORMAT OBRAZKU’, E_USER_WARNING);
    exit();
    break;
    }

    list($width, $height) = $imgInfo;

    /*resizing image*/
    $originalWidth = $width;
    $originalHeight = $height;
    $ratio = $width / $height;
    $height = $max_new_height;
    $width = $height * $ratio;

    if($width > 150)
    {
    $ratio = $height / $width;
    $width = $max_new_width;
    $height = $width * $ratio;
    }

    $newImg = imagecreatetruecolor($width, $height);

    /*saved alpha in image (in bachkgound image)*/
    if(($imgInfo[2] == 3))
    {
    imagealphablending($newImg, false);
    imagesavealpha($newImg, true);
    }
    elseif(($imgInfo[2] == 1))
    {
    /*find color, that is reserved for alpha. set this color as transparent for truecolor background ($newImg), and fill this image with transparent color.*/

    $transparent = imageColorTransparent($main);

    if($transparent != -1)
    {
    $transparent_color = imageColorsForIndex($main, $transparent);

    $transparent_new = imageColorAllocate($newImg, $transparent_color[‘red’], $transparent_color[‘green’], $transparent_color[‘blue’]);
    $transparent_new_index = imageColorTransparent($newImg, $transparent_new);
    imageFill($newImg, 0, 0, $transparent_new_index); /*<– don't forget*/
    }

    imageCopyResized($newImg, $main, 0, 0, 0, 0, $width, $height, $originalWidth, $originalHeight); /*<– if you merge images with function imageCopyResampled(), It will not work*/
    }

    if($imgInfo[2] != 1)
    imagecopyresampled($newImg, $main, 0, 0, 0, 0, $width, $height, $originalWidth, $originalHeight);

    /*output*/
    if(empty($save))
    header('Content-type: ' . $imgInfo['mime']);
    switch($imgInfo[2])
    {
    case(1): imagegif($newImg, $save); break;
    case(2): imagejpeg($newImg, $save, 100); break;
    case(3): imagepng($newImg, $save, 9); break;

    default:
    trigger_error('Resizovani obraku se posralo, proc, to fakt nevim', E_USER_WARNING);
    break;
    }

    imagedestroy($main);
    imagedestroy($newImg);

  12. very nice article, i have spent more than a day to find this solution. this code really works me.. thanks a lot.

  13. imagealphablending($newImg, false) broke it for me.

    So you may leave it out or set it to true to use “imagecopyresampled”

    Now you won’t have any black or white or color background within you copied gif or png images anymore.

Leave a Reply to Oliver Cancel reply

Your email address will not be published. Required fields are marked *