5

我想实现一个使用倒立失真滤镜的应用程序。我正在使用here中的算法,它通过getPixel()和setpixel()方法更改像素位置。我的问题是Android设备的速度太慢,并且有些应用程序实现了相同的领域(和其他)过滤方式比我的方法更快。 (例如Picsay Pro应用程序)任何人都可以分享或指导寻找或实现快速失真算法。寻找快速图像失真算法

实际滤波器实现该算法:

public boolean sphereFilter(Bitmap b, boolean bSmoothing) 
{ 
    int nWidth = b.getWidth(); 
    int nHeight = b.getHeight(); 

    Point [][] pt = new Point[nWidth][nHeight]; 
    Point mid = new Point(); 
    mid.x = nWidth/2; 
    mid.y = nHeight/2; 

    double theta, radius; 
    double newX, newY; 

    for (int x = 0; x < nWidth; ++x) 
     for (int y = 0; y < nHeight; ++y) 
     { 
      pt[x][y]= new Point(); 
     } 

    for (int x = 0; x < nWidth; ++x) 
     for (int y = 0; y < nHeight; ++y) 
     { 
      int trueX = x - mid.x; 
      int trueY = y - mid.y; 
      theta = Math.atan2((trueY),(trueX)); 

      radius = Math.sqrt(trueX*trueX + trueY*trueY); 

      double newRadius = radius * radius/(Math.max(mid.x, mid.y)); 

      newX = mid.x + (newRadius * Math.cos(theta)); 

      if (newX > 0 && newX < nWidth) 
      { 
       pt[x][y].x = (int) newX; 
      } 
      else 
      { 
       pt[x][y].x = 0; 
       pt[x][y].y = 0; 
      } 

      newY = mid.y + (newRadius * Math.sin(theta)); 

      if (newY > 0 && newY < nHeight && newX > 0 && newX < nWidth) 
      {     
       pt[x][ y].y = (int) newY; 
      } 
      else 
      { 
       pt[x][y].x = pt[x][y].y = 0; 
      } 
     } 
    offsetFilterAbs(b, pt); 
    return true; 
} 

,它取代了计算出的像素位的代码。

public boolean offsetFilterAbs(Bitmap b, Point[][] offset) 
{ 
     int nWidth = b.getWidth(); 
     int nHeight = b.getHeight(); 

     int xOffset, yOffset; 

     for(int y=0;y < nHeight;++y) 
     { 
      for(int x=0; x < nWidth; ++x) 
      { 
       xOffset = offset[x][y].x; 
       yOffset = offset[x][y].y; 

       if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth) 
       { 
        b.setPixel(x, y, b.getPixel(xOffset, yOffset)); 
       }     
      }    
     } 

    return true; 
} 
+0

可能重复的[图像变形 - 凸起效果算法](http://stackoverflow.com/questions/5055625/image-warping-bulge-effect-algorithm) – 2011-04-04 19:03:26

+0

是的,它几乎是重复的,但请注意,对这个问题的接受答案是* not *真的是你想要的 - 你想要的是GLSL着色器。 – 2011-04-04 19:08:18

+0

@BlueRaja,我目前使用相同的算法与你的链接已经和它仍然太慢的Android设备 – Tony 2011-04-05 15:33:29

回答

5

我目前使用相同的算法与您的链接已经在一个,它仍然是Android设备

太慢从我link in the comments above

 
Given 
r = Sqrt((x - 0.5)^2 + (y - 0.5)^2) 
a = ArcTan2(y - 0.5, x - 0.5) 
n = Bulge factor (default = 1) 

Set 
x' = r^n * Cos(a) + 0.5 
y' = r^n * Sin(a) + 0.5 

(请记住,在此等式中,xy范围从0到1.如果您的尺寸范围从0到w,更换0.5w/2

使用a bit of math,我们可以看到,

 
Cos(a) = Cos(ArcTan2(y - 0.5, x - 0.5)) 
     = (x - 0.5)/r 
Sin(a) = Sin(ArcTan2(y - 0.5, x - 0.5)) 
     = (y - 0.5)/r 

这使得最终的结果方程

 
r = (x - 0.5)^2 + (y - 0.5)^2 
n = Bulge factor (default = 0) 

Set 
x' = r^n * (x - 0.5) + 0.5 
y' = r^n * (y - 0.5) + 0.5 

(我删除平方根,因为我们拿结果到一个实际的权力反正...所以真的要使这个等效,我们应该使用n/2而不是n,但si NCE我们定义“隆起的因素,”我们就可以离开了额外的部门)

由于只有乘法和一个真实幂的屈指可数,这可能是最快的,你可以期望得到的。

+1

+1我不打算回答这个问题,因为我的Android-fu是零。但是OP也许应该尝试对他的代码进行一些基本的分析,看看哪些是主要的时间消费者。或者消除多余的触发器就足够了。 – 2011-04-05 17:59:31

+0

@ belisarius我试图分析我的代码,并且这两个函数(计算新的x,y位置并替换它们)每个需要大约2000ms,这与“Picsay Pro”相比太差了。 – Tony 2011-04-06 12:51:23

+1

@Tony * Picsay Pro *可能会使用OpenGL ...并且不会创建数千个不必要的'Point'对象。 – 2011-04-06 16:28:50