之前我们了解过,所有呈现在屏幕上的图片,均由一个个带有颜色的像素点而组成。
而如今,给了你一张动漫图片,你如何获得你要的效果呢?
将彩图灰化,给图片加上马赛克,实现图片融合?
走过路过不错过,这些统统可实现 。
现在,我们就可以来试一试了。
1.建立一个窗口类,加上滤镜的按钮。
2.新建一个Fiter类,来写我们的滤镜方法。
第一步:写方法获取图片的信息(即那些像素点的颜色)。
public int[][] getpix(String path) {
File file = new File(path);
try {
BufferedImage buf = ImageIO.read(file);
int w = buf.getWidth();
int h = buf.getHeight();
int[][] imagearr = new int[w][h];
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
imagearr[i][j] = buf.getRGB(i, j);
}
}
return imagearr;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
A:首先,我们要明白获取信息后,是需要储存的,而有什么又会比二维数组更适合呢?
所以,我们创建一个返回值为二维数组的方法,方便之后赋值操作。
内部参数(path),指的是图片路径,供之后使用。
B:之后,得到你要的图片,再提取出信息。
用File类,得到图片。再用BufferedImage类,建立一个缓存图片, 得到图片的信息。
目的是,可以用BufferedImage的方法,获取宽,高,RGB值。
最后,用二维数组储存好我们的信息吧 。
第二步:写RGB值拆分方法。(之前提到了,可以去翻翻,给我加点浏览量!!!)
第三步:写灰化方法:
public void begray(Graphics g) {
int pix;
int[][] img = getpix("C:\\Users\\27259\\Desktop\\jieyi.png");
for (int i = 0; i < img.length; i++) {
for (int j = 0; j < img[i].length; j++) {
pix = img[i][j];
divide(pix);
gray = (int) (0.4 * red + 0.25 * green + 0.35 * blue);
Color cl = new Color(gray, gray, gray);
g.setColor(cl);
g.fillRect(300 + i, 300 + j, 1, 1);
}
}
}//灰化
A:创立二维数组,用getpix(path)得到图片信息。
B:遍历数组,上颜色,画实心矩形,宽高为1。(注意 gray = (int) (0.4 * red + 0.25 * green + 0.35 * blue)公式,前人幸苦得来,岂有不用之理?)
第四步:写马赛克化方法:
for (int i = 0; i < img.length; i += 5) {
for (int j = 0; j < img[i].length; j += 5) {
pix = img[i][j];
Color cl=new Color(pix);
g.setColor(cl);
g.fillRect(300 + i , 300 + j , 5, 5);
}
}
A:大致与灰化相同。
B:只用隔几个点才采取颜色。
C:画宽高为间距的实心矩形。
第五步:写图片融合方法:
A:大致与灰化方法一样,不过提取两张图片。
int[][] img1 = getpix("C:\\Users\\27259\\Desktop\\jieyi.jpg");
int[][] img2 = getpix("C:\\Users\\27259\\Desktop\\xuezhixia.png");
B:注意两图宽高的不同,取小值,防止越界。
C:判断pix大小,决定使用那张图片的颜色。
3.创建一个类(AC)实现 ActionListener,然后给在actionPerformed方法里,调用Fiter类里面的滤镜方法。
4.大功告成,快去整活!