| 1 |
<?php
|
| 2 |
// $Id: imagerotate.inc,v 1.4 2009/02/13 00:06:02 drewish Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* provides the imagerotate function for php-gd extensions compiled with the
|
| 7 |
* upstream libgd instead of the libgd bundled with php.
|
| 8 |
*/
|
| 9 |
|
| 10 |
|
| 11 |
// Define as included.
|
| 12 |
define('IMAGEAPI_IMAGEROTATE_PHP', 1);
|
| 13 |
|
| 14 |
function imagerotate(&$im, $angle, $bgcolor) {
|
| 15 |
if ($angle === 0) {
|
| 16 |
return $im;
|
| 17 |
}
|
| 18 |
// imagerotate() in php's libgd rotates the image counterclockwise,
|
| 19 |
// this implementation rotates clockwise. The angle needs to be
|
| 20 |
// inverted to give the same behaviour between these implementations.
|
| 21 |
$angle = 360 - $angle;
|
| 22 |
|
| 23 |
$width = imagesx($im);
|
| 24 |
$height = imagesy($im);
|
| 25 |
// background color.
|
| 26 |
list($r, $g, $b, $a) = imageapi_hex2rgba($bgcolor);
|
| 27 |
|
| 28 |
switch ($angle) {
|
| 29 |
case 270:
|
| 30 |
case 90:
|
| 31 |
// flip dimensions.
|
| 32 |
$rot_width = $height;
|
| 33 |
$rot_height = $width;
|
| 34 |
break;
|
| 35 |
case 180:
|
| 36 |
// maintain dims.
|
| 37 |
$rot_width = $width;
|
| 38 |
$rot_height = $height;
|
| 39 |
break;
|
| 40 |
|
| 41 |
default:
|
| 42 |
// well it won't be easy but we'll actually rotate this
|
| 43 |
// puppy ourselves.. gonna require a little trig.
|
| 44 |
// @todo: convert to a polar equation and use 1/2 length of hypoteneus.
|
| 45 |
$center_x = floor($width/2);
|
| 46 |
$center_y = floor($height/2);
|
| 47 |
|
| 48 |
// convert to radians and precompute ...
|
| 49 |
$cosangle = cos(deg2rad($angle+180));
|
| 50 |
$sinangle = sin(deg2rad($angle+180));
|
| 51 |
|
| 52 |
// caluculate new width and height.
|
| 53 |
$corners=array(array(0, 0), array($width, 0), array($width, $height), array(0, $height));
|
| 54 |
$max_x = $min_x = $max_y = $min_y = 0;
|
| 55 |
foreach ($corners as $key => $value) {
|
| 56 |
$value[0] -= $center_x; //Translate coords to center for rotation
|
| 57 |
$value[1] -= $center_y;
|
| 58 |
$x = $value[0] * $cosangle + $value[1] * $sinangle;
|
| 59 |
$y = $value[1] * $cosangle - $value[0] * $sinangle;
|
| 60 |
$max_x = max($x, $max_x);
|
| 61 |
$min_x = min($x, $min_x);
|
| 62 |
$max_y = max($y, $max_y);
|
| 63 |
$min_y = min($y, $min_y);
|
| 64 |
}
|
| 65 |
$rot_width = (int)$max_x - $min_x;
|
| 66 |
$rot_height = (int)$max_y - $min_y;
|
| 67 |
$rot_center_x = floor($rot_width/2);
|
| 68 |
$rot_center_y = floor($rot_height/2);
|
| 69 |
}
|
| 70 |
|
| 71 |
$rotate = imagecreatetruecolor($rot_width, $rot_height);
|
| 72 |
$bg = imagecolorallocatealpha($rotate, $r, $g, $b, $a);
|
| 73 |
imagefilledrectangle($rotate, 0, 0, $rot_width, $rot_height, $bg);
|
| 74 |
imagealphablending($rotate, false);
|
| 75 |
imagesavealpha($rotate, true);
|
| 76 |
|
| 77 |
switch ($angle) {
|
| 78 |
case 270:
|
| 79 |
$rot_width--;
|
| 80 |
for ($y = 0; $y < $height; ++$y)
|
| 81 |
for ($x = 0; $x < $width; ++$x)
|
| 82 |
imagesetpixel($rotate, $rot_width - $y, $x, imagecolorat($im, $x, $y));
|
| 83 |
break;
|
| 84 |
case 90:
|
| 85 |
$rot_height--;
|
| 86 |
for ($y = 0; $y < $height; ++$y)
|
| 87 |
for ($x = 0; $x < $width; ++$x)
|
| 88 |
imagesetpixel($rotate, $y, $rot_height - $x, imagecolorat($im, $x, $y));
|
| 89 |
break;
|
| 90 |
case 180:
|
| 91 |
$rot_width--;
|
| 92 |
$rot_height--;
|
| 93 |
for ($y = 0; $y < $height; ++$y)
|
| 94 |
for ($x = 0; $x < $width; ++$x)
|
| 95 |
imagesetpixel($rotate, $rot_width - $x, $rot_height - $y, imagecolorat($im, $x, $y));
|
| 96 |
break;
|
| 97 |
|
| 98 |
default:
|
| 99 |
for ($y = 0; $y < $rot_height; ++$y) {
|
| 100 |
for ($x = 0; $x < $rot_width; ++$x) {
|
| 101 |
$mod_y = $rot_center_y-$y;
|
| 102 |
$mod_x = $rot_center_x-$x;
|
| 103 |
$old_x = $mod_x * $cosangle + $mod_y * $sinangle + $center_x;
|
| 104 |
$old_y = $mod_y * $cosangle - $mod_x * $sinangle + $center_y;
|
| 105 |
if ($old_x >= 0 && $old_x < $width && $old_y >= 0 && $old_y < $height) {
|
| 106 |
$color = imagecolorat($im, $old_x, $old_y);
|
| 107 |
imagesetpixel($rotate, $x, $y, $color);
|
| 108 |
}
|
| 109 |
}
|
| 110 |
}
|
| 111 |
}
|
| 112 |
return $rotate;
|
| 113 |
}
|
| 114 |
|