PHP
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

imagesavealpha> <imagerectangle
Last updated: Fri, 03 Jul 2009

view this page in

imagerotate

(PHP 4 >= 4.3.0, PHP 5)

imagerotateRotate an image with a given angle

Description

resource imagerotate ( resource $image , float $angle , int $bgd_color [, int $ignore_transparent= 0 ] )

Rotates the image image using the given angle in degrees.

The center of rotation is the center of the image, and the rotated image may have different dimensions than the original image.

Parameters

image

An image resource, returned by one of the image creation functions, such as imagecreatetruecolor().

angle

Rotation angle, in degrees.

bgd_color

Specifies the color of the uncovered zone after the rotation

ignore_transparent

If set and non-zero, transparent colors are ignored (otherwise kept).

Return Values

Changelog

Version Description
5.1.0 ignore_transparent was added.

Examples

Example #1 Rotate an image 180 degrees

This example rotates an image 180 degrees - upside down.

<?php
// File and rotation
$filename 'test.jpg';
$degrees 180;

// Content type
header('Content-type: image/jpeg');

// Load
$source imagecreatefromjpeg($filename);

// Rotate
$rotate imagerotate($source$degrees0);

// Output
imagejpeg($rotate);
?>

The above example will output something similar to:

Notes

Note: This function is only available if PHP is compiled with the bundled version of the GD library.



imagesavealpha> <imagerectangle
Last updated: Fri, 03 Jul 2009
 
add a note add a note User Contributed Notes
imagerotate
Anonymous
26-Jun-2009 12:32
Sorry, the previous class contains an error, the original image after the rotation 1px move on and get the unwanted "border".

After a careful reading of the local debate, I am using the tip from Dave Richards wrote a new function. With its images can be rotated only 90 ° (default), 180 ° and 270 °, but one rarely needs more ...

The function returns False, or rotated image
<?php
if(!function_exists("imagerotate")) {
    function
imagerotate($srcImg, $angle, $bgcolor, $ignore_transparent = 0) {
        return
rotateImage($srcImg, $angle);
    }
}

function
rotateImage($img1, $rec) {
   
$wid = imagesx($img1);
   
$hei = imagesy($img1);
    switch(
$rec) {
        case
270:
           
$img2 = @imagecreatetruecolor($hei, $wid);
        break;
        case
180:
           
$img2 = @imagecreatetruecolor($wid, $hei);
        break;
        default :
           
$img2 = @imagecreatetruecolor($hei, $wid);
    }
    if(
$img2) {
        for(
$i = 0;$i < $wid; $i++) {
            for(
$j = 0;$j < $hei; $j++) {
               
$ref = imagecolorat($img1,$i,$j);
                switch(
$rec) {
                    case
270:
                        if(!@
imagesetpixel($img2, ($hei - 1) - $j, $i, $ref)){
                            return
false;
                        }
                    break;
                    case
180:
                        if(!@
imagesetpixel($img2, $i, ($hei - 1) - $j, $ref)) {
                            return
false;
                        }
                    break;
                    default:
                        if(!@
imagesetpixel($img2, $j, ($wid - 1) - $i, $ref)) {
                            return
false;
                        }
                }
            }
        }
        return
$img2;
    }
    return
false;
}
?>

Petr
Mike Knoop
24-Jun-2009 09:25
Don't be tricked into thinking this function will rotate the image resource handle in-place. While the documentation currently doesn't specify and return values, I've found the following return values to be true:

"Returns an image resource identifier on success, FALSE on errors. "

Simply make sure you're doing something like...
<?php
$rotated_img
= imagerotate($src_img, 45, $color)
?>

-Mike
krteczek01 at gmail dot com
23-Jun-2009 10:21
Hi, I've rewrote function to class with static methods. Advantage of this solution is ability to be called several times during script execution.

<?php
/*
    Unfinished imagerotate replacement. ignore_transparent is, well, ignored. :)
    Also, should have some standard functions for 90, 180 and 270 degrees, since they are quite
    easy to implement faster.
*/

if(!function_exists("imagerotate")) {
    function
imagerotate(&$srcImg, $angle, $bgcolor, $ignore_transparent = 0) {
        return
imagerotateEquivalent::rotate(&$srcImg, $angle, $bgcolor, $ignore_transparent);
    }
}

class
imagerotateEquivalent {

    static private function
rotateX($x, $y, $theta){
        return
$x * cos($theta) - $y * sin($theta);
    }

    static private function
rotateY($x, $y, $theta){
        return
$x * sin($theta) + $y * cos($theta);
    }

    public static function
rotate(&$srcImg, $angle, $bgcolor, $ignore_transparent = 0) {
       
       
$srcw = imagesx($srcImg);
       
$srch = imagesy($srcImg);

        if(
$angle == 0) return $srcImg;

       
// Convert the angle to radians
       
$theta = deg2rad ($angle);

       
// Calculate the width of the destination image.
       
$temp = array (    self::rotateX(0,     0, 0-$theta),
                       
self::rotateX($srcw, 0, 0-$theta),
                       
self::rotateX(0,     $srch, 0-$theta),
                       
self::rotateX($srcw, $srch, 0-$theta)
                    );
       
$minX = floor(min($temp));
       
$maxX = ceil(max($temp));
       
$width = $maxX - $minX;

       
// Calculate the height of the destination image.
       
$temp = array (    self::rotateY(0,     0, 0-$theta),
                       
self::rotateY($srcw, 0, 0-$theta),
                       
self::rotateY(0,     $srch, 0-$theta),
                       
self::rotateY($srcw, $srch, 0-$theta)
                    );
       
$minY = floor(min($temp));
       
$maxY = ceil(max($temp));
       
$height = $maxY - $minY;

       
$destimg = imagecreatetruecolor($width, $height);
       
imagefill($destimg, 0, 0, imagecolorallocate($destimg, 0,255, 0));

       
// sets all pixels in the new image
       
for($x=$minX;$x<$maxX;$x++) {
            for(
$y=$minY;$y<$maxY;$y++)
            {
               
// fetch corresponding pixel from the source image
               
$srcX = round(self::rotateX($x, $y, $theta));
               
$srcY = round(self::rotateY($x, $y, $theta));
                if(
$srcX >= 0 && $srcX < $srcw && $srcY >= 0 && $srcY < $srch)
                {
                   
$color = imagecolorat($srcImg, $srcX, $srcY );
                }
                else
                {
                   
$color = $bgcolor;
                }
               
imagesetpixel($destimg, $x-$minX, $y-$minY, $color);
            }
        }
        return
$destimg;
    }
}

?>
anon at here dot com
13-Jun-2009 08:00
I was quite surprised to see that no one had done any working rotate function. And since I needed one for my web hotel, I whipped this one up. Someone might want to expand it so that it matches imagerotate.

Also, does imagerotate really rotate things counter clockwise? Otherwise this should also be changed.

<?php
if(!function_exists("imagerotate")) {
    function
imagerotate(&$srcImg, $angle, $bgcolor, $ignore_transparent = 0) {
        return
imagerotateEquivalent(&$srcImg, $angle, $bgcolor, $ignore_transparent);
    }
}

/*
    Unfinished imagerotate replacement. ignore_transparent is, well, ignored. :)
    Also, should have some standard functions for 90, 180 and 270 degrees, since they are quite
    easy to implement faster.
*/
function imagerotateEquivalent(&$srcImg, $angle, $bgcolor, $ignore_transparent = 0)
{
    function
rotateX($x, $y, $theta){
        return
$x * cos($theta) - $y * sin($theta);
    }
    function
rotateY($x, $y, $theta){
        return
$x * sin($theta) + $y * cos($theta);
    }
   
   
$srcw = imagesx($srcImg);
   
$srch = imagesy($srcImg);
 
    if(
$angle == 0) return $srcImg;
   
   
// Convert the angle to radians
   
$theta = deg2rad ($angle);

   
   
// Calculate the width of the destination image.
   
$temp = array (    rotateX(0,     0, 0-$theta),
                   
rotateX($srcw, 0, 0-$theta),
                   
rotateX(0,     $srch, 0-$theta),
                   
rotateX($srcw, $srch, 0-$theta)
                );
   
$minX = floor(min($temp));
   
$maxX = ceil(max($temp));
   
$width = $maxX - $minX;
   
   
// Calculate the height of the destination image.
   
$temp = array (    rotateY(0,     0, 0-$theta),
                   
rotateY($srcw, 0, 0-$theta),
                   
rotateY(0,     $srch, 0-$theta),
                   
rotateY($srcw, $srch, 0-$theta)
                );
   
$minY = floor(min($temp));
   
$maxY = ceil(max($temp));
   
$height = $maxY - $minY;
   
   
$destimg = imagecreatetruecolor($width, $height);
   
imagefill($destimg, 0, 0, imagecolorallocate($destimg, 0,255, 0));

   
// sets all pixels in the new image
   
for($x=$minX;$x<$maxX;$x++) {
        for(
$y=$minY;$y<$maxY;$y++)
        {
           
// fetch corresponding pixel from the source image
           
$srcX = round(rotateX($x, $y, $theta));
           
$srcY = round(rotateY($x, $y, $theta));
            if(
$srcX >= 0 && $srcX < $srcw && $srcY >= 0 && $srcY < $srch)
            {
               
$color = imagecolorat($srcImg, $srcX, $srcY );
            }
            else
            {
               
$color = $bgcolor;
            }
           
imagesetpixel($destimg, $x-$minX, $y-$minY, $color);
        }
    }
   
    return
$destimg;
}
?>
dave dot richards at gmail dot com
17-Apr-2009 11:47
There is a slight mistake in the previous post by Kae Cyphet.

When setting the pixels of the new image the co-ordinates have to occasionally use the width ($wid) and height ($hei). These values must be reduced by 1 as the co-ordinates start at 0 (Not 1) so they only go up to $wid - 1 and $hei - 1 (Not $wid and $hei).

Here's an example of the first function to show this:

<?php
function rotate_right90($im)
{
 
$wid = imagesx($im);
 
$hei = imagesy($im);
 
$im2 = imagecreatetruecolor($hei,$wid);

 for(
$i = 0;$i < $wid; $i++)
 {
  for(
$j = 0;$j < $hei; $j++)
  {
  
$ref = imagecolorat($im,$i,$j);
  
imagesetpixel($im2,($hei - 1) - $j,$i,$ref);
  }
 }
 return
$im2;
}
?>

Other than that very useful functions!
Kae Cyphet
23-Jan-2009 09:50
To solve that annoying problem of having to install a pre-compiled version of GD just to get imagerotate working.

here is an open source solution.
uses the standard stuff included in php when you uncomment 'extension=php_gd2.dll' in the php.ini file and there ya go!

Useage:
<?php
$im
= imagecreatefromjpeg('test.jpg');

header('Content-type: image/jpg');
imagejpeg(rotate_right90($im));

imagedestroy($im);
?>

'=================================

<?php
function rotate_right90($im)
{
 
$wid = imagesx($im);
 
$hei = imagesy($im);
 
$im2 = imagecreatetruecolor($hei,$wid);

 for(
$i = 0;$i < $wid; $i++)
 {
  for(
$j = 0;$j < $hei; $j++)
  {
  
$ref = imagecolorat($im,$i,$j);
  
imagesetpixel($im2,$hei - $j,$i,$ref);
  }
 }
 return
$im2;
}

function
rotate_left90($im)
{
 
$wid = imagesx($im);
 
$hei = imagesy($im);
 
$im2 = imagecreatetruecolor($hei,$wid);

 for(
$i = 0;$i < $wid; $i++)
 {
  for(
$j = 0;$j < $hei; $j++)
  {
  
$ref = imagecolorat($im,$i,$j);
  
imagesetpixel($im2,$j, $wid - $i,$ref);
  }
 }
 return
$im2;
}

function
mirror($im)
{
 
$wid = imagesx($im);
 
$hei = imagesy($im);
 
$im2 = imagecreatetruecolor($wid,$hei);

 for(
$i = 0;$i < $wid; $i++)
 {
  for(
$j = 0;$j < $hei; $j++)
  {
  
$ref = imagecolorat($im,$i,$j);
  
imagesetpixel($im2,$wid - $i,$j,$ref);
  }
 }
 return
$im2;
}

function
flip($im)
{
 
$wid = imagesx($im);
 
$hei = imagesy($im);
 
$im2 = imagecreatetruecolor($wid,$hei);

 for(
$i = 0;$i < $wid; $i++)
 {
  for(
$j = 0;$j < $hei; $j++)
  {
  
$ref = imagecolorat($im,$i,$j);
  
imagesetpixel($im2,$i,$hei - $j,$ref);
  }
 }
 return
$im2;
}
?>
rassols[at]Gmail[dota]com
12-Jan-2009 11:24
Really working function for imagemagic replacement of imagerotate GD2. Need integrated into php imagemagic.
<?php
if ( !function_exists( 'imagerotate' ) ) {
    function
imagerotate( $source_image, $angle, $bgd_color ) {
       
$angle = 360-$angle; // GD rotates CCW, imagick rotates CW
       
$temp_src = '/tmp/temp_src.png';
       
$temp_dst = '/tmp/temp_dst.png';
        if (!
imagepng($source_image,$temp_src)){
            return
false;
        }
       
$imagick = new Imagick();
       
$imagick->readImage($temp_src);
       
$imagick->rotateImage(new ImagickPixel($bgd_color?$bgd_color:'black'), $angle);
       
$imagick->writeImage($temp_dst);
       
//trigger_error( 'imagerotate(): could not write to ' . $file1 . ', original image returned', E_USER_WARNING );
       
$result = imagecreatefrompng($temp_dst);
       
unlink($temp_dst);
       
unlink($temp_src);
        return
$result;
    }
}
?>
joseluis at pellicer dot org
02-Dec-2008 04:14
About that rotating function by david at horizon-nigh not working, I found the bug.
I noticed that the x1 and y1 where not used, so, in the loop through every pixel and transform it, change

$x2 = $x * cos($theta) - $y * sin($theta);
$y2 = $x * sin($theta) + $y * cos($theta);

to:
          
$x2 = $x1 * cos($theta) - $y1 * sin($theta);
$y2 = $x1 * sin($theta) + $y1 * cos($theta);
fernando_empresarial at ig dot com dot br
13-Nov-2008 12:52
<?php
$urlImage
= "images/image.png";
$urlNewImage = "images/imageNew.png";
   
$src_img = imagecreatefrompng($urlImage);
$originalX = imagesx($src_img);
$originalY = imagesy($src_img);
$dst_img = imagecreatetruecolor(640,480);

   
$imageRotate = imagerotate($src_img,20,-1);
       
imagepng($imageRotate,$urlNewImage);
imagedestroy($dst_img);
imagedestroy($src_img);
?>
momeunier at gmail dot com
16-Oct-2008 01:39
And if you are running Ubuntu but you wan to build your own gd library, follow these simple steps.

http://info.momeunier.fr/node/20
foi02 at cartefoi dot net
02-Oct-2008 02:50
For those who are looking for the GD library for Ubuntu, I let a copy on my server:  http://www.cartefoi.net/compl_compl_2.php
It was pretty hard to find, somebody gaveme his. Thanks a lot to him (message up).
Bert Vandeghinste
20-Sep-2008 02:17
I'm now using david's code with these changes to get a transparent effect.

I exec convert 2 times:

<?php
exec
( $imagick . ' -background \'#555555\' -rotate ' . $angle . ' ' . $file1 . ' ' . $file2 );
exec( $imagick . ' -transparent \'#555555\' -transparent-color \'#555555\' ' . $file2 . ' ' . $file3 );
?>

and then use this after I rotated $output:
<?php imagecolortransparent($output, imagecolorallocatealpha($output, 85, 85, 85, 127)); ?>
david at horizon-nigh dot org
12-Sep-2008 04:06
I couldn't get the replacements from 'the dot thawk' or 'pilot' to work for some reason, so here's my own replacement. It uses ImageMagick; binary must be installed, and you may need to modify the search path. (I didn't use PHP's ImageMagick support for my own reasons.)

<?php
   
/**
     * imagerotate()
     * Debian php5-gd packages do not include imagerotate() due to some convoluted reason.
     *
     * @param int $angle - same as PHP builtin function
     * @param $bgd_color - not implemented, apparently always #FFFFFF
     *
     * @return same as PHP builtin function
     */
   
if ( !function_exists( 'imagerotate' ) ) {

        function
imagerotate( $source_image, $angle, $bgd_color ) {

           
$angle = 360-$angle; // GD rotates CCW, imagick rotates CW

           
foreach ( array( '/usr/bin', '/usr/local/bin', '/opt/local/bin', '/sw/bin' ) as $path ) {

                if (
file_exists( $path . '/convert' ) ) {
                   
$imagick = $path . '/convert';
                    if (
$path == '/opt/local/bin' ) {
                       
$imagick = 'DYLD_LIBRARY_PATH="" ' . $imagick; // some kind of conflict with MacPorts and MAMP
                   
}
                    break;
                }

            }

            if ( !isset(
$imagick ) ) {

               
//trigger_error( 'imagerotate(): could not find imagemagick binary, original image returned', E_USER_WARNING );
               
return $source_image;

            }

           
$file1 = '/tmp/imagick_' . rand( 10000,99999 ) . '.png';
           
$file2 = '/tmp/imagick_' . rand( 10000,99999 ) . '.png';

            if ( @
imagepng( $source_image, $file1 ) ) {

               
exec( $imagick . ' -rotate ' . $angle . ' ' . $file1 . ' ' . $file2 );

                if (
file_exists( $file2 ) ) {

                   
$new_image = imagecreatefrompng( $file2 );
                   
unlink( $file1 );
                   
unlink( $file2 );
                    return
$new_image;

                } else {

                   
//trigger_error( 'imagerotate(): imagemagick conversion failed, original image returned', E_USER_WARNING );
                   
return $source_image;

                }

            } else {

               
//trigger_error( 'imagerotate(): could not write to ' . $file1 . ', original image returned', E_USER_WARNING );
               
return $source_image;

            }

        }

    }
?>
AJenbo
26-Aug-2008 08:45
I modified cbl25's function to allow it to rotate an image either clock wise or counter clock wise.

<?php
function rotateImage($image, $direction) {
   
$direction = strtolower($direction);
   
$degrees = $direction == 'cw' ? 270 : ($direction == 'ccw' ? 90 : NULL);
    if(!
$degrees)
        return
$image;
   
$width = imagesx($image);
   
$height = imagesy($image);
   
$side = $width > $height ? $width : $height;
   
$imageSquare = imagecreatetruecolor($side, $side);
   
imagecopy($imageSquare, $image, 0, 0, 0, 0, $width, $height);
   
imagedestroy($image);
   
$imageSquare = imagerotate($imageSquare, $degrees, 0, -1);
   
$image = imagecreatetruecolor($height, $width);
   
$x = $degrees == 90 ? 0 : ($height > $width ? 0 : ($side - $height));
   
$y = $degrees == 270 ? 0 : ($height < $width ? 0 : ($side - $width));
   
imagecopy($image, $imageSquare, 0, 0, $x, $y, $height, $width);
   
imagedestroy($imageSquare);
    return
$image;
}

//Usage
$image = rotateImage($image, 'cw');
$image = rotateImage($image, 'ccw');
?>
cbl25
19-Aug-2008 02:29
Here is a simple function to rotate a non-square image 90 degrees clockwise.

<?php
function rotateImage($imageResource)
{
   
$width = imagesx($imageResource);
   
$height = imagesy($imageResource);
   
$side = $width > $height ? $width : $height;
   
$squareImage = imagecreatetruecolor($side, $side);
   
imagecopy($squareImage,$imageResource,0,0,0,0,$width,$height);
   
$squareImage = imagerotate($squareImage,270,0,-1);
   
$imageResource = imagecreatetruecolor($height, $width);
   
$x = $height > $width ? 0 : $side - $height;
   
imagecopy($imageResource,$squareImage,0,0,$x,0,$height,$width);
    return
$imageResource;
}
?>
the dot thawk+phpnet at gmail dot com
16-Jul-2008 03:44
In response to pilot at myupb dot com on 31-May-2008 02:23
---

I am not sure why you would be defining your own PI, instead of using the built-in constant, and why you do the degrees to radian conversion manually. There might be a speed issue, however here is the exact same code with that small difference.

<?php
if(!function_exists("imagerotate")) {
    function
imagerotate(&$srcImg, $angle, $transparentColor = null) {
       
$srcw = imagesx($srcImg);
       
$srch = imagesy($srcImg);
      
        if(
$angle == 0) return $srcImg;
      
       
// Convert the angle to radians
       
$theta = deg2rad ($angle);
      
       
// Get the origin (center) of the image
       
$originx = $srcw / 2;
       
$originy = $srch / 2;
      
       
// The pixels array for the new image
       
$pixels = array();
       
$minx = 0;
       
$maxx = 0;
       
$miny = 0;
       
$maxy = 0;
       
$dstw = 0;
       
$dsth = 0;
      
       
// Loop through every pixel and transform it
       
for($x=0;$x<$srcw;$x++) {
            for(
$y=0;$y<$srch;$y++) {
                list(
$x1, $y1) = translateCoordinate($originx, $originy, $x, $y, false);
              
               
$x2 = $x * cos($theta) - $y * sin($theta);
               
$y2 = $x * sin($theta) + $y * cos($theta);
              
               
// Store the pixel color
               
$pixels[] = array($x2, $y2, imagecolorat($srcImg, $x, $y));
              
               
// Check our boundaries
               
if($x2 > $maxx) $maxx = $x2;
                if(
$x2 < $minx) $minx = $x2;
                if(
$y2 > $maxy) $maxy = $y2;
                if(
$y2 < $miny) $miny = $y2;
            }
        }
      
       
// Determine the new image size
       
$dstw = $maxx - $minx + 1;
       
$dsth = $maxy - $miny + 1;
      
       
// Create our new image
       
$dstImg = imagecreatetruecolor($dstw, $dsth);
      
       
// Fill the background with our transparent color
       
if($transparentColor == null) $transparentColor = imagecolorallocate($dstImg, 1, 2, 3);
       
imagecolortransparent($dstImg, $transparentColor);
       
imagefilledrectangle($dstImg, 0, 0, $dstw + 1, $dsth + 1, $transparentColor);
      
       
// Get the new origin
       
$neworiginx = -$minx;
       
$neworiginy = -$miny;
      
       
// Fill in the pixels
       
foreach($pixels as $data) {
            list(
$x, $y, $color) = $data;
            list(
$newx, $newy) = translateCoordinate($neworiginx, $neworiginy, $x, $y);
           
imagesetpixel($dstImg, $newx, $newy, $color);
        }
      
        return
$dstImg;
    }
  
   
/**
     * Translates from mathematical coordinate system to computer coordinate system using
     * origin coordinates from the computer system or visa versa
     *
     * @param int $originx
     * @param int $originy
     * @param int $x
     * @param int $y
     * @param bool $toComp
     * @return array(int $x, int $y)
     */
   
function translateCoordinate($originx, $originy, $x, $y, $toComp=true) {
        if(
$toComp) {
           
$newx = $originx + $x;
           
$newy = $originy - $y;
        } else {
           
$newx = $x - $originx;
           
$newy = $originy - $y;
        }
      
        return array(
$newx, $newy);
    }
}
?>
pilot at myupb dot com
31-May-2008 12:23
Shortly after posting I was informed about a very nice algorithm for calculating the new pixel position for a rotation and thought it would be a nice improvement. Hopes this helps anyone needing a full implementation.

Note: I tested the function on a 3Mb photo and it seemed to work perfectly with no quality loss.

<?php
if(!function_exists("imagerotate")) {
    function
imagerotate(&$srcImg, $angle, $transparentColor = null) {
       
$srcw = imagesx($srcImg);
       
$srch = imagesy($srcImg);
       
        if(
$angle == 0) return $srcImg;
       
       
// Convert the angle to radians
       
$pi = 3.141592654;
       
$theta = $angle * $pi / 180;
       
       
// Get the origin (center) of the image
       
$originx = $srcw / 2;
       
$originy = $srch / 2;
       
       
// The pixels array for the new image
       
$pixels = array();
       
$minx = 0;
       
$maxx = 0;
       
$miny = 0;
       
$maxy = 0;
       
$dstw = 0;
       
$dsth = 0;
       
       
// Loop through every pixel and transform it
       
for($x=0;$x<$srcw;$x++) {
            for(
$y=0;$y<$srch;$y++) {
                list(
$x1, $y1) = translateCoordinate($originx, $originy, $x, $y, false);
               
               
$x2 = $x * cos($theta) - $y * sin($theta);
               
$y2 = $x * sin($theta) + $y * cos($theta);
               
               
// Store the pixel color
               
$pixels[] = array($x2, $y2, imagecolorat($srcImg, $x, $y));
               
               
// Check our boundaries
               
if($x2 > $maxx) $maxx = $x2;
                if(
$x2 < $minx) $minx = $x2;
                if(
$y2 > $maxy) $maxy = $y2;
                if(
$y2 < $miny) $miny = $y2;
            }
        }
       
       
// Determine the new image size
       
$dstw = $maxx - $minx + 1;
       
$dsth = $maxy - $miny + 1;
       
       
// Create our new image
       
$dstImg = imagecreatetruecolor($dstw, $dsth);
       
       
// Fill the background with our transparent color
       
if($transparentColor == null) $transparentColor = imagecolorallocate($dstImg, 1, 2, 3);
       
imagecolortransparent($dstImg, $transparentColor);
       
imagefilledrectangle($dstImg, 0, 0, $dstw + 1, $dsth + 1, $transparentColor);
       
       
// Get the new origin
       
$neworiginx = -$minx;
       
$neworiginy = -$miny;
       
       
// Fill in the pixels
       
foreach($pixels as $data) {
            list(
$x, $y, $color) = $data;
            list(
$newx, $newy) = translateCoordinate($neworiginx, $neworiginy, $x, $y);
           
imagesetpixel($dstImg, $newx, $newy, $color);
        }
       
        return
$dstImg;
    }
   
   
/**
     * Translates from mathematical coordinate system to computer coordinate system using
     * origin coordinates from the computer system or visa versa
     *
     * @param int $originx
     * @param int $originy
     * @param int $x
     * @param int $y
     * @param bool $toComp
     * @return array(int $x, int $y)
     */
   
function translateCoordinate($originx, $originy, $x, $y, $toComp=true) {
        if(
$toComp) {
           
$newx = $originx + $x;
           
$newy = $originy - $y;
        } else {
           
$newx = $x - $originx;
           
$newy = $originy - $y;
        }
       
        return array(
$newx, $newy);
    }
}
?>
pilot at myupb dot com
30-May-2008 02:33
Thanks to the people who contributed the code for the 90 180 and 270 rotations. I needed a full implementation however so I wrote one. By no mean do I think this is the best way of doing it, I just whipped this together for myself. Seems to work good for me.

Note: I didn't want the image to be shrunk when rotating so this implementation will keep the size of the original image but just rotate it.

<?php
if(!function_exists("imagerotate")) {
    function
imagerotate(&$srcImg, $angle, $transparentColor = null) {
       
$srcw = imagesx($srcImg);
       
$srch = imagesy($srcImg);
       
        if(
$angle == 0) return $srcImg;
       
       
// Convert the angle to radians
       
$pi = 3.141592654;
       
$theta = $angle * $pi / 180;
       
       
// Get the origin (center) of the image
       
$originx = $srcw / 2;
       
$originy = $srch / 2;
       
       
// The pixels array for the new image
       
$pixels = array();
       
$minx = 0;
       
$maxx = 0;
       
$miny = 0;
       
$maxy = 0;
       
$dstw = 0;
       
$dsth = 0;
       
       
// Loop through every pixel and transform it
       
for($x=0;$x<$srcw;$x++) {
            for(
$y=0;$y<$srch;$y++) {
                list(
$x1, $y1) = translateCoordinate($originx, $originy, $x, $y, false);
               
               
$theta1 = 0;
               
$noTranslate = false;
               
               
// Determine the angle of original point
               
if($x1 > 0 && $y1 > 0) {
                   
// Quadrant 1
                   
$theta1 = atan($y1/$x1);
                } elseif(
$x1 < 0 && $y1 > 0) {
                   
// Quadrant 2
                   
$theta1 = $pi - atan($y1/abs($x1));
                } elseif(
$x1 < 0 && $y1 < 0) {
                   
// Quadrant 3
                   
$theta1 = $pi + atan($y1/$x1);
                } elseif(
$x1 > 0 && $y1 < 0) {
                   
// Quadrant 4
                   
$theta1 = 2 * $pi - atan(abs($y1)/$x1);
                } elseif(
$x1 == 0 && $y1 > 0) {
                   
$theta1 = $pi / 2;
                } elseif(
$x1 == 0 && $y1 < 0) {
                   
$theta1 = 3 * $pi / 2;
                } elseif(
$x1 > 0 && $y1 == 0) {
                   
$theta1 = 0;
                } elseif(
$x1 < 0 && $y1 == 0) {
                   
$theta1 = $pi;
                } else {
                   
// Only case left should be $x1 == 0 && $y1 == 0
                   
$noTranslate = true;
                }
               
               
// Translate the position
               
if(!$noTranslate) {
                   
// Calculate the new angle
                   
$theta2 = $theta1 + $theta;
                   
                   
// Make sure theta2 is in between 0 - 2pi
                   
while($theta2 < 0) $theta2 += 2 * $pi;
                    while(
$theta2 > (2 * $pi)) $theta2 -= 2 * $pi;
                   
                   
$radius = sqrt($x1*$x1 + $y1*$y1);
                   
                   
$x2 = ($radius * cos($theta2));
                   
$y2 = ($radius * sin($theta2));
                } else {
                   
$x2 = $x1;
                   
$y2 = $y1;
                }
               
               
// Store the pixel color
               
$pixels[] = array($x2, $y2, imagecolorat($srcImg, $x, $y));
               
               
// Check our boundaries
               
if($x2 > $maxx) $maxx = $x2;
                if(
$x2 < $minx) $minx = $x2;
                if(
$y2 > $maxy) $maxy = $y2;
                if(
$y2 < $miny) $miny = $y2;
            }
        }
       
       
// Determine the new image size
       
$dstw = $maxx - $minx + 1;
       
$dsth = $maxy - $miny + 1;
       
       
// Create our new image
       
$dstImg = imagecreatetruecolor($dstw, $dsth);
       
       
// Fill the background with our transparent color
       
if($transparentColor == null) $transparentColor = imagecolorallocate($dstImg, 1, 2, 3);
       
imagecolortransparent($dstImg, $transparentColor);
       
imagefilledrectangle($dstImg, 0, 0, $dstw + 1, $dsth + 1, $transparentColor);
       
       
// Get the new origin
       
$neworiginx = -$minx;
       
$neworiginy = -$miny;
       
       
// Fill in the pixels
       
foreach($pixels as $data) {
            list(
$x, $y, $color) = $data;
            list(
$newx, $newy) = translateCoordinate($neworiginx, $neworiginy, $x, $y);
           
imagesetpixel($dstImg, $newx, $newy, $color);
        }
       
        return
$dstImg;
    }
   
   
/**
     * Translates from mathematical coordinate system to computer coordinate system using
     * origin coordinates from the computer system or visa versa
     *
     * @param int $originx
     * @param int $originy
     * @param int $x
     * @param int $y
     * @param bool $toComp
     * @return array(int $x, int $y)
     */
   
function translateCoordinate($originx, $originy, $x, $y, $toComp=true) {
        if(
$toComp) {
           
$newx = $originx + $x;
           
$newy = $originy - $y;
        } else {
           
$newx = $x - $originx;
           
$newy = $originy - $y;
        }
       
        return array(
$newx, $newy);
    }
}
?>
achilles
31-Mar-2008 10:02
otimized integration from 23-Feb-2007 04:21
just put it anywhere you like to use imagerotate with 90, 180, 270 degrees.
<?php
if(!function_exists("imagerotate")) {
    function
imagerotate($src_img, $angle) {
       
$src_x = imagesx($src_img);
       
$src_y = imagesy($src_img);
        if (
$angle == 180) {
           
$dest_x = $src_x;
           
$dest_y = $src_y; }
        elseif (
$src_x <= $src_y) {
           
$dest_x = $src_y;
           
$dest_y = $src_x; }
        elseif (
$src_x >= $src_y) {
           
$dest_x = $src_y;
           
$dest_y = $src_x; }
       
       
$rotate=imagecreatetruecolor($dest_x,$dest_y);
       
imagealphablending($rotate, false);
              
        switch (
$angle) {
            case
270:
                for (
$y = 0; $y < ($src_y); $y++) {
                    for (
$x = 0; $x < ($src_x); $x++) {
                       
$color = imagecolorat($src_img, $x, $y);
                       
imagesetpixel($rotate, $dest_x - $y - 1, $x, $color); }}
                break;
            case
90:
                for (
$y = 0; $y < ($src_y); $y++) {
                    for (
$x = 0; $x < ($src_x); $x++) {
                       
$color = imagecolorat($src_img, $x, $y);
                       
imagesetpixel($rotate, $y, $dest_y - $x - 1, $color); }}
                break;
            case
180:
                for (
$y = 0; $y < ($src_y); $y++) {
                    for (
$x = 0; $x < ($src_x); $x++) {
                       
$color = imagecolorat($src_img, $x, $y);
                       
imagesetpixel($rotate, $dest_x - $x - 1, $dest_y - $y - 1, $color); }}
                break;
            default:
$rotate = $src_img; }
        return
$rotate; }}
?>
qrgames at NOSPAMTYrushyo dot com
11-Aug-2007 11:06
imagerotate seems to be very fussy about handling transparency when copymerging onto another image. You can use the GD library's other transparency features to cover up the fact imagerotate gets it wrong HOWEVER it will only work if the top-left corner of the image is transparent at all rotations, so make the image a little bigger than it needs to be. This has been tested with png32 but does not work entirely for png8, as a phenomena creates noise around the rotated image.

<?php

$imgImage
= imagecreatefrompng("image.png");
$colBlack = imagecolorallocate($imgImage, 0, 0, 0);
$imgImage = imagerotate($imgImage, 360 - $intHeading, 0);
imagefill($imgImage, 0, 0, $colBlack);
imagecolortransparent($imgImage, $colBlack);
imagecopymerge($imgOriginalImage , $imgImage, $intX, $intY, 0, 0, $intHeight, $intWidth, 100);
imagedestroy($imgImage);

?>

Note. $intHeading is in degrees clockwise :)
Thomaschaaf
23-Feb-2007 03:21
<?php
function rotate($degrees)
    {
        if(
function_exists("imagerotate"))
           
$this->image = imagerotate($this->image, $degrees, 0);
        else
        {
            function
imagerotate($src_img, $angle)
            {
               
$src_x = imagesx($src_img);
               
$src_y = imagesy($src_img);
                if (
$angle == 180)
                {
                   
$dest_x = $src_x;
                   
$dest_y = $src_y;
                }
                elseif (
$src_x <= $src_y)
                {
                   
$dest_x = $src_y;
                   
$dest_y = $src_x;
                }
                elseif (
$src_x >= $src_y
                {
                   
$dest_x = $src_y;
                   
$dest_y = $src_x;
                }
               
               
$rotate=imagecreatetruecolor($dest_x,$dest_y);
               
imagealphablending($rotate, false);
               
                switch (
$angle)
                {
                    case
270:
                        for (
$y = 0; $y < ($src_y); $y++)
                        {
                            for (
$x = 0; $x < ($src_x); $x++)
                            {
                               
$color = imagecolorat($src_img, $x, $y);
                               
imagesetpixel($rotate, $dest_x - $y - 1, $x, $color);
                            }
                        }
                        break;
                    case
90:
                        for (
$y = 0; $y < ($src_y); $y++)
                        {
                            for (
$x = 0; $x < ($src_x); $x++)
                            {
                               
$color = imagecolorat($src_img, $x, $y);
                               
imagesetpixel($rotate, $y, $dest_y - $x - 1, $color);
                            }
                        }
                        break;
                    case
180:
                        for (
$y = 0; $y < ($src_y); $y++)
                        {
                            for (
$x = 0; $x < ($src_x); $x++)
                            {
                               
$color = imagecolorat($src_img, $x, $y);
                               
imagesetpixel($rotate, $dest_x - $x - 1, $dest_y - $y - 1, $color);
                            }
                        }
                        break;
                    default:
$rotate = $src_img;
                };
                return
$rotate;
            }
           
$this->image = imagerotate($this->image, $degrees);
        }
    }
?>
m dot quinton at gmail dot com
14-Sep-2006 04:30
with large file, where imagerotate is missing, you can use, when possible "convert" command from ImageMagick. Here is a sample script.

<?php

error_reporting
(E_ALL);

header("Content-type: image/png");

$file = 'images/test/imgp2498.jpg';

image_rotate_with_convert($file, 90);

function
image_rotate_with_convert($file, $angle){
   
passthru("convert -rotate $angle $file -");
}

?>
barbarism at oscillatewildly dot com
18-Apr-2006 02:00
If you pass "-1" into the last param of imagecreatefrompng, it preserves PNG transparently properly!

Exampe:

<?php
    $filename
= './documents/135.pdf.png';
   
$degrees = 40;

   
header('Content-type: image/png');

   
$source = imagecreatefrompng($filename);

   
$rotate = imagerotate($source, $degrees, -1);

   
imagealphablending($rotate, true);
   
imagesavealpha($rotate, true);

   
imagepng($rotate);
?>
Longhair
13-Apr-2006 09:03
<?php

//KOMPASS //PHP4.0 //GD2

$wert=0; //0-360 degree
$null=46; //Offset
$bgcolor=0x0033CC;
$grad=$wert+$null;
$kompass=imagecreatefromjpeg("bilder/kompass_ohne.jpg");
$nadel=imagecreatefromjpeg("bilder/nadel_bleu.jpg");

$mov_nadel= imagerotate($nadel, $grad, $bgcolor);

$xKom=imagesx($kompass);
$yKom=imagesy($kompass);

$x2Kom=$xKom/2;
$y2Kom=$yKom/2;

$xNad=imagesy($mov_nadel);
$yNad=imagesy($mov_nadel);

$y2Nad=$yNad/2+$x2Kom-$yNad; //92/2=46 + 100-92
$x2Nad=$xNad/2+$y2Kom-$xNad;

imagecopy ( $kompass, $mov_nadel, $x2Nad, $y2Nad, 0, 0, $xNad, $xNad );

header("Content-type: image/jpg");
//wird als JEPG-Bild Ausgegeben
//imagepng($kompass);
imagejpeg($kompass);
//imagegif($nadel);
imagedestroy($nadel);
imagedestroy($kompass);

?>
gareth at crxchaos dot co dot uk
02-Mar-2006 03:19
It's worth noting this function will only rotate true colour images - If you have a 256 colour pallet based image it will not rotate with this. Use the following code to convert the 256 colour image to truecolour first:

<?php

if (!imageistruecolor($im))
{
 
$w = imagesx($im);
 
$h = imagesy($im);
 
$t_im = imagecreatetruecolor($w,$h);
 
imagecopy($t_im,$im,0,0,0,0,$w,$h);
 
$im = $t_im;
}

?>

I have found no mention of this shortcoming of imagerotate anywhere on the Internet. Hopefully this will limit the number of people who, like me, are trying to troubleshoot a perfectly operation PHP install.
simon_nuttall at hotmail dot com
27-Sep-2005 05:06
The following is potentially useful. It extracts the central largest circle of an image into a square of specified size, and optionally rotates it. The rest of the square is made transparent, so useful for drawing over other images. I've named it after binocular effect because on some old TV shows whenever they show someone looking through binoculars the screen shows a big circular image with black edges.

<?php

function image_binocular_effect($src, $bearing, $out_square) {
 
// the source image is resampled to fit within the specified square, and rotated clockwise by bearing.
 // the largest circle within the image is retained, the rest made transparent.
 
$out = imagecreatetruecolor($out_square, $out_square);
 
$width=imagesx($src);
 
$height=imagesy($src);
 
$square=min($width, $height);
 
imagecopyresampled($out, $src, 0, 0, ($width - $square)/2 , ($height - $square)/2, $out_square, $out_square, $square, $square);

 
$mask = imagecreatetruecolor($out_square, $out_square);
 
$black = ImageColorAllocate ($mask, 0, 0, 0);
 
$white = ImageColorAllocate ($mask, 255, 255, 255);
 
imagefilledrectangle($mask , 0, 0, $out_square, $out_square, $white);
 
$centrexy=$out_square / 2;
 
imagefilledellipse($mask, $centrexy, $centrexy, $out_square, $out_square, $black);
 
ImageColorTransparent($mask, $black);
 
imagecopymerge($out, $mask0, 0, 0, 0, $out_square, $out_square, 100);
 if (
$bearing != 0) {
 
$rotated_img=imagerotate($out , 360-$bearing, $white);
 
// take off only the rotated width
 
$rotated_map_width = imagesx($rotated_img);
 
$rotated_map_height = imagesy($rotated_img);
 
imagecopy($out, $rotated_img, 0, 0, ($rotated_map_width - $out_square) / 2, ($rotated_map_height - $out_square) / 2, $out_square, $out_square);
  }
 
ImageColorTransparent($out, $white);
 return
$out;
}

// Create a sample image to demonstrate the effect, but looks much better on real photos.

$src = imagecreatetruecolor(200, 50);
imagefilledrectangle($src, 0, 0, 200, 50, imagecolorallocate($src, 255, 255, 255));
ImageString($src, 3, 10, 10, "This is a sample image to illustrate the binocular effect", imagecolorallocate($im, 192, 0, 0));
$img=image_binocular_effect($src, 72, 50);
ImagePNG($img,"test.png");

?>
wulff at fyens dot dk
01-Mar-2005 09:22
I liked the rotateImageBicubic function implemented by darren at lucidtone dot com. But it just snipped off the parts of the image that were outside the original image.

I fixed this, even though I admit that my solution is a bit naive. But it might come in handy for somebody.

Also his bicubic implementation was broken on my machine so I left it out, if you need it just copy and paste it from above.

<?php

// $src_img - a GD image resource
// $angle - degrees to rotate clockwise, in degrees
// returns a GD image resource
// USAGE:
// $im = imagecreatefrompng('test.png');
// $im = imagerotate($im, 15);
// header('Content-type: image/png');
// imagepng($im);
function imageRotate($src_img, $angle, $bicubic=false) {
 
  
// convert degrees to radians
  
$angle = $angle + 180;
  
$angle = deg2rad($angle);
 
  
$src_x = imagesx($src_img);
  
$src_y = imagesy($src_img);
 
  
$center_x = floor($src_x/2);
  
$center_y = floor($src_y/2);

  
$cosangle = cos($angle);
  
$sinangle = sin($angle);

  
$corners=array(array(0,0), array($src_x,0), array($src_x,$src_y), array(0,$src_y));

   foreach(
$corners as $key=>$value) {
    
$value[0]-=$center_x;        //Translate coords to center for rotation
    
$value[1]-=$center_y;
    
$temp=array();
    
$temp[0]=$value[0]*$cosangle+$value[1]*$sinangle;
    
$temp[1]=$value[1]*$cosangle-$value[0]*$sinangle;
    
$corners[$key]=$temp;   
   }
  
  
$min_x=1000000000000000;
  
$max_x=-1000000000000000;
  
$min_y=1000000000000000;
  
$max_y=-1000000000000000;
  
   foreach(
$corners as $key => $value) {
     if(
$value[0]<$min_x)
      
$min_x=$value[0];
     if(
$value[0]>$max_x)
      
$max_x=$value[0];
  
     if(
$value[1]<$min_y)
      
$min_y=$value[1];
     if(
$value[1]>$max_y)
      
$max_y=$value[1];
   }

  
$rotate_width=round($max_x-$min_x);
  
$rotate_height=round($max_y-$min_y);

  
$rotate=imagecreatetruecolor($rotate_width,$rotate_height);
  
imagealphablending($rotate, false);
  
imagesavealpha($rotate, true);

  
//Reset center to center of our image
  
$newcenter_x = ($rotate_width)/2;
  
$newcenter_y = ($rotate_height)/2;

   for (
$y = 0; $y < ($rotate_height); $y++) {
     for (
$x = 0; $x < ($rotate_width); $x++) {
      
// rotate...
      
$old_x = round((($newcenter_x-$x) * $cosangle + ($newcenter_y-$y) * $sinangle))
         +
$center_x;
      
$old_y = round((($newcenter_y-$y) * $cosangle - ($newcenter_x-$x) * $sinangle))
         +
$center_y;
     
       if (
$old_x >= 0 && $old_x < $src_x
            
&& $old_y >= 0 && $old_y < $src_y ) {

          
$color = imagecolorat($src_img, $old_x, $old_y);
       } else {
        
// this line sets the background colour
        
$color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
       }
      
imagesetpixel($rotate, $x, $y, $color);
     }
   }
  
  return(
$rotate);
}

?>
Borszczuk
05-Jan-2005 01:21
Here's a function that implements right angle (multiplicity of 90 degs - 90, 180, 270) rotation if you need one but lacks native imagerotate() or you don't want non-square images to be scaled down as with imagerotate(). As you probably noticed it's not self contained function, as 180 rotation is handled by ImageFlip() function to gain the performance. The ImageFlip() function used is published here: http://php.net/imagecopy in the comment of mine placed on  05-Jan-2005 04:30

Please note: that in case of 0 degrees rotation handle to imgSrc is returned which may lead to problems if you imagedestroy() it undonditionaly. To solve that you shall add imagecopy($imgDest, $imgSrc, 0,0, 0,0,$srcX, $srcY)  in proper place which I have intentionally ommited to save memory resources

<?php

// $imgSrc - GD image handle of source image
// $angle - angle of rotation. Needs to be positive integer
// angle shall be 0,90,180,270, but if you give other it
// will be rouned to nearest right angle (i.e. 52->90 degs,
// 96->90 degs)
// returns GD image handle of rotated image.
function ImageRotateRightAngle( $imgSrc, $angle )
{
   
// ensuring we got really RightAngle (if not we choose the closest one)
   
$angle = min( ( (int)(($angle+45) / 90) * 90), 270 );

   
// no need to fight
   
if( $angle == 0 )
        return(
$imgSrc );

   
// dimenstion of source image
   
$srcX = imagesx( $imgSrc );
   
$srcY = imagesy( $imgSrc );

    switch(
$angle )
        {
        case
90:
           
$imgDest = imagecreatetruecolor( $srcY, $srcX );
            for(
$x=0; $x<$srcX; $x++ )
                for(
$y=0; $y<$srcY; $y++ )
                   
imagecopy($imgDest, $imgSrc, $srcY-$y-1, $x, $x, $y, 1, 1);
            break;

        case
180:
           
$imgDest = ImageFlip( $imgSrc, IMAGE_FLIP_BOTH );
            break;

        case
270:
           
$imgDest = imagecreatetruecolor( $srcY, $srcX );
            for(
$x=0; $x<$srcX; $x++ )
                for(
$y=0; $y<$srcY; $y++ )
                   
imagecopy($imgDest, $imgSrc, $y, $srcX-$x-1, $x, $y, 1, 1);
            break;
        }

    return(
$imgDest );
}
?>
darren at lucidtone dot com
08-Dec-2004 04:43
Here's a neat function for those of us who don't have imagerotate() on our servers.  It's based on a comment from ron at korving dot demon dot nl on the manual page for imagecopyresampled.

I'm still not 100% on coping with transparency, but this function seems to cope okay.  It doesn't resize to fit within bounds, it just rotates and you lose anything outside the image box. 

The bicubic mode is slooow.

If you want to be able to change the background colour, pass in a colour and use it where indicated.  The line I used just sets it transparent.

<?php
// $src_img - a GD image resource
// $angle - degrees to rotate clockwise, in degrees
// returns a GD image resource
// USAGE:
// $im = imagecreatefrompng('test.png');
// $im = imagerotate($im, 15);
// header('Content-type: image/png');
// imagepng($im);
function imageRotateBicubic($src_img, $angle, $bicubic=false) {
   
   
// convert degrees to radians
   
$angle = $angle + 180;
   
$angle = deg2rad($angle);
   
   
$src_x = imagesx($src_img);
   
$src_y = imagesy($src_img);
   
   
$center_x = floor($src_x/2);
   
$center_y = floor($src_y/2);
   
   
$rotate = imagecreatetruecolor($src_x, $src_y);
   
imagealphablending($rotate, false);
   
imagesavealpha($rotate, true);

   
$cosangle = cos($angle);
   
$sinangle = sin($angle);
   
    for (
$y = 0; $y < $src_y; $y++) {
      for (
$x = 0; $x < $src_x; $x++) {
   
// rotate...
   
$old_x = (($center_x-$x) * $cosangle + ($center_y-$y) * $sinangle)
      +
$center_x;
   
$old_y = (($center_y-$y) * $cosangle - ($center_x-$x) * $sinangle)
      +
$center_y;
   
    if (
$old_x >= 0 && $old_x < $src_x
        
&& $old_y >= 0 && $old_y < $src_y ) {
      if (
$bicubic == true) {
       
$sY  = $old_y + 1;
       
$siY  = $old_y;
       
$siY2 = $old_y - 1;
       
$sX  = $old_x + 1;
       
$siX  = $old_x;
       
$siX2 = $old_x - 1;
       
       
$c1 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY2));
       
$c2 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY));
       
$c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
       
$c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));
       
       
$r = ($c1['red']  + $c2['red']  + $c3['red']  + $c4['red']  ) << 14;
       
$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) << 6;
       
$b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >> 2;
       
$a = ($c1['alpha']  + $c2['alpha']  + $c3['alpha']  + $c4['alpha'] ) >> 2;
       
$color = imagecolorallocatealpha($src_img, $r,$g,$b,$a);
      } else {
       
$color = imagecolorat($src_img, $old_x, $old_y);
      }
    } else {
         
// this line sets the background colour
     
$color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
    }
   
imagesetpixel($rotate, $x, $y, $color);
      }
    }
    return
$rotate;
}
?>
jon at driestone dot com
07-Oct-2004 03:42
imagerotate does not preserve the alpha channel, so if you want to rotate a PNG you need to get
creative. I don't see any command to retrieve the alpha information from an image (as far as
I could see,) so you'll have to do a bit of manual labor before hand. In my case I created a
second PNG file with the alpha saved as RGB data and manually "copied" the data from source
to destination:

<?php
   
function alpha_rotate($dst,$src,$rotate,$offsetX,$offsetY){

       
$top = imagecreatefrompng("image_processing/shadow.png");
       
$top_alpha = imagecreatefrompng("image_processing/shadow_alpha.png");
               
       
imagecopyresampled($top,$src,0,0,0,0,100,100,100,100);
               
       
$top = imagerotate($top,$rotate,0x000000);
       
$top_alpha = imagerotate($top_alpha,$rotate,0x000000);
   
   
        for (
$theX=0;$theX<imagesx($top);$theX++){
            for (
$theY=0;$theY<imagesy($top);$theY++){
   
               
$rgb = imagecolorat($top,$theX,$theY);
               
$r = ($rgb >> 16) & 0xFF;
               
$g = ($rgb >> 8) & 0xFF;
               
$b = $rgb & 0xFF;
               
               
$rgb = imagecolorat($top_alpha,$theX,$theY);
               
$a = $rgb & 0xFF;
               
$a = 127-floor($a/2);

               
$myColor = imagecolorallocatealpha($top,$r,$g,$b,$a);
               
imagesetpixel($dst,($theX+$offsetX),($theY+$offsetY),$myColor);   
            }
        }
    }
?>
christoph (at) raketenbasis (dot) de
04-Oct-2004 07:41
The default direction of imageRotate() is counter clockwise. Heres a little function which solves the problem.

<?php

   
function rotate(&$image_source, $rotate_value, $rotate_clockwise = true) {
        if(
$rotate_clockwise == true) {
           
$rotate_value = 360 - $rotate_value;
        }
       
$image_source = imageRotate($image_source, $rotate_value, 0);
    }
   
?>

imagesavealpha> <imagerectangle
Last updated: Fri, 03 Jul 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites