如何使用PHP GD创建鱼眼效果

如何使用PHP GD创建鱼眼效果,php,gd,fisheye,Php,Gd,Fisheye,有没有办法用PHP-GD对图像进行鱼眼(或桶变换)效果? 我通过一些代码发现了这一点,但我很难将其移植到PHP 使用GD的PHP无法以可接受的方式完成这样的事情,逐像素处理图像将非常缓慢 Imagick确实支持一个函数,使您能够编写自己的表达式(),之后所有内容都将在Imagick内部处理 所以我找到了一种方法来满足你在Imagick中的要求,我从。你可以在他的博客上看到这个表达的完整解释。有关此函数的更多文档可在官方网站上获得,您可以在那里了解如何构建自己的表达式 请注意,关于返回值的PHP文

有没有办法用PHP-GD对图像进行鱼眼(或桶变换)效果? 我通过一些代码发现了这一点,但我很难将其移植到PHP


使用GD的PHP无法以可接受的方式完成这样的事情,逐像素处理图像将非常缓慢

Imagick确实支持一个函数,使您能够编写自己的表达式(),之后所有内容都将在Imagick内部处理

所以我找到了一种方法来满足你在Imagick中的要求,我从。你可以在他的博客上看到这个表达的完整解释。有关此函数的更多文档可在官方网站上获得,您可以在那里了解如何构建自己的表达式

请注意,关于返回值的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;
?>

无论如何,请记住,这仍然是缓慢的,无论你用它做什么,都要小心…

但是-使用GD和fast是可能的!!与ImageMagick相比
创建一个大小为(2*SourceWidth)/PI的新图像。
走遍新图像的每个像素,找出距离中心的距离。 dsource=hypot(x-centerX,y-centerY)
通过dTest.=2*r*asin(dsource/r)/2查找源图像中的相应距离
r是目标图像的一半宽度。
参见基准点示例:

函数鱼眼($infilename,$outfilename){
$im=imagecreatefrompng($infilename);
$ux=imagesx($im);//源图像宽度(x)
$uy=imagesy($im);//源图像高度(y)
$umx=$ux/2;//源代码
$umy=$uy/2;
如果($ux>$uy)$ow=2*$uy/pi();//目标图像的宽度
else$ow=2*$ux/pi();
$out=ImageCreateTureColor($ow+1,$ow+1);
$trans=imagecolortransparent($out,ImageColorAllocate($out,0,0,0));
图像填充($im,1,1,$trans);
对于($c=0;$c 8)&0xFF;
$b=$color&0xFF;
$temp=imagecolorexact($out,$r,$g,$b);
imagesetpixel($out,$x,$y,$temp);
}
}
}
imagepng($out,$outfilename);
}

您要么直接实现鱼眼算法本身,这将是缓慢的。或者找到其他方法来实现这一点。例如,使用exec()等将宏n导入photoshop。。。我不知道有谁做过这件事……如果你有C编程知识,你可以下载gd源代码并实现一个新特性——然后发布它!那个密码太旧了。。。无论如何,如果你找到了解决方案,请发布它!我也很想知道。。。顺便说一句,你的操作系统是什么?这是可行的,但它比MATLAB代码更复杂。PHP不太适合字节运算,您可能需要一个3层数组(R、G、B)。因此,我还建议使用
exec(imagemagick)
。我知道6.4.x版本的imagemagick有这样的过滤器,但主机上没有。所以我必须找到一种用PHP实现这一点的方法。但是看起来MATLAB比PHP用更少的代码就可以做到这一点。非常感谢!你是我的英雄D
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);
     }