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