【问题标题】:How to create a fisheye effect with PHP GD如何使用 PHP GD 创建鱼眼效果
【发布时间】:2011-05-22 22:13:59
【问题描述】:

有没有办法使用 PHP-GD 对图像进行 FishEye(或桶形变换)效果? 我用一些代码找到了这个,但我很难将它移植到 PHP。

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

【问题讨论】:

  • 你要么必须直接实现鱼眼算法本身,这将是 SLOOOWWWW。或者找到其他方法来做到这一点。比如用exec()之类的macro'n进入photoshop...我不知道有谁做过这个...
  • 如果您有 C 编程知识,您可以下载 gd 源代码并实现新功能 - 并发布!那个代码太旧了......无论如何,如果你找到解决方案,请发布!我也很想知道......顺便说一句,你的操作系统是什么?
  • 这是可行的,但它比 MATLAB 代码更复杂。 PHP 不适合字节算术,您可能需要一个 3 层数组(R、G、B)。所以我也建议诉诸exec(imagemagick)
  • 我知道ImageMagick 6.4.x 版本有这样的过滤器,但我的主机上没有。所以我必须想办法用 PHP 做到这一点。但似乎 MATLAB 可以用比 PHP 更少的代码来做到这一点。

标签: php gd fisheye


【解决方案1】:

带有 GD 的 PHP 无法以可接受的方式做这样的事情,逐像素处理图像会非常慢...

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

无论如何,请记住,这仍然很慢,无论你做什么都要小心......

【讨论】:

  • 非常感谢!你是我的英雄! :D
【解决方案2】:

但是 - 与 ImageMagick 相比
创建一个大小为 (2*SourceWidth)/PI 的新图像。
遍历新图像的每个像素并找到与中心的距离。 d来源=hypot(x-centerX,y-centerY)
通过ddest.=2*r*asin(dsource/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);
     }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    相关资源
    最近更新 更多