图像特效------三角几何应用

来源:互联网 发布:php冒泡排序法从大到小 编辑:程序博客网 时间:2024/06/01 07:39

一:基本的三角函数知识


同样根据a, b的值可以计算出角度θ值,称之为反三角函数,角度θ=atan2(a, b)

图像处理中应用三角函数常常把中心点设置为A点,任意像素点B到A的距离可以根据三

角函数来计算得出,常见的计算模型如下:


对待求像素点加以一定三角函数变化,可以实现很多意想不到的图形特效,中心像素点可以

通过以下计算获得

int centerX = width/2;

int centerY = height/2;

扫描到的像素点p(x, y)可以基于 中心像素点,角度θ,两点之间距离Radius可以通过如

下计算获得:

int trueX = col -centerX;

int trueY = row -centerY;

theta = Math.atan2((trueY),(trueX));

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

二:特效原理

实现的特效很简单,上述的三角几何中计算结果中,有两个可以改变其值再重新计算坐标

P(x,y)。一个是角度,另外一个是半径距离,分别对角度与距离加以一定权重值计算,得到

如下两种特效:

1.  哈哈镜效果,主要是改变半径值,计算方法如下:

double newRadius = Math.sqrt(radius) * factor;

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

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

其中factor为输入参数

 

2.  中心螺旋效果,主要是改变角度θ的值,计算方法如下:

newX = centerX + (radius * Math.cos(theta+degree * radius));

newY = centerY + (radius * Math.sin(theta+degree * radius));

其中degree为输入参数.


三:程序效果

哈哈镜效果:


螺旋效果


两个滤镜程序的源代码如下:

1. Magic Mirror

[java] view plaincopy
  1. package com.process.blur.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4.   
  5. public class MagicMirrorFilter extends AbstractBufferedImageOp {  
  6.     private double factor = 15.0d; // default value  
  7.       
  8.     public MagicMirrorFilter() {  
  9.           
  10.     }  
  11.       
  12.     public MagicMirrorFilter(double factor) {  
  13.         this.factor = factor;  
  14.     }  
  15.   
  16.     public double getFactor() {  
  17.         return factor;  
  18.     }  
  19.   
  20.     public void setFactor(double factor) {  
  21.         this.factor = factor;  
  22.     }  
  23.   
  24.     @Override  
  25.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  26.         int width = src.getWidth();  
  27.         int height = src.getHeight();  
  28.   
  29.         if ( dest == null )  
  30.             dest = createCompatibleDestImage( src, null );  
  31.   
  32.         int[] inPixels = new int[width*height];  
  33.         int[] outPixels = new int[width*height];  
  34.         getRGB( src, 00, width, height, inPixels );  
  35.         int index = 0, outIndex = 0;  
  36.         int centerX = width/2;  
  37.         int centerY = height/2;  
  38.         double theta, radius;  
  39.         double newX, newY;  
  40.         int offsetX = 0, offsetY = 0;  
  41.         for(int row=0; row<height; row++) {  
  42.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  43.             for(int col=0; col<width; col++) {  
  44.   
  45.                 int trueX = col - centerX;  
  46.                 int trueY = row - centerY;  
  47.                 theta = Math.atan2((trueY),(trueX));  
  48.                 radius = Math.sqrt(trueX*trueX + trueY*trueY);  
  49.                 double newRadius = Math.sqrt(radius) * factor;  
  50.                 newX = centerX + (newRadius * Math.cos(theta));  
  51.                 newY = centerY + (newRadius * Math.sin(theta));  
  52.                   
  53.                 if (newX > 0 && newX < width) {  
  54.                     offsetX = (int)newX;  
  55.                 } else {  
  56.                     newX = 0;  
  57.                 }  
  58.                   
  59.                 if (newY > 0 && newY < height) {  
  60.                     offsetY = (int)newY;  
  61.                 } else {  
  62.                     newY = 0;  
  63.                 }  
  64.                   
  65.                 index = offsetY * width + offsetX;  
  66.                 ta = (inPixels[index] >> 24) & 0xff;  
  67.                 tr = (inPixels[index] >> 16) & 0xff;  
  68.                 tg = (inPixels[index] >> 8) & 0xff;  
  69.                 tb = inPixels[index] & 0xff;  
  70.                   
  71.                 // use newX, newY and fill the pixel data now...  
  72.                 outIndex = row * width + col;  
  73.                 outPixels[outIndex] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  74.             }  
  75.         }  
  76.   
  77.         setRGB( dest, 00, width, height, outPixels );  
  78.         return dest;  
  79.     }  
  80.   
  81. }  
2. Swirl
[java] view plaincopy
  1. package com.process.blur.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4.   
  5. public class SwirlFilter extends AbstractBufferedImageOp{  
  6.   
  7.     // recommended scope is [0.1 ~ 0.001]  
  8.     private double degree = 0.02d; // default value,   
  9.       
  10.     public SwirlFilter() {  
  11.           
  12.     }  
  13.       
  14.     public double getDegree() {  
  15.         return degree;  
  16.     }  
  17.   
  18.     public void setDegree(double degree) {  
  19.         this.degree = degree;  
  20.     }  
  21.   
  22.     @Override  
  23.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  24.         int width = src.getWidth();  
  25.         int height = src.getHeight();  
  26.   
  27.         if ( dest == null )  
  28.             dest = createCompatibleDestImage( src, null );  
  29.   
  30.         int[] inPixels = new int[width*height];  
  31.         int[] outPixels = new int[width*height];  
  32.         getRGB( src, 00, width, height, inPixels );  
  33.         int index = 0, outIndex = 0;  
  34.         int centerX = width/2;  
  35.         int centerY = height/2;  
  36.         double theta, radius;  
  37.         double newX, newY;  
  38.         int offsetX = 0, offsetY = 0;  
  39.         for(int row=0; row<height; row++) {  
  40.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  41.             for(int col=0; col<width; col++) {  
  42.   
  43.                 int trueX = col - centerX;  
  44.                 int trueY = row - centerY;  
  45.                 theta = Math.atan2((trueY),(trueX));  
  46.                 radius = Math.sqrt(trueX*trueX + trueY*trueY);  
  47.                   
  48.                 // the top trick is to add (degree * radius), generate the swirl effect...  
  49.                 newX = centerX + (radius * Math.cos(theta + degree * radius));  
  50.                 newY = centerY + (radius * Math.sin(theta + degree * radius));  
  51.                   
  52.                 if (newX > 0 && newX < width) {  
  53.                     offsetX = (int)newX;  
  54.                 } else {  
  55.                     offsetX = col;  
  56.                 }  
  57.                   
  58.                 if (newY > 0 && newY < height) {  
  59.                     offsetY = (int)newY;  
  60.                 } else {  
  61.                     offsetY = row;  
  62.                 }  
  63.                   
  64.                 index = offsetY * width + offsetX;  
  65.                 ta = (inPixels[index] >> 24) & 0xff;  
  66.                 tr = (inPixels[index] >> 16) & 0xff;  
  67.                 tg = (inPixels[index] >> 8) & 0xff;  
  68.                 tb = inPixels[index] & 0xff;  
  69.                   
  70.                 // use newX, newY and fill the pixel data now...  
  71.                 outIndex = row * width + col;  
  72.                 outPixels[outIndex] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  73.             }  
  74.         }  
  75.   
  76.         setRGB( dest, 00, width, height, outPixels );  
  77.         return dest;  
  78.     }  
  79.   
  80. }  
0 0
原创粉丝点击