2010-12-09 31 views
5

有沒有辦法在PHP-GD上對圖像進行FishEye(或桶形轉換)效果? 我發現這與一些代碼,但我很難將其移植到PHP。如何用PHP創建魚眼效果GD

How can I implement a fisheye lens effect (barrel transformation) in MATLAB?

+0

你要麼必須直接實現魚眼ALGO本身,這將是SLOOOWWWW。或者找到其他方式來做到這一點。比如macro'n into exec with exec()或者類似的東西......我不知道有誰這樣做過...... – DampeS8N 2010-12-09 15:22:06

+0

如果你有C編程知識,你可以下載* gd *源代碼並實現一個新功能 - 併發布!這段代碼太舊了......無論如何,如果你找到一個解決方案,請發佈它!我也很想知道...... Btw什麼是您的操作系統? – 2010-12-09 15:36:32

回答

2

但是 - 這是可能的GD和快!與ImageMagick比較
enter image description here 創建一個尺寸爲(2 * SourceWidth)/ PI的新圖像。
步行穿過新圖像的每個像素並找到距中心的距離。 d = hypot將(X-的centerX,γ-centerY)
通過 d DEST查找所述源圖像中的對應距離。 = 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); 
    } 
6

PHP與GD不能做到以可接受的方式這樣的事情,處理圖像逐像素將是很慢...

Imagick不支持的功能,使你可以編寫自己的表達式(fximage),之後所有內容都將在Imagick內部處理。

所以我找到了一種方法去做你在Imagick所要求的,我從"Scott builds Software" blog - fisheye effect in imagick中提取了表達式。你可以在他的博客中閱讀表達的完整解釋。官方ImageMagick網站提供了該功能的更多文檔,您可以在此瞭解如何構建自己的表達式。

請注意關於返回值的PHP文檔不正確,我也在那裏評論。該函數返回實際的Imagick對象。

因此,這裏是你的代碼:

<?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; 
?> 

無論如何,請記住,這是仍然緩慢,小心,不管你與做...