主要思想:
主要是利用三角正弦函数与余弦函数的变换效果,完成对像素的位移变换,产生
水纹效果,因为自然界中的水纹多少都是正弦波或者余弦波的叠加效果。
参数解析:
支持两个输入参数设置,一个是波长,表示像素位移的多少,另外一个是周期
表示正弦或者余弦函数的在像素中的变换周期。
关键程序解析:
计算位移与周期变化代码如下:
xoffset = (int)((double)wave * Math.sin(2.0 * Math.PI * (float)row / period));
yoffset = (int)((double)wave * Math.cos(2.0 * Math.PI * (float)col / period));
程序效果:
程序源代码:
package com.gloomyfish.filter.study;
import java.awt.image.BufferedImage;
public class WaterFilter extends AbstractBufferedImageOp {
private double wave;
private double period;
public WaterFilter() {
wave = 25.0;
period = 128;
}
public void setPeriod(double period) {
this.period = period;
}
public void setWave(double nWave) {
this.wave = nWave;
}
@Override
public BufferedImage filter(BufferedImage src, BufferedImage dest) {
int width = src.getWidth();
int height = src.getHeight();
if ( dest == null )
dest = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
Point[][] ssPixels = new Point[height][width];
getRGB( src, 0, 0, width, height, inPixels );
int index = 0, index2 = 0;
int xoffset = 0, yoffset = 0;
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
xoffset = (int)((double)wave * Math.sin(2.0 * Math.PI * (float)row / period));
yoffset = (int)((double)wave * Math.cos(2.0 * Math.PI * (float)col / period));
xoffset = xoffset + col;
yoffset = yoffset + row;
if(xoffset < 0 || xoffset >=width) {
xoffset = 0;
}
if(yoffset < 0 || yoffset >=height) {
yoffset = 0;
}
// save the 2D coordinate newX, and newY
ssPixels[row][col] = new Point(xoffset, yoffset);
}
}
// coordinate 2D result and fill the pixels data.
for(int row=0; row<height; row++) {
int ta = 0, tr = 0, tg = 0, tb = 0;
for(int col=0; col<width; col++) {
index = row * width + col;
index2 = ssPixels[row][col].getRow() * width + ssPixels[row][col].getCol();
ta = (inPixels[index2] >> 24) & 0xff;
tr = (inPixels[index2] >> 16) & 0xff;
tg = (inPixels[index2] >> 8) & 0xff;
tb = inPixels[index2] & 0xff;
outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
}
}
setRGB( dest, 0, 0, width, height, outPixels );
return dest;
}
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getRow() {
return this.y;
}
public int getCol() {
return this.x;
}
}
}
转载文章请注明出自本博客