Monday, 29 March 2010

Set Perspective of an Image Using PHP GD

To set the perspective of an image (i.e make one side appear further away from the other in a isosceles trapezoid)

You could use a library like ImageMagick but I personally think that installing too many libraries takes up too much memory and cpu so I wrote my own function.

To keep it looking smooth, it enlarges the image by 5 (see $mult) and copies each column to a new image at the required size. It then shrinks the image back down to the original size.

With bigger images you will need to set $mult to a smaller integer, as it could use a lot of memory but with smaller images it works fine



$i is the image to be manipulated
$gradient is the gradient as percentage - (0.01 - 0.99)
$rightdown if true the right hand side comes down otherwise the left side.
$background rgb background color 0xFFFFFF is white 0x000000 is black.

function perspective($i,$gradient=0.85,$rightdown=true,$background=0xFFFFFF) {
$mult=5;
$w=imagesx($i);
$h=imagesy($i);
$image=imagecreatetruecolor($w*$mult,$h*$mult);
imagecopyresized($image,$i,0,0,0,0,$w*$mult,$h*$mult,$w,$h);
imagedestroy($i);
$w*=$mult;
$h*=$mult;
$im=imagecreatetruecolor($w,$h);
$background=imagecolorallocate($im,($background>>16)&0xFF,($background>>8)&0xFF,$background&0xFF);
imagefill($im,0,0,$background);
imageantialias($im,true);
$nh=$h-($h*$gradient);
for ($x=0; $x<$w; $x++) {
 $ni=(($rightdown) ? $x : $w-$x);
 $p=intval($h-(($ni/$w)*$nh));
 if (($p%2)<>0)
  $p-=1;
 $nx=intval(($p-$h)/2);
 imagecopyresampled($im,$image,$x,0,$x,$nx,1,$p,1,$h-1);
 imageline($im,$x,0,$x,-$nx-1,$background);
 imageline($im,$x,$h-1,$x,$h+$nx,$background);
}
imagedestroy($image);
imagefilter($im,IMG_FILTER_SMOOTH,10);
$i=imagecreatetruecolor($w/$mult,$h/$mult);
imageantialias($i,true);
imagecopyresampled($i,$im,0,0,0,0,$w,$h,$w*$mult,$h*$mult);
imagedestroy($im);
return $i;
}

5 comments:

Anonymous said...

Nice post. I agree about not installing wasteful memory suckers.

Esteban said...

Thank you..this works for me. I tried to use Imagick. It has wonderful properties and not hard to learn.but not portable. Wants you to install.. Also you needs to find correct extensions for php . If your site is on a paid host. you have no chance to use it..So thank you very much. (I will extend and use this script to manipulate some Maps.. )

Anonymous said...

Very good post. I want to overlay some perspective text over an image that has a perspective view....can this be done?

James Cantrell said...

Yeah, its possible to overlay text before you do the perspective using

imagestring($image,4,0,0,$string,$text_color);

brindha said...

Man you r awesome ....

DoFollow Blog

Post a Comment

Why not leave a comment... What harm can it do?