## 美颜相机
实现美颜相机,我们一共需要三个类
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 blocke.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;}}