• 【Java-GUI】06 绘图 Part2 位图处理


    绘画程序案例:

    原视频排错找了半天,原来是变量名的问题

    package cn.dzz;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    
    public class Sketchpad {
        // 窗体对象
        private Frame frame = new Frame();
        // 画板宽高
        private final int WIDTH = 500;
        private final int HEIGHT = 400;
    
        private PopupMenu popupMenu = new PopupMenu();
        private MenuItem redMenuItem = new MenuItem("red");
        private MenuItem greenMenuItem = new MenuItem("green");
        private MenuItem blueMenuItem = new MenuItem("blue");
    
        // 定义一个变量记录画笔的颜色
        private Color localColor = Color.BLACK;
    
        // 缓冲图像对象
        BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    
        // 获取图形对象
        Graphics graphics = bufferedImage.getGraphics();
    
        // 自定义一个Canvas画布类
        class DrawingBoard extends Canvas {
            @Override
            public void paint(Graphics g) {
                // super.paint(g);
                g.drawImage(bufferedImage, 0, 0, null);
            }
        }
        Canvas canvas = new DrawingBoard();
    
        // 缓冲光标的坐标值
        private int buffLocationX = -1;
        private int buffLocationY = -1;
    
        public void init() {
            ActionListener actionListener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String actionCommand = e.getActionCommand();
                    switch (actionCommand) {
                        case "red" :
                            localColor = Color.RED;
                            break;
                        case "green" :
                            localColor = Color.GREEN;
                            break;
                        case "blue" :
                            localColor = Color.BLUE;
                            break;
                    }
                }
            };
    
            redMenuItem.addActionListener(actionListener);
            greenMenuItem.addActionListener(actionListener);
            blueMenuItem.addActionListener(actionListener);
    
            popupMenu.add(redMenuItem);
            popupMenu.add(greenMenuItem);
            popupMenu.add(blueMenuItem);
    
    
            canvas.add(popupMenu);
            canvas.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseReleased(MouseEvent e) {
                    //super.mouseReleased(e);
                    boolean popupTrigger = e.isPopupTrigger();
                    if (popupTrigger) {
                        popupMenu.show(canvas, e.getX(), e.getY());
                    }
    
                    // 刷新坐标
                    buffLocationX = -1;
                    buffLocationY = -1;
                }
            });
    
            // 设置背景白色
            graphics.setColor(Color.WHITE);
            graphics.fillRect(0,0, WIDTH, HEIGHT);
    
            // 通过监听鼠标行为实现绘画功能
            canvas.addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    //super.mouseDragged(e);
    
                    if (buffLocationX > 0 && buffLocationY > 0) {
                        graphics.setColor(localColor);
                        graphics.drawLine(buffLocationX, buffLocationY, e.getX(), e.getY());
                    }
    
                    // 将缓冲的坐标更新到鼠标释放后的位置
                    buffLocationX = e.getX();
                    buffLocationY = e.getY();
    
                    // 刷新画布
                    canvas.repaint();
                }
            });
    
            canvas.setPreferredSize(new Dimension(WIDTH, HEIGHT));
            frame.add(canvas);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            new Sketchpad().init();
        }
    }
    

    演示效果:

    ImageIO的使用

    static BufferedImage read(File input)
    static BufferedImage read(InputStream input)
    static boolean write(RenderedImage im, String formatName, File)

    案例:

    package cn.dzz;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    public class ImageCheck {
    
        private Frame frame = new Frame("图片查看器");
    
        // 菜单组件
        MenuBar menuBar = new MenuBar();
        Menu fileMenu = new Menu("file");
        MenuItem openMenuItem = new MenuItem("open image");
        MenuItem saveMenuItem = new MenuItem("save as ...");
    
        // 展示图片的画布组件, 根据IO对象的调用方式猜测是一个封装二进制流的对象
        BufferedImage buffImage;
    
        class DisplayUnit extends Canvas {
            @Override
            public void paint(Graphics g) {
                // super.paint(g);
                g.drawImage(buffImage, 0, 0, null);
            }
        }
        Canvas canvas = new DisplayUnit();
    
        public void init() throws Exception {
            // 组装视图
            fileMenu.add(openMenuItem);
            fileMenu.add(saveMenuItem);
            menuBar.add(fileMenu);
            frame.setMenuBar(menuBar);
            frame.add(canvas);
    
            // 菜单的事件处理
            openMenuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 打开文件对话框并且可见
                    FileDialog fileDialog = new FileDialog(frame, "open img file", FileDialog.LOAD);
                    fileDialog.setVisible(true);
    
                    // 获取文件坐标
                    String directory = fileDialog.getDirectory();
                    String file = fileDialog.getFile();
    
                    // 使用图片IO对象根据文件坐标读取,加载到buffImage对象中
                    try {
                        buffImage = ImageIO.read(new File(directory + file));
                        // 画布对象就可以根据buffImage对象渲染出来画面了
                        canvas.repaint();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            });
            saveMenuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 打开文件对话框并且可见
                    FileDialog fileDialog = new FileDialog(frame, "save img file", FileDialog.SAVE);
                    fileDialog.setVisible(true);
    
                    // 获取保存文件坐标
                    String directory = fileDialog.getDirectory();
                    String file = fileDialog.getFile();
                    // 获取后缀名的方法 这里存在的问题是如果格式后缀一定要写,如果不写就是无法写入到硬盘中(或者就是硬编码写死在方法的参数中)
                    String suffix = file.substring(file.lastIndexOf(".") + 1);
    
                    try {
                        // 格式名称是取文件的后缀
                        ImageIO.write(buffImage, suffix, new File(directory + file));
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            });
    
            // 位置,大小,可见,可关闭
            frame.setBounds(200,200,704,508);
            frame.setVisible(true);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    // super.windowClosing(e);
                    System.exit(0);
                }
            });
        }
    
        public static void main(String[] args) {
            try {
                new ImageCheck().init();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

      

  • 相关阅读:
    扩展GridView控件增加选择列
    Flash图片轮换/切换左右推拉效果
    Flash图片轮换/切换普通效果1
    WebForm_PostBackOptions未定义 解决方法
    SQL Server 2008无法还原日志备份或差异备份的问题解决(转)
    一个简单的C#多线程间同步的例子.[转]
    SQL2008报错:无法还原日志备份或差异备份,因为没有文件可用于前滚(转)
    C# 字符、字符串过滤,只能输入数字、中文、英文、大写、小写(转)
    C# Monitor类锁定对象
    使用SqlServer中的float类型时发现的问题(转)
  • 原文地址:https://www.cnblogs.com/mindzone/p/14380949.html
Copyright © 2020-2023  润新知