質問
PHP-GDの画像に魚眼(またはバレル変換)効果を行う方法はありますか?私はこれをいくつかのコードで見つけましたが、PHPに移植するのに苦労しています。
解決
だが - GDとFastで可能です!! ImageMagickと比較してサイズの新しい画像を作成します (2*sourceWidth)/pi.
新しい画像の各ピクセルをトローして、中央から距離を見つけます。dソース= Hypot(x-centerx、y-centery)
ソース画像の対応する距離をbyで見つけます d運命。= 2*r*asin(dソース/r)/2
r 宛先画像の半分の幅です。
ベンチマークの例を参照してください: http://meindesign.net/picture2bubble/picture2bubble.php
function fisheye($infilename,$outfilename){
$im=imagecreatefrompng($infilename);
$ux=imagesx($im);//Source imgage width(x)
$uy=imagesy($im);//Source imgage height(y)
$umx=$ux/2;//Source middle
$umy=$uy/2;
if($ux>$uy)$ow=2*$uy/pi();//Width for the destionation image
else $ow=2*$ux/pi();
$out=imagecreatetruecolor($ow+1,$ow+1);
$trans=imagecolortransparent($out,ImageColorAllocate($out,0,0,0));
imagefill($im,1,1,$trans);
for($c=0;$c<imagecolorstotal($im);$c++){//Copy palette
$col=imagecolorsforindex($im,$c);
imagecolorset($out,$c,$col[red],$col[green],$col[blue]);
}
$om=$ow/2;//destination middle
for($x=0;$x<=$ow;++$x){//Loop X in destination image
for($y=0;$y<=$ow;++$y){//Loop y in destination image
$otx=$x-$om;//X in relation to the middle
$oty=$y-$om;//Y in relation to the middle
$oh=hypot($otx,$oty);//distance
$arc=(2*$om*asin($oh/$om))/(2);
$factor=$arc/$oh;
if($oh<=$om){//if pixle inside radius
$color=imagecolorat($im,round($otx*$factor+$umx),round($oty*$factor+$umy));
$r = ($color >> 16) & 0xFF;
$g = ($color >> 8) & 0xFF;
$b = $color & 0xFF;
$temp=imagecolorexact($out, $r, $g, $b);
imagesetpixel($out,$x,$y,$temp);
}
}
}
imagepng($out,$outfilename);
}
他のヒント
GDを使用したPHPは許容できる方法でそのようなことを行うことはできません。画像のピクセルごとの処理は本当に遅くなります...
Imagicicは、独自の表現を作成できる機能をサポートしています(fximage)、その後、すべてがImagicick内で内部で処理されます。
だから私はあなたがImagicickで要求したことをする方法を見つけました、私はからの表現をテイクしました 「Scott Builds Software」ブログ-ImagicickのFisheye Effect. 。彼のブログで表現の完全な説明を読むことができます。この機能のさらなるドキュメントは公式で入手できます ImageMagick サイト、あなたはそこであなた自身の表現を構築する方法をそこで学ぶことができます。
返品値に関するPHPドキュメントは間違っていることに注意してください。また、コメントしました。関数は実際のImagicickオブジェクトを返します。
これがあなたのコードです:
<?php
/* Create new object */
$im = new Imagick();
/* Create new checkerboard pattern */
$im->newPseudoImage(100, 100, "pattern:checkerboard");
/* Set the image format to png */
$im->setImageFormat('png');
/* Fill background area with transparent */
$trans = Imagick::VIRTUALPIXELMETHOD_TRANSPARENT;
$im->setImageVirtualPixelMethod($trans);
/* Activate matte */
$im->setImageMatte(true);
/* This is the expression that define how to do the fisheye effect */
$distort_expression =
'kk=w*0.5;
ll=h*0.5;
dx=(i-kk);
dy=(j-ll);
aa=atan2(dy,dx);
rr=hypot(dy,dx);
rs=rr*rr/hypot(kk,ll);
px=kk+rs*cos(aa);
py=ll+rs*sin(aa);
p{px,py}';
/* Perform the distortion */
$im = $im->fxImage($distort_expression);
/* Ouput the image */
header("Content-Type: image/png");
echo $im;
?>
とにかく、これはまだ遅いことを覚えておいてください、あなたがそれで何をしているのか注意してください...