|
|
 |
imagerotate (PHP 4 >= 4.3.0, PHP 5) imagerotate -- Rotate an image with a given angle Descriptionresource imagerotate ( resource src_im, float angle, int bgd_color [, int ignore_transparent] )
Rotates the src_im image using a given
angle in degrees. bgd_color
specifies the color of the uncovered zone after the rotation.
The center of rotation is the center of the image, and the rotated
image is scaled down so that the whole rotated image fits in the
destination image - the edges are not clipped.
If ignore_transparent is set and non-zero,
transparent colors are ignored (otherwise kept). This parameter was added
in PHP 5.1.
Example 1. Rotate an image 180 degrees
This example rotates an image 180 degrees - upside down.
|
// File and rotation
$filename = 'test.jpg';
$degrees = 180;
// Content type
header('Content-type: image/jpeg');
// Load
$source = imagecreatefromjpeg($filename);
// Rotate
$rotate = imagerotate($source, $degrees, 0);
// Output
imagejpeg($rotate);
|
|
Note: This function is only available if
PHP is compiled with the bundled version of the GD library.
User Contributed Notes
imagerotate
jmichel at faeryscape dot com
27-Apr-2005 01: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 08:25
standart code rotate image(only Jpeg)
<?
$r=0; $img="254.jpg" $source = imagecreatefromjpeg($img);
$img = imagerotate($source, $r, 0);
imagejpeg($img);
?>
11-Apr-2005 11: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.
troumad at libertysurf dot fr
02-Mar-2005 05:02
I thank's Borszczuk fot her message 05-Jan-2005 02:21, but theire is a problem. He has write :
case 270:
$imgDest = imagecreatetruecolor( $srcY, $srcX );
for( $x=0; $x<$srcX; $x++ )
for( $y=0; $y<$srcY; $y++ )
imagecopy($imgDest, $imgSrc, $srcY-$y-1, $srcX-$x-1, $x, $y, 1, 1);
break;
and it's :
imagecopy($imgDest, $imgSrc, $y, $srcX-$x-1, $x, $y, 1, 1);
I use this because I dont understand why imagerotate don't work in my Mandrake 10.1 and my debien testing !
wulff at fyens dot dk
01-Mar-2005 03: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
function imageRotate($src_img, $angle, $bicubic=false) {
$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; $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);
$newcenter_x = ($rotate_width)/2;
$newcenter_y = ($rotate_height)/2;
for ($y = 0; $y < ($rotate_height); $y++) {
for ($x = 0; $x < ($rotate_width); $x++) {
$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 {
$color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
}
imagesetpixel($rotate, $x, $y, $color);
}
}
return($rotate);
}
?>
jonathan AT sharpmedia DOT net
18-Feb-2005 12:28
This method rotates an image in 90 degree increments (eg count should be between 1 and 3) and avoids the problems of image scaling that imageRotate has...
<?php
function rotateImage($src, $count = 1, $quality = 95)
{
if (!file_exists($src)) {
return false;
}
list($w, $h) = getimagesize($src);
if (($in = imageCreateFromJpeg($src)) === false) {
echo "Failed create from source<br>";
return false;
}
$angle = 360 - ((($count > 0 && $count < 4) ? $count : 0 ) * 90);
if ($w == $h || $angle == 180) {
$out = imageRotate($in, $angle, 0);
} elseif ($angle == 90 || $angle == 270) {
$size = ($w > $h ? $w : $h);
if (($tmp = imageCreateTrueColor($size, $size)) == false) {
echo "Failed create square trueColor<br>";
return false;
}
if (($out = imageCreateTrueColor($h, $w)) == false) {
echo "Failed create trueColor<br>";
return false;
}
imageCopy($tmp, $in, 0, 0, 0, 0, $w, $h);
$tmp2 = imageRotate($tmp, $angle, 0);
imageCopy($out, $tmp2, 0, 0, ($angle == 270 ? abs($w - $h) : 0), 0, $h, $w);
imageDestroy($tmp);
imageDestroy($tmp2);
} elseif ($angle == 360) {
imageDestroy($in);
return true;
}
imageJpeg($out, $src, $quality);
imageDestroy($in);
imageDestroy($out);
return true;
}
?>
Borszczuk
05-Jan-2005 07:41
A bugfix for ImageRotateRightAngle() - imagecopy() line for 270 degress should look like this:
imagecopy($imgDest, $imgSrc, $y, $srcX-$x-1, $x, $y, 1, 1);
Borszczuk
05-Jan-2005 07: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
function ImageRotateRightAngle( $imgSrc, $angle )
{
$angle = min( ( (int)(($angle+45) / 90) * 90), 270 );
if( $angle == 0 )
return( $imgSrc );
$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, $srcY-$y-1, $srcX-$x-1, $x, $y, 1, 1);
break;
}
return( $imgDest );
}
?>
darren at lucidtone dot com
07-Dec-2004 10: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.
<?
function imageRotateBicubic($src_img, $angle, $bicubic=false) {
$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++) {
$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 {
$color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
}
imagesetpixel($rotate, $x, $y, $color);
}
}
return $rotate;
}
?>
jon at driestone dot com
07-Oct-2004 10: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:
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 02: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);
}
?>
| |