Java学习——美颜相机3.0

目录

一.创建窗体

二.创建两个面板

1.JPanel面板

2.ImgPanel面板

三.添加动作监听器

四.创建ImageFilter类

 五.创建ImgPanel类


一.创建窗体

可以使用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);

    }
}

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。针对USB接口程序设计,我们需要先了解一些基础知识: 1. USB是什么? USB(Universal Serial Bus)是一种用于连接计算机与外部设备的串行总线标准,可用于数据传输、充电和供电等多种用途。 2. USB接口类型 USB接口按照接口类型分为USB Type-A、USB Type-B、mini-USB、micro-USB等多种类型。 3. USB接口规范 USB接口规范包括USB1.0、USB2.0、USB3.0等多个版本,每个版本都有自己的传输速度和功能特性。 在了解了上述基础知识后,我们可以开始设计USB接口程序。具体步骤如下: 1. 定义一个接口类Usb,在该类中定义一个抽象方法,用于实现数据传输功能。 ```java public interface Usb { void transferData(); } ``` 2. 定义一个USB设备类,该类实现了Usb接口,并实现了接口中的抽象方法,用于实现具体的数据传输功能。 ```java public class UsbDevice implements Usb { @Override public void transferData() { System.out.println("USB设备传输数据"); } } ``` 3. 定义一个主机类,该类也实现了Usb接口,但是该类的transferData方法中不是实现传输数据的功能,而是调用USB设备类的transferData方法,从而实现数据传输。 ```java public class Host implements Usb { private Usb usbDevice; public Host(Usb usbDevice) { this.usbDevice = usbDevice; } @Override public void transferData() { usbDevice.transferData(); } } ``` 4. 在主函数中实例化USB设备类和主机类,并调用主机类的transferData方法,从而实现数据传输。 ```java public static void main(String[] args) { UsbDevice usbDevice = new UsbDevice(); Host host = new Host(usbDevice); host.transferData(); } ``` 这样,我们就完成了一个简单的USB接口程序设计。当然,实际情况中,USB接口程序可能会更加复杂,需要考虑更多的因素,例如不同类型的USB接口、不同版本的USB规范等等。同时,我们还需要注意USB接口程序的稳定性和可靠性,以确保程序的正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值