Rotating transparent PNG's and GIF's

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

Rotating transparent PNG's and GIF's

Post by Mr Tech »

I've put together some code for rotating images. I want it to maintain the transparency of PNG and GIF files...

I used some code from an image resizing script that maintains transparency hoping I would figure it out...

Everything works except transparent PNG's and GIF's... PNG's end up with a black background and GIF's end up with a white background.

Here is my code:

Code: Select all

// Rotate image
function rotate_image($file, $file_save, $rotate_degrees, $rotate_direction = 'right', $output = 'file', $delete_original = true, $use_linux_commands = false) {
    if ($rotate_degrees < 0) {
        return false;
    }   
 
    $image = '';
    $info = getimagesize($file);
    list($width, $height) = $info;   
   
    if ($rotate_direction == 'left')
        $rotate = $rotate_degrees;
    else
        $rotate = '-' . $rotate_degrees;
 
    switch ($info[2]) {
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif($file);
            break;
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($file);
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng($file);
            break;
        default:
            return false;
    }
   
    $image_rotated = imagecreatetruecolor($width, $height);
   
    if (($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG)) {
        $trnprt_indx = imagecolortransparent($image);
   
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
       
            // Get the original image's transparent color's RGB values
            $trnprt_color    = imagecolorsforindex($image, $trnprt_indx);
           
            // Allocate the same color in the new image resource
            $trnprt_indx    = imagecolorallocate($image_rotated, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
           
            // Completely fill the background of the new image with allocated color.
            imagefill($image_rotated, 0, 0, $trnprt_indx);
           
            // Set the background color for new image to transparent
            imagecolortransparent($image_rotated, $trnprt_indx);
       
        // Always make a transparent background color for PNGs that don't have one allocated already
        } else if ($info[2] == IMAGETYPE_PNG) {
       
            // Turn off transparency blending (temporarily)
            imagealphablending($image_rotated, false);
           
            // Create a new transparent color for image
            $color = imagecolorallocatealpha($image_rotated, 0, 0, 0, 127);
           
            // Completely fill the background of the new image with allocated color.
            imagefill($image_rotated, 0, 0, $color);
           
            // Restore transparency blending
            imagesavealpha($image_rotated, true);
           
        }
    }   
   
    imagecopyresampled($image_rotated, $image, 0, 0, 0, 0, $width, $height, $width, $height);   
   
    $bgcolor = '0xFFFFFF';
    if (isset($trnprt_indx))
        $bgcolor = $trnprt_indx;
    $image_rotated_out = imagerotate($image_rotated, $rotate, $bgcolor, 0);
   
    if ($delete_original)
        if ($use_linux_commands)
            exec('rm '.$file);
        else
            @unlink($file);
 
    switch (strtolower($output)) {
        case 'browser':
            $mime = image_type_to_mime_type($info[2]);
            header("Content-type: $mime");
            $output = NULL;
            break;
        case 'file':
            $output = $file_save;
            break;
        default:
            break;
    }   
 
    switch ($info[2]) {
        case IMAGETYPE_GIF:
            imagegif($image_rotated_out, $output);
            break;
        case IMAGETYPE_JPEG:
            imagejpeg($image_rotated_out, $output);
            break;
        case IMAGETYPE_PNG:
            imagepng($image_rotated_out, $output);
            break;
        default:
            return false;
    }   
    return true;
}
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: Rotating transparent PNG's and GIF's

Post by McInfo »

A hint for the PNG images: imagesavealpha() applies to the image being saved/displayed ($image_rotated_out), not the source image.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Wed Jun 16, 2010 2:05 pm, edited 1 time in total.
User avatar
Mr Tech
Forum Contributor
Posts: 424
Joined: Tue Aug 10, 2004 3:08 am

Re: Rotating transparent PNG's and GIF's

Post by Mr Tech »

Awesome that helped a lot! Well, i've got the PNG's to work and almost getting the GIFs to work too... the gifs are about 98% transparent however there is a black border around the outside of the original image and also around the image itself.

I've attached a screenshot...

Here is an update of my code... It's a little messy but it works...

Code: Select all

// Rotate image
function rotate_image($file, $file_save, $rotate_degrees, $rotate_direction = 'right', $output = 'file', $delete_original = true, $use_linux_commands = false) {
    if ($rotate_degrees < 0)
        return false;
    if ($rotate_direction == 'left')
        $rotate = $rotate_degrees;
    else
        $rotate = '-' . $rotate_degrees;
    $info = getimagesize($file);
    $image = '';
    switch ($info[2]) {
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif($file);
            break;
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($file);
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng($file);
            break;
        default:
            return false;
    }
    
    // set background transparent if GIF or PNG
    $bgcolor = '0xFFFFFF';
    if (($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG)) {
        $trnprt_indx = imagecolortransparent($image);
        
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
        
            // Get the original image's transparent color's RGB values
            $trnprt_color    = imagecolorsforindex($image, $trnprt_indx);
            
            // Allocate the same color in the new image resource
            $trnprt_indx    = imagecolorallocate($image, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            
        }
        
        $bgcolor = $trnprt_indx;
    }
    
    // rotate image
    $image = imagerotate($image, $rotate, $bgcolor, 0);
    
    // get dimensions
    $width = imagesx($image);
    $height = imagesy($image);
    
    // output image
    $image_rotated = imagecreatetruecolor($width, $height); 
    if (($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG)) {
        //$trnprt_indx = imagecolortransparent($image);
    
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
        
            // Get the original image's transparent color's RGB values
            $trnprt_color    = imagecolorsforindex($image, $trnprt_indx);
            
            // Allocate the same color in the new image resource
            $trnprt_indx    = imagecolorallocate($image_rotated, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            
            // Completely fill the background of the new image with allocated color.
            imagefill($image_rotated, 0, 0, $trnprt_indx);
            
            // Set the background color for new image to transparent
            imagecolortransparent($image_rotated, $trnprt_indx);
        
        // Always make a transparent background color for PNGs that don't have one allocated already
        } else if ($info[2] == IMAGETYPE_PNG) {
        
            // Turn off transparency blending (temporarily)
            imagealphablending($image_rotated, false);
            
            // Create a new transparent color for image
            $color = imagecolorallocatealpha($image_rotated, 0, 0, 0, 127);
            
            // Completely fill the background of the new image with allocated color.
            imagefill($image_rotated, 0, 0, $color);
            
            // Restore transparency blending
            imagesavealpha($image_rotated, true);
            
        }
    }   
    imagecopyresampled($image_rotated, $image, 0, 0, 0, 0, $width, $height, $width, $height);   
        
    if ($delete_original)
        if ($use_linux_commands)
            exec('rm '.$file);
        else
            @unlink($file);
 
    switch (strtolower($output)) {
        case 'browser':
            $mime = image_type_to_mime_type($info[2]);
            header("Content-type: $mime");
            $output = NULL;
            break;
        case 'file':
            $output = $file_save;
            break;
        default:
            break;
    }   
 
    switch ($info[2]) {
        case IMAGETYPE_GIF:
            imagegif($image_rotated, $output);
            break;
        case IMAGETYPE_JPEG:
            imagejpeg($image_rotated, $output);
            break;
        case IMAGETYPE_PNG:
            imagepng($image_rotated, $output);
            break;
        default:
            return false;
    }   
    return true;
}
Picture 1.png
Picture 1.png (31.97 KiB) Viewed 1428 times
Post Reply