【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();
        }
    }
}

  

 

posted @ 2021-02-07 09:48  emdzz  阅读(91)  评论(0编辑  收藏  举报