Поворот изображения

 
0
 
PHP
ava
pnd_ku | 05.01.2007, 22:21
Драствуйте!
Возникла такая проблема:
Я создаю изображение с прозрачным фоном, потом его поворачиваю.
Мне нужно сохранять фон прозрачным...
посматрите пожалуйста код - так будет понятнее


<?php
$angle=0;

$im=imagecreatefrompng("overlay.png");
imagesavealpha($im,TRUE);
imagefill($im,0,0,imagecolorallocatealpha($im,0,0,0,127));
$im=imagerotate($im,$angle,imagecolorallocatealpha($im,50,50,50,127),false);

$im1=imagecreatetruecolor(imagesx($im),imagesy($im));
imagesavealpha($im1,TRUE);
imagefill($im1,0,0,imagecolorallocatealpha($im1,0,0,0,127));
imagecopy($im1,$im,0,0,0,0,imagesx($im),imagesy($im));

header("Content-type: image/png");
imagepng($im1);
ImageDestroy($im);
ImageDestroy($im1);
?>


overlay.png - пнгшка с альфа каналом. Если быть точнее фон полностью прозрачный, а в центре рыба smile
$angle - угол поворота. Изменяется от 45 до -44. Вернее в этих пределах всё как надо - картинка повернулась, фон прозрачный.
Но если вылезти за пределы угла, то фон становиться чорным...
Вот это проблема и я не знаю как её пофиксить :(

Есть какие-ни6уть идей??.. ))
Ответы (20)
ava
Mal Hack | 05.01.2007, 23:25 #
gd какой версии? Во всех браузерах черный фон?
ava
pnd_ku | 06.01.2007, 00:04 #
Gd 2.0.28 версии..
браузеры ессно все проверил, сохранял в файл - одна фигня.
Кстати пишет что пнг 32 битный, вывод в гиф тоже не помог.
ava
Mal Hack | 06.01.2007, 00:42 #
<?php

$angle=48;

$im=imagecreatefrompng("test.png");
imagesavealpha($im,true);

$im=imagerotate($im,$angle,imagecolorallocatealpha($im,0,0,0,127),0);
imagecolortransparent($im,imagecolorallocatealpha($im,0,0,0,127));

header("Content-type: image/png");
imagepng($im);
ImageDestroy($im);

?>

ava
pnd_ku | 06.01.2007, 12:05 #
не излечилось ((
ava
Mal Hack | 06.01.2007, 14:33 #
Как не излечилось, когда у меня все красиво smile
Сейчас проверю еще разок, конечно...
ava
Mal Hack | 06.01.2007, 15:09 #
Интересно получается...

$angle=5;



$im=imagecreatefrompng("test.png");
imagesavealpha($im,TRUE);
imagefill($im,1,1,255);
// imagecolortransparent($im,imagecolorallocatealpha($im,0,0,0,127));
///imagecolorallocatealpha($im,255,255,255,127)
imagesavealpha($im,TRUE);
imagecolortransparent($im,255);
imagesavealpha($im,TRUE);
$im=imagerotate($im,$angle,255,0);
imagecolortransparent($im,255);

Прозрачность есть в браузере, но ее нет в файле...
ava
pnd_ku | 06.01.2007, 15:29 #
хммм... всё ещё нет..
не люблю я такие ситуации когда ошибка не от меня зависит...
и гд обновить не имею прав :(

спасиба всё равно большое.. ;-)
ava
Mal Hack | 06.01.2007, 15:36 #
Тут есть два варианты. Либо баг в gd или php, кстати, какая у тебя версия.
Либо мы оба делаем какую-то маленькую ошибку, к примеру imagesavealpha($im,TRUE); не в том месте...
ava
pnd_ku | 06.01.2007, 16:05 #
у меня xampp

Добавлено позднее:
у меня xampp последней сборки....
залил на другой хост в Кювейте smile
там пхп как сги рабоатет, версия 5.1.2, гд 2.0.28

оч странно....
ava
Mal Hack | 06.01.2007, 16:39 #
Цитата (pnd_ku @ 6.1.2007, 16:05 findReferencedText)
там пхп как сги рабоатет, версия 5.1.2, гд 2.0.28

результат тот же?
ava
pnd_ku | 06.01.2007, 16:55 #
ога :(
в зенд девелопер зон отправить чтоле чтобы посматрели....
ava
pnd_ku | 06.01.2007, 17:10 #
дык я уже посматрел перед тем как тему постить smile
всё равно вопрос это не решает...
тут трабла как раз в момент поворота картинки ( причом до определённого градуса), без него я проблем не испытываю
ava
Mal Hack | 06.01.2007, 17:12 #
Цитата (pnd_ku @ 6.1.2007, 17:10 findReferencedText)
тут трабла как раз в момент поворота картинки ( причом до определённого градуса), без него я проблем не испытываю

Да знаю... Сейчас поем и попробую пошариться по закромам...
ava
pnd_ku | 06.01.2007, 17:16 #
Приятного smile
я тож подумаю ещё и поэкспериментирую...
ava
PARROT | 06.01.2007, 18:22 #
Посмотрите тут: http://www.komkon.org/~denis/mydoc/gd.htm может поможет :hmmm
ava
Mal Hack | 06.01.2007, 18:28 #
Кажется мне, что все эти глюк от несоверщенства GD..
Порылся в закромах phpclub'a, как всегда, ничего дельного кроме фразы "пошел в поиск" не нашел... Решил глянуть комменты в оф мане, на случай, если что проглядел...

http://ru2.php.net/manual/ru/function.imagerotate.php#46338
/*
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);
}
}
}


http://ru2.php.net/manual/ru/function.imagerotate.php#52288
Цитата


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)

ava
pnd_ku | 07.01.2007, 11:37 #
гонять по картинке в 1024х1024 по пикселям в пхп - жесть имхо smile
хотя вариант с маской интересный, не спорю...

родилось более быстрое решение и стандартными средствами - чтобы повернуть на угол, больший 45 градусов, мы отражаем картинку по вертикали, и потом уже поворачиваем..
и попадаем во всю шкалу градусов без проблем.

воть smile
спасиба!
ava
Mal Hack | 07.01.2007, 13:47 #
pnd_ku, код итоговый приведи.
ava
pnd_ku | 09.01.2007, 17:42 #
да да, конечно!
Тока отражение по вертикали тоже не сохраняло прозарчности, поэтому для решения всех головняков была сотварена самостоятельная фугкция поворота изображения (пнг с альфа каналом)
Вот.

<?
//function rotate image
function imRotate($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)
{
//Translate coords to center for rotation
$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);
//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);
}

###################################################################
###################################################################
###################################################################

//background and overlay images
$background="bg.jpg";
$overlay="overlay.png";

//check for files
if(!file_exists($background)||!file_exists($overlay))
die("no source images");

//get variables
$text=substr(trim($_GET['text']),0,10);
$angle=(float)trim($_GET['angle']);
if($angle<0)
$angle=0;
if($angle>359)
$angle=359;

//create image handle
switch(strtolower(substr($background,strrpos($background,".")+1)))
{
case "gif":
$im=imagecreatefromgif($background);
break;
case "jpg":
$im=imagecreatefromjpeg($background);
break;
case "jpeg":
$im=imagecreatefromjpeg($background);
break;
case "png":
$im=imagecreatefrompng($background);
break;
case "bmp":
$im=imagecreatefromwbmp($background);
break;
default:
die("unsupported file format");
}

//create overlay image handle
$im1=imagecreatefrompng($overlay);
imagesavealpha($im1,true);
//rotate overlay image
$im1=imRotate($im1,$angle);
//merge images
$left=(imagesx($im)-imagesx($im1))/2;
$top=(imagesy($im)-imagesy($im1))/2;
imagecopy($im,$im1,$left,$top,0,0,imagesx($im1),imagesy($im1));


//create text
$bbox=imageftbbox ( 25, $angle, "arial.ttf", $text);
$width=abs($bbox[4]-$bbox[0]);
$height=abs($bbox[1]-$bbox[5]);
imagettftext($im,25,$angle,(imagesx($im)-$width*cos(deg2rad($angle)))/2,(imagesy($im)+$height*sin(deg2rad($angle)))/2,imagecolorallocate($im,255,255,255),"arial.ttf",$text);

//output image at png format
header("Content-type: image/png");
imagepng($im);

//destroy images in memory
imagedestroy($im);
imagedestroy($im1);
?>
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить