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

search for in the

imagesavealpha> <imagerectangle
Last updated: Fri, 20 Jun 2008

view this page in

imagerotate

(PHP 4 >= 4.3.0, PHP 5)

imagerotate — Fait tourner une image d'un angle

Description

resource imagerotate ( resource $source_image , float $angle , int $bgd_color [, int $ignore_transparent ] )

imagerotate() fait tourner l'image src_im d'un angle de angle , en degrés.

Le centre de rotation est le centre de l'image, et l'image tournée est réduite de telle sorte que les ajustements apportés à l'image tournée - les bords ne soient pas coupés.

Liste de paramètres

source_image

Le lien vers l'image source

angle

L'angle de rotation, en degrés.

bgd_color

Spécifie la couleur des zones qui seront découvertes après la rotation.

ignore_transparent

Si ce paramètre est défini et ne vaut pas zéro, les couleurs transparentes seront ignorées.

Valeurs de retour

Historique

Version Description
5.1.0 Le paramètre ignore_transparent a été ajouté.

Exemples

Exemple #1 Rotation d'une image de 180 degrés

Cet exemple tourne une image de 180 degrés - à l'envers.

<?php
// Fichier et degrés de rotation
$filename 'test.jpg';
$degrees 180;

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

// Chargement
$source imagecreatefromjpeg($filename);

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

// Affichage
imagejpeg($rotate);
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

Notes

Note: Cette fonction n'est disponible que si PHP est compilé avec la version embarquée de la bibliothèque GD.



imagesavealpha> <imagerectangle
Last updated: Fri, 20 Jun 2008
 
add a note add a note User Contributed Notes
imagerotate
pilot at myupb dot com
30-May-2008 05: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 07: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.

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);
    }
}
cjastram at gmail dot com
13-May-2008 07:31
This function does not resize the image being rotated, as indicated by the phrase, "the rotated image is scaled down so that the whole rotated image fits in the destination image."  The returned image resource is resized up so as to exactly fit the rotated source image.

For those using Ubuntu, if you have permission to access your PHP modules directory, you can snag a bundled php-gd.so from another distribution (such as Red Hat or Mandriva) and replace yours, and you should be good to go (I was).  Remember, though, that the reason Ubuntu does not do this is because of security, so be responsible!
Dominik Scholz - info at HAM&SPAM dot go4u dot de
02-Apr-2008 10:23
I took the previous mentioned code and optimized it a little bit. It does some speed improvements for me, but I did no exact measurements. Instead of decrementing by 1 in each cycle of the for-loops, I did the decrementing once before the loops. Maybe further improvements can be made...

<?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 ((
$angle == 90) || ($angle == 270))
        {
           
$dest_x = $src_y;
           
$dest_y = $src_x;
        }
        else
        {
            return
$src_img;
        }
       
       
$rotate=imagecreatetruecolor($dest_x,$dest_y);
       
imagealphablending($rotate, false);
              
        switch (
$angle)
        {
            case
270:
               
$dest_x--;
                for (
$y = 0; $y < $src_y; $y++)
                    for (
$x = 0; $x < $src_x; $x++)
                       
imagesetpixel($rotate, $dest_x - $y, $x, imagecolorat($src_img, $x, $y));
                break;
            case
90:
               
$dest_y--;
                for (
$y = 0; $y < $src_y; $y++)
                    for (
$x = 0; $x < $src_x; $x++)
                       
imagesetpixel($rotate, $y, $dest_y - $x, imagecolorat($src_img, $x, $y));
                break;
            case
180:
               
$dest_x--;
               
$dest_y--;
                for (
$y = 0; $y < $src_y; $y++)
                    for (
$x = 0; $x < $src_x; $x++)
                       
imagesetpixel($rotate, $dest_x - $x, $dest_y - $y, imagecolorat($src_img, $x, $y));
                break;
        }
        return
$rotate;
    }
}
?>
achilles
31-Mar-2008 03: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; }}
?>
Anonymous
25-Oct-2007 01:36
the solution barbarism at oscillatewildly dot com came up with to use -1 to preserve transparency apparently only works if you have PHP5 settings on your host.
(This took me 2 days to figure out. I hope I save someone else that time.)

My settings:
PHP Version: 5.2.2
GD Version: bundled (2.0.34 compatible)

Working in PHP5 Example:
<?php
    $filename
= 'picturewithtransparency.png';
   
$degrees = -90; // tilt it

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

   
$source = imagecreatefrompng($filename);

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

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

   
imagepng($rotate);
?>
qrgames at NOSPAMTYrushyo dot com
11-Aug-2007 04: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 07:21
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);
        }
    }

This one works better than the one below from the 12th February and if the faster function is available it will take that.
It is still not optimized but turning pictures works better..
crymsan
12-Feb-2007 02:44
My php install does not have imagerotate (ubuntu). So, after fiddling with a few others I wrote my own code to rotate images in 90 degree increments. Any speed improvements would be great.

<?php
function imageRotate($src_img, $angle) {

   
$src_x = imagesx($src_img);
   
$src_y = imagesy($src_img);
    if (
$angle == 90 || $angle == -910) {
       
$dest_x = $src_y;
       
$dest_y = $src_x;
    } else {
       
$dest_x = $src_x;
       
$dest_y = $src_y;
    }

   
$rotate=imagecreatetruecolor($dest_x,$dest_y);
   
imagealphablending($rotate, false);

    switch (
$angle) {
        case
90:
            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;
}
?>
cedric dot francoys at easy-cms dot org
07-Jan-2007 10:26
note for this message : "I was having a problem with rotating a PNG. I used -1 for ignore_transparent and in Firefox the uncovered area was transparent but in IE it showed as grey.
The real problem is IE 6.0 does not support transparent PNGs.  So don't blame the imagerotatefunction.  I don't know about IE 7 though."

In fact, IE6 doesn't handle the transparency for 24 bits PNG images. But it does for 8 bits PNG. (This problem has been solved with IE7).
Meanwhile, even if the input image is a 8 bits one, the image returned by imagesrotate is a 24 bit one ... so IE6 wont correctly display it.
http://whitemarker.blogspot.com
03-Jan-2007 03:06
I was having a problem with rotating a PNG. I used -1 for ignore_transparent and in Firefox the uncovered area was transparent but in IE it showed as grey.

The real problem is IE 6.0 does not support transparent PNGs.  So don't blame the imagerotatefunction.  I don't know about IE 7 though.
m dot quinton at gmail dot com
14-Sep-2006 09: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
17-Apr-2006 07:00
If you pass "-1" into the last param of imagecreatefrompng, it preserves PNG transparently properly!

Exampe:

    $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 02:03
<?

//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 07: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.
olav-x at volvo-power.net
18-Nov-2005 04:17
I tried the example provided by 'jonathan AT sharpmedia DOT net', and that gave me strange rotations, with offset on the image.

I dont need an advanced rotation script like that, so I used his function wrapper and make a more simple edition.

ps. the code above the function is only for test-purpose.
I'll retrieve srcpic from the db.

the idea here, is that I'll store rotated thumbs of the original thumb. Then the user can click on the thumb which is "correctly rotated" and then the original file will be rotated.

I think I'll make some backup function implemented too!
the idea is that the rotated files will  have _ROT<int>.ext
eg. if you rotate the file "bicycle.jpg" 1 rotation (90 degrees), it will be copied to: bicycle_ROT1.jpg, 180 degrees would be _ROT2.jpg, and so on.

There is only 3 rots, I should have removed the ROT0 here, as well as the code might need improvement.
However, I think that simple codes like this ones, are the easiest ones to use as a foundation, as they are - simple!

What you can improve, if you want to do this:
* there is a lot! however, you have to wrap the $dst in something like:
if (!isset($dst)) {
}

eg. so you can over-ride the "save to", when calling the function!

this is beta 0.0000001 however, so play with it, slaughter it, whatever.

good luck!

Olav Alexander Mjelde

<?php
// #### start of test
$srcpic = 'bilder/biler/_tmp/foo.jpg';
echo
rotateImage($srcpic, $dstpic, 1, 100);
echo
rotateImage($srcpic, $dstpic, 2, 100);
echo
rotateImage($srcpic, $dstpic, 3, 100);
// #### end of test

// this function rotates an image
function rotateImage($src, $dst, $count = 1, $quality = 95)
{
   if (!
file_exists($src)) {
       return
false;
   }
  
// generate output filename
extension
   $dst
= substr($src, 0, strrpos($src, ".")) . "_ROT" . $count  . substr($src, strrpos($src, "."), strlen($src));

switch (
$count) {
case
0:
  
$degrees = 0;
   break;
case
1:
  
$degrees = 90;
   break;
case
2:
  
$degrees = 180;
   break;
case
3:
  
$degrees = 270;
   break;
}

// Load
$source = imagecreatefromjpeg($src);
// Rotate
$rotate = imagerotate($source, 360 - $degrees, 0);
// Output
imagejpeg($rotate, $dst, $quality);

  
imageDestroy($rotate);
  
imageDestroy($source);

   return
true;
}

?>
simon_nuttall at hotmail dot com
27-Sep-2005 10: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");

?>
kumm at webstar dot hu
22-Aug-2005 12:59
A better bugfix for jonathan AT sharpmedia DOT net's rotateImage function

you need to replace:

// Now copy tmp2 to $out;
imagecopy($out, $tmp2, 0, 0, ($angle == 270 ? abs($w - $h) : 0), 0, $h, $w);

with:
// Now copy tmp2 to $out;
if ($h>$w) {
   imagecopy($out, $tmp2, 0, 0, 0, ($angle == 90 ? abs($w - $h) : 0), $h, $w);
} else {
   imagecopy($out, $tmp2, 0, 0, ($angle == 270 ? abs($w - $h) : 0), 0, $h, $w);
}

otherwise the image gets moved when rotating a standing up image
jmichel at faeryscape dot com
26-Apr-2005 11:56
Imagerotate apparently destroy transparency information (transparent areas turn to black). For now the only walkaround I found is to use  :

imagecolortransparent($image,imagecolorat($image,0,0));

but the result is quite awful if your original picture uses smooth transparency (which is probably the case with PNG pictures)
oflashp at bk dot ru
22-Apr-2005 06:25
standart code rotate image(only Jpeg)
<?
$r=0; //rotate
$img="254.jpg" //image
$source = imagecreatefromjpeg($img);
$img = imagerotate($source, $r, 0);
imagejpeg($img);
?>
11-Apr-2005 09:58
Just an advice for those who want to create image galleries and want to add a function to rotate pictures.

The way this here works is always to decompress the picture, rotate it and compress it again.

Therefore there _WILL_ always be a loss in quality. The more often you rotate the image the stronger the artefacts will be visible.

Also using ImageMagick, if available does not help, as it also does not support lossless JPG manipulations.

If you need a rotate function, ask your provider to install JPEGTRAN on the machine your server runs on and use the command line tool from your php application.
wulff at fyens dot dk
01-Mar-2005 01: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