目录
一.创建窗体
可以使用JFrame的构造函数来创建的一窗体,并且我们可以在里面使用setTitle、setSize、setLayout、setVisible、setDefaultCloseOperation等方法来给窗体设置标题、给窗体设置大小、给窗口布局、给窗口设置可见......
二.创建两个面板
1.JPanel面板
JPanel面板依赖与窗体进行使用,面板只能放在窗体中使用,不能单独展示出来。JPanel和其它组件一样可以添加组件、设置布局、更改属性。我们可以创建JPanel面板来放置按钮,给窗体进行美化。
2.ImgPanel面板
ImgPanel面板是我们自己创建的面板类,用来放置图片,作为图片面板。
(这两个面板我们都可以用setBackground来设置面板的背景颜色,美化效果。)
创建窗体和两个面板的代码如下:
public void showUI(){ JFrame jf = new JFrame(); jf.setTitle("美颜相机v1"); jf.setSize(900,800); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setLocationRelativeTo(null); jf.setLayout(new BorderLayout()); //创建两个面板 JPanel btnJP = new JPanel(); btnJP.setBackground(Color.LIGHT_GRAY); //添加按钮 String[] btnStrs = {"打开","保存","撤回","原图","灰度","二值化","马赛克","原点马赛克","反片","老照片","油画","轮廓化"}; for(int i = 0;i <btnStrs.length;i++){ JButton btn = new JButton(btnStrs[i]); btnJP.add(btn); btn.addActionListener(il); //将按钮封装 if (i < 3){ btn.setActionCommand("FileOP"); }else { btn.setActionCommand("ImageFilterOP"); } } //使用自己创建的面板类 创建图像面板 ImgPanel imgJP = new ImgPanel(); imgJP.setBackground(Color.BLACK); jf.add(btnJP,BorderLayout.SOUTH); jf.add(imgJP,BorderLayout.CENTER); jf.setVisible(true); il.g = imgJP.getGraphics(); //将监听器中的动态数组传递到图像面板的动态数组中 imgJP.imgList2 = il.imgList; il.imgPanel = imgJP; }
三.添加动作监听器
在JPanel面板中,我们创建完按钮之后需要给按钮添加动作监听器,因此我们需要创建ImageListener类来继承接口。并且我们还需要在动作监听器里实现按钮的筛选。
在创建JPanel面板的时候,我们已经对按钮进行分装,将"打开","保存","撤回"这些文件处理类按钮封装到FileOP,将"原图","灰度","二值化","马赛克","原点马赛克","反片","老照片","油画","轮廓化"这些图像处理类按钮封装到ImageFilterOP。在这里我们就要调用这两个方法。
public class ImageListener implements ActionListener { //图像处理类对象 ImageFilter imgf = new ImageFilter(); Graphics g; int[][] imgArr; ArrayList<BufferedImage> imgList = new ArrayList<>(); ImgPanel imgPanel; @Override public void actionPerformed(ActionEvent e) { //获取按钮的ActionCommand String ac = e.getActionCommand(); System.out.println(ac); //获取按钮对象 JButton btn = (JButton) e.getSource(); //获取按钮上的文本 String op = btn.getText(); //调用文件操作方法 if (ac.equals("FileOP")) { fileOP(op); } else if (ac.equals("ImageFilterOP")) { //调用图像处理方法 ImageFilterOP(op); } //调用面板刷新 imgPanel.repaint(); } //定义一个文件操作方法 public void fileOP(String op){ if (op.equals("打开")) { //文件选择器 JFileChooser chooser = new JFileChooser(); //文件选择过滤器 将打开的目录下其他不需要的文件隐藏 FileNameExtensionFilter filter = new FileNameExtensionFilter( "JPG & PNG Images", "jpg", "jpeg", "png"); chooser.setFileFilter(filter); //打开文件选择对话框 int returnVal = chooser.showOpenDialog(null); //returnVal 获取关闭对话框时的状态信息 if (returnVal == JFileChooser.APPROVE_OPTION) { String filePath = chooser.getSelectedFile().getPath(); System.out.println("You chose to open this file: " + filePath); imgArr = imgf.getImagePixArr(filePath); } } //保存 if (op.equals("保存")){ //文件选择器 JFileChooser chooser = new JFileChooser(); //文件选择过滤器 将打开的目录下其他不需要的文件隐藏 FileNameExtensionFilter filter = new FileNameExtensionFilter( "JPG & PNG Images", "jpg", "jpeg", "png"); chooser.setFileFilter(filter); //打开文件保存对话框 int returnVal = chooser.showSaveDialog(null); //returnVal 获取关闭对话框时的状态信息 if (returnVal == JFileChooser.APPROVE_OPTION) { String filePath = chooser.getSelectedFile().getPath(); System.out.println("You chose to open this file: " + filePath); //根据选中的文件路径,创建一个File对象 File file = new File(filePath); if (imgList.size() <= 0){ JOptionPane.showMessageDialog(null,"没有可以保存的图片"); } int lastIndex = imgList.size() - 1; //取出最后一张图像文件 BufferedImage img = imgList.get(lastIndex); //将最后一张图像对象写入文件中 try { ImageIO.write(img,"PNG",file); } catch (IOException e) { throw new RuntimeException(e); } } } //撤回 if (op.equals("撤回")) { //判断数组中是否存有图片 if (imgList.size() <= 0) { JOptionPane.showMessageDialog(null, "没有可撤回的图片"); return; } //计算最后一张图片的下标 int lastIndex = imgList.size() - 1; //删除最后一张图片 imgList.remove(lastIndex); } } private void ImageFilterOP(String op) { if (imgArr == null) { JOptionPane.showMessageDialog(null, "请先选择一张图片"); return; } else if (op.equals("原图")) { BufferedImage img = imgf.drawImage01(imgArr); imgList.add(img); } else if (op.equals("灰度")) { BufferedImage img1 = imgf.drawImage02(imgArr); imgList.add(img1); } else if (op.equals("二值化")) { BufferedImage img1 = imgf.drawImage03(imgArr); imgList.add(img1); } else if (op.equals("马赛克")) { BufferedImage img1 = imgf.drawImage04(imgArr); imgList.add(img1); }else if (op.equals("原点马赛克")) { BufferedImage img1 = imgf.drawImage05(imgArr); imgList.add(img1); }else if (op.equals("反片")) { BufferedImage img1 = imgf.drawImage06(imgArr); imgList.add(img1); }else if (op.equals("老照片")) { BufferedImage img1 = imgf.drawImage07(imgArr); imgList.add(img1); }else if (op.equals("油画")) { BufferedImage img1 = imgf.drawImage08(imgArr); imgList.add(img1); }else if (op.equals("轮廓化")) { BufferedImage img1 = imgf.drawImage09(imgArr); imgList.add(img1); } } }
四.创建ImageFilter类
在这个ImageFilter类中,去读取图片的像素值,并保存到二维数组中,遍历二维数组,绘制图片,并进行重绘保存图片,以及给图片实现马赛克,灰度,油画等效果。
public class ImageFilter { //加载图片的方法 public int[][] getImagePixArr(String path){ File file = new File(path); try { BufferedImage img = ImageIO.read(file); int w = img.getWidth(); int h = img.getHeight(); int[][] imgArr = new int[w][h]; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { imgArr[i][j] = img.getRGB(i,j); } } return imgArr; } catch (IOException e) { throw new RuntimeException(e); } } //图片滤镜的方法 //原图 public BufferedImage drawImage01(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i++) { for (int j = 0; j < imgArr[i].length; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); bg.setColor(color); bg.fillRect(i,j,1,1); } } return img; } //灰度 public BufferedImage drawImage02(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img1 = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img1.getGraphics(); //将处理的像素绘制到缓存图像中 for (int i = 0; i < imgArr.length; i++) { for (int j = 0; j < imgArr[i].length; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); int gray = (red + green + blue) / 3; Color color1 = new Color(gray,gray,gray); bg.setColor(color1); bg.fillRect(i,j,1,1); } } return img1; } //二值化 public BufferedImage drawImage03(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img1 = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img1.getGraphics(); //将处理的像素绘制到缓存图像中 for (int i = 0; i < imgArr.length; i++) { for (int j = 0; j < imgArr[i].length; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); int gray = (red + green + blue) / 3; if (gray < 128){ bg.setColor(Color.BLACK); }else { bg.setColor(Color.WHITE); } bg.fillRect(i,j,1,1); } } return img1; } //马赛克 public BufferedImage drawImage04(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i+=10) { for (int j = 0; j < imgArr[i].length; j+=10) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); bg.setColor(color); bg.fillRect(i,j,10,10); } } return img; } //原点马赛克 public BufferedImage drawImage05(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i+=10) { for (int j = 0; j < imgArr[i].length; j+=10) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); bg.setColor(color); bg.fillOval(i,j,10,10); } } return img; } //反片 public BufferedImage drawImage06(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i++) { for (int j = 0; j < imgArr[i].length; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); Color color1 = new Color(255-red,255-green,255-blue); bg.setColor(color1); bg.fillRect(i,j,1,1); } } return img; } //老照片 public BufferedImage drawImage07(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i++) { for (int j = 0; j < imgArr[i].length; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); int nred = red+25; int ngreen = green+25; if(nred > 255)nred = 255; if(ngreen >255)ngreen =255; Color color1 = new Color(nred,ngreen,blue); bg.setColor(color1); bg.fillRect(i,j,1,1); } } return img; } //油画 public BufferedImage drawImage08(int[][] imgArr) { Random random = new Random(); //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length; i+=3) { for (int j = 0; j < imgArr[i].length; j+=3) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int w = random.nextInt(10) + 4; int h = random.nextInt(10) + 4; bg.setColor(color); bg.fillRect(i,j,w,h); } } return img; } //轮廓化 public BufferedImage drawImage09(int[][] imgArr) { //先创建一个空白的缓存图像 BufferedImage img = new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB); //获取图像的Graphics Graphics bg = img.getGraphics(); //将处理的像素都绘制的缓存图像中 for (int i = 0; i < imgArr.length-2; i++) { for (int j = 0; j < imgArr[i].length-2; j++) { int pixNum = imgArr[i][j]; Color color = new Color(pixNum); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); int gray = (red+green+blue) / 3; int rgb1 = imgArr[i + 2][j + 2]; Color color1 = new Color(rgb1); int red1 = color1.getRed(); int green1 = color1.getGreen(); int blue1 = color1.getBlue(); int gray1 = (red1+green1+blue1) / 3; if(Math.abs(gray1-gray) >10){ bg.setColor(Color.BLACK); }else{ bg.setColor(Color.WHITE); } bg.fillRect(i,j,1,1); } } return img; } }
五.创建ImgPanel类
创建ImgPanel类,实现图片居中显示
public class ImgPanel extends JPanel { ArrayList<BufferedImage> imgList2; @Override public void paint(Graphics g) { super.paint(g); //判断list中有无图片 if (imgList2.size() <= 0){ return; } //获取最后一张图片的下标 int lastIndex = imgList2.size() - 1; //获取图片 BufferedImage img = imgList2.get(lastIndex); //计算居中坐标 int x = (this.getWidth() - img.getWidth()) / 2; int y = (this.getHeight() - img.getHeight()) / 2; //绘制图片 g.drawImage(img,x,y,null); } }