#3 28.12.07 23:14
Re: [php+gd] поворот изображений
А если прям фтанке, то
Код::
<?php
function imagerotate(&$img, $ang, $bg=FALSE, $width=FALSE,
$height=FALSE, $bench=FALSE) {
if($bench) $time = microtime();
if(!$bg) $bg = imagecolorallocate($img, 255,255,255);
// size of the image
$src_w = imagesx($img);
$src_h = imagesy($img);
// reduce angle
while($ang > 180) $ang = $ang-360;
while($ang < -180) $ang = $ang+360;
// угол > 90°
if($ang > 90) {
imagerotate($img, 90, $bg, $src_h,$src_w);
$ang = $ang - 90;
}
elseif($ang < -90) {
imagerotate($img, -90, $bg, $src_h,$src_w);
$ang = $ang + 90;
}
// размер изображения
$src_w = imagesx($img);
$src_h = imagesy($img);
if($ang != 0) {
// перевод градусов в радианы
if($ang > 0) $wrad = deg2rad($ang);
else $wrad = deg2rad((-1*$ang));
$sin = sin($wrad); if($sin < 0) $sin*=-1;
$cos = cos($wrad); if($cos < 0) $cos*=-1;
// размер изображения, после поворота
$dst_w = (int) ( $sin*$src_h + $cos*$src_w );
$dst_h = (int) ( $cos*$src_h + $sin*$src_w );
if($dst_w < 0) $dst_w *= -1;
if($dst_h < 0) $dst_h *= -1;
$scale_x = (int) ( $width/$dst_w );
$scale_y = (int) ( $height/$dst_h );
// создаем изображение и устанавливаем цвет фона
$dst_img = imagecreatetruecolor($dst_w, $dst_h);
imagefill($dst_img, 0,0, $bg);
for($i=0; $i<$src_h; $i++) {
for($j=0; $j<$src_w; $j++) {
// получаем новую позицию пикселя
if($ang > 0) {
$dst_x = (int) ( $sin*($src_h-$i) + $cos*$j );
$dst_y = (int) ( $sin*$j + $cos*$i );
}
else {
$dst_x = (int) ( $sin*$i + $cos*$j );
$dst_y = (int) ( $sin*($src_w-$j) + $cos*$i );
}
if($scale_x != 0) $dst_x = $dst_x*$scale_x;
if($scale_y != 0) $dst_y = $dst_y*$scale_y;
// получаем цвет данного пикселя
$col = imagecolorat($img, $j, $i);
// рисуем пиксель (рисуем два пикселя за раз чтобы избежать появления
// брешей/окон)
imagefilledrectangle($dst_img, $dst_x,$dst_y, $dst_x+1,$dst_y, $col);
}
}
// необходимо взять пробу
if($width!==FALSE && $height!==FALSE && ($width!=$dst_w || $height!=$dst_h)) {
$new_img = imagecreatetruecolor($width, $height);
imagefill($new_img, 0,0, $bg);
imagecopyresampled($new_img, $dst_img, 0,0,0,0, $width,$height,
$dst_w,$dst_h);
imagedestroy($dst_img);
$img = $new_img;
}
else $img = $dst_img;
}
// не надо поворачивать, только взять пробу
elseif($width!==FALSE && $height!==FALSE && ($width!=$dst_w || $height!=$dst_h)) {
$dst_img = imagecreatetruecolor($width, $height);
imagefill($dst_img, 0,0, $bg);
imagecopyresampled($dst_img, $img, 0,0,0,0, $width, $height, $src_w, $src_h);
$img = $dst_img;
}
// ничего не надо делать
else $img = $dst_img;
if(!$bench) return;
// необязательная часть модуля, которая выводит данные работы функции
elseif($bench == "IMAGE") {
list($usec, $sec) = explode(" ",microtime());
$etime = (float)$usec + (float)$sec;
list($usec, $sec) = explode(" ",$time);
$etime -= (float)$usec + (float)$sec;
$etime = substr($etime, 0, 7);
imagefilledrectangle($img, 0,0, 42,12, imagecolorallocate($img, 255,255,255));
imagestring($img, 2, 0,0, $etime, imagecolorallocate($img, 0,0,0));
}
elseif($bench == "STRING") {
list($usec, $sec) = explode(" ",microtime());
$etime = (float)$usec + (float)$sec;
list($usec, $sec) = explode(" ",$time);
$etime -= (float)$usec + (float)$sec;
return $etime;
}
}
?>Итак, функция imagerotate. Синтаксис:
imagerotate($img, $ang[, $bg[, $width, $height[, $bench]]]);
$img - изображение, которое необходимо вращать.
$ang - угол поворота
$bg (опционально) - индекс цвета фона (по-умолчанию: белый)
$width и $height (опционально) - изображение будет приведено к этому
размеру. Обязательно использование обоих параметров вместе!
$bench (опционально)
"STRING" возвращает время, необходимое для выполнить функцию.
"IMAGE" поместит маленькую отметку с временем на изображение.
Примерное время выполнения функции при изображении размером 250x200px
при повороте <90° составляет примерно 1 секунду; при повороте на
угол >90° - ~2 секунды
!Эта функция работает только с изображениями JPEG!
Исправлено Malkolm (28.12.07 23:14)
Offline

