## 美颜相机
实现美颜相机,我们一共需要三个类
1、UI界面类
2、事件监听器
3、封装方法,直接调用的类
1、UI界面类ImageUI
如果我们一个一个加上按钮会进行大量的复制粘贴工作,所以我们用循环遍历写一个方法直接调用
public void addButton() {
String[] btnstrs= {"原图","马赛克","底片","灰度","轮廓提取","美白","油画","温暖","梦幻","二值化","撤回"};
for(int i=0;i<btnstrs.length;i++) {
String btnstr=btnstrs[i];
JButton btn =new JButton(btnstr);
add(btn);
btn.addActionListener(imglisten);
}
写界面初始化的方法,创立一些基本属性
public void initUI() {
setTitle("图像处理");
setSize(800,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
//布局
FlowLayout flow=new FlowLayout();
setLayout(flow);
//调用加上按钮的方法
addButton();
setVisible(true);
//从监听器上获取画笔
imglisten.g=getGraphics();
}
JFrame中自带的paint方法会让窗体在改变时自动重绘,导致我们图片的丢失,所以这里重写一下paint方法,让每次重绘的时候图片也重绘
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i<imglisten.bfimgSize;i++) {
System.out.println("刷新"+i);
BufferedImage buffimg=imglisten.buffimgList[i];
g.drawImage(buffimg,100,100,null);
}
}
2、事件监听器类ImageListener
不要忘记在UI类中加上事件监听器类
ImageListener imglisten=new ImageListener();
在事件监听器中,我们需要实现ActionListener接口,声明画笔与封装方法类,需要使用的储存像素的数组,写一些方法去调用
public class ImageListener implements ActionListener{
//需要调用封装方法类的许多方法
//声明区:
Graphics g=null;
ImageEff imgeff=new ImageEff();
int[][] imgarr;
public ImageListener() {
String ImagPath01="C:\\Users\\86158\\Desktop\\微信图片_20220123111425.jpg";
// String ImagPath02=" ";
imgarr=imgeff.getImagePixArray(ImagPath01);
}
{
System.out.println("daimakuai");
}
//声明一下存图片的数组
BufferedImage[] buffimgList=new BufferedImage[200];
int bfimgSize=0;
下面是实现接口中的方法,复制过来,并写上方法体
(其中的img是之后封装方法类里面的返回值,为了在改变窗体时图片不丢失,也为了撤回按键的实现,把返回值存入一个数组,不丢失)
public void actionPerformed(ActionEvent e) {
String btnstr=e.getActionCommand();
System.out.println("点击了"+btnstr);
if(btnstr.equals("原图")) {
BufferedImage img=imgeff.drawImage_01(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("马赛克")) {
BufferedImage img=imgeff.drawImage_02(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("底片")) {
BufferedImage img=imgeff.drawImage_03(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("灰度")) {
BufferedImage img=imgeff.drawImage_04(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("轮廓提取")) {
BufferedImage img=imgeff.drawImage_05(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("美白")) {
BufferedImage img=imgeff.drawImage_06(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("油画")) {
BufferedImage img=imgeff.drawImage_07(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}
else if(btnstr.equals("温暖")) {
BufferedImage img=imgeff.drawImage_08(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("梦幻")) {
BufferedImage img=imgeff.drawImage_09(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("二值化")) {
BufferedImage img=imgeff.drawImage_10(imgarr,g);
buffimgList[bfimgSize]=img;
bfimgSize++;
}else if(btnstr.equals("撤回")) {
for(int i=0;i<bfimgSize-1;i++) {
System.out.println("刷新"+i);
BufferedImage buffimg=buffimgList[i];
g.drawImage(buffimg, 100, 100, null);
}
}
}
3、封装方法类 ImageEff
创建一个缓冲图片,把缓冲图片的每个像素点的颜色遍历,读取到一个二维数组,并返回,下面的处理方法需要使用
public int[][] getImagePixArray(String path){
File file=new File(path);
BufferedImage buffimg=null;
try {
buffimg=ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int w=buffimg.getWidth();
int h=buffimg.getHeight();
int[][] imgarr=new int[w][h];
for(int i=0;i<w;i++) {
for(int j=0;j<h;j++) {
imgarr[i][j]=buffimg.getRGB(i, j);
}
}return imgarr;
}
为了解决一个一个画像素点,绘图速度慢的问题,我们调用drawImage方法,直接把img相关属性写好,一次画一张缓冲图片
下面是一些滤镜实现的算法
//原图
public BufferedImage drawImage_01(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
img.setRGB(i, j, rgb);
/* Color color=new Color(rgb);
g.setColor(color);
g.fillRect(100+i, 100+j, 1, 1);*/
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//马赛克
public BufferedImage drawImage_02(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i+=10) {
for(int j=0;j<imgarr[0].length;j+=10) {
int rgb=imgarr[i][j];
img.setRGB(i, j, rgb);
Color color=new Color(rgb);
g.setColor(color);
g.fillRect(100+i, 100+j, 10, 10);
}
}
return img;
}
//底片
public BufferedImage drawImage_03(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue =color.getBlue();
Color ncolor=new Color(255-red,255-green,255-blue);
int n=ncolor.getRGB();
/* Color color=new Color(rgb);
g.setColor(color);
g.fillRect(100+i, 100+j, 1, 1);*/
img.setRGB(i, j, n);
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//灰度
public BufferedImage drawImage_04(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue =color.getBlue();
int grey=(red+blue+green)/3;
Color ncolor=new Color(grey,grey,grey);
int n=ncolor.getRGB();
/* g.setColor(color);
g.fillRect(100+i, 100+j, 1, 1);*/
img.setRGB(i, j, n);
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//轮廓提取
public BufferedImage drawImage_05(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length-2;i++) {
for(int j=0;j<imgarr[0].length-2;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue =color.getBlue();
int grey=(red+blue+green)/3;
int nrgb=imgarr[i+2][j+2];
Color ncolor=new Color(nrgb);
int nred=ncolor.getRed();
int ngreen=ncolor.getGreen();
int nblue =ncolor.getBlue();
int ngrey=(nred+nblue+ngreen)/3;
if(Math.abs(grey-ngrey)>15) {
Color B=new Color(0,0,0);
int n=B.getRGB();
img.setRGB(i, j, n);
}else {
Color B=new Color(225,225,225);
int n=B.getRGB();
img.setRGB(i, j, n);
}
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//美白
public BufferedImage drawImage_06(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue =color.getBlue();
int grey=(red+blue+green)/3;
int nred=red>220?250:red+30;
int nblue=blue>220?250:blue+30;
int ngreen=green>220?250:green+30;
Color ncolor=new Color(nred,ngreen,nblue);
if(grey<100) {
int n=color.getRGB();
img.setRGB(i, j, n);
}else {
int n=ncolor.getRGB();
img.setRGB(i, j, n);
}
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//油画?(不知道怎么setRGB这一步,所以油画返回的img是什么?应该也没有问题)
public BufferedImage drawImage_07(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i+=5) {
for(int j=0;j<imgarr[0].length;j+=5) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
Random random=new Random();
int ran=random.nextInt(20)+5;
g.setColor(color);
g.fillOval(100+i, 100+j, ran, ran);
}
}
return img;
}
//温暖
public BufferedImage drawImage_08(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue=color.getBlue();
Color warmness=new Color(red,green,blue/3);
int warm=warmness.getRGB();
img.setRGB(i, j, warm);
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//梦幻
public BufferedImage drawImage_09(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue=color.getBlue();
Color warmness=new Color(red,green*2/3,blue);
int warm=warmness.getRGB();
img.setRGB(i, j, warm);
}
}
g.drawImage(img, 100, 100,null);
return img;
}
//整理到此处!!!二值化
public BufferedImage drawImage_10(int[][]imgarr,Graphics g) {
BufferedImage img=new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr[0].length;j++) {
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int green=color.getGreen();
int blue =color.getBlue();
int grey=(red+blue+green)/3;
if(grey<125) {
Color B=new Color(0,0,0);
int n=B.getRGB();
img.setRGB(i, j, n);
}else {
Color B=new Color(255,255,255);
int n=B.getRGB();
img.setRGB(i, j, n);
}
}
}
g.drawImage(img, 100, 100,null);
return img;
}
}