1. 程式人生 > >Java在JPanel中自由繪圖,並將繪圖儲存為jpg檔案

Java在JPanel中自由繪圖,並將繪圖儲存為jpg檔案

在JPanel中繪圖,並利用ImageIO將JPanel儲存為圖片時,往往只儲存一個空白的JPanel,使用者所繪製的圖形往往不能正確儲存,查了很多資料說是要呼叫paintComponent方法而不是paint方法,但是這裡強調的事自由繪圖,而不是畫好圖然後呈現出來。

下面一小段程式是將一個Jpanel儲存為圖片的正常思路,但在自由繪圖時,這個程式只儲存一個空白的JPanel。


public boolean savePanelAsJpg(File file, DrawPanel panel) {
    Dimension imageSize = panel.getSize();
    BufferedImage image = new BufferedImage(imageSize.width,imageSize.height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics = image.createGraphics();
    panel.paint(graphics);
    graphics.dispose();
    try {
        ImageIO.write(image, "jpg", file);
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}
要想將使用者的自由繪圖儲存,換一種思路也許很簡單,抓屏,沒錯,Java的一個類Robot提供了抓屏的功能,使用Robot抓屏時可以抓取指定的矩形區域,也可以抓取一個控制元件,當然是提供控制元件的座標位置和大小。下面是Robot的使用方法,直接返回一個BufferedImage物件。
//可以指定要抓取的區域
BufferedImage screencapture = new Robot().createScreenCapture(
	new Rectangle( 15, 15, 150, 150));
		
//可以抓取指定控制元件:
BufferedImage image = new Robot().createScreenCapture( 
	new Rectangle( jFrame.getX(), jFrame.getY(), jFrame.getWidth(), jFrame.getHeight() ) );

下面是一個使用Jpanel繪圖並儲存為jpg檔案的完整例子。
package cvts;

import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class DrawSave {

	private JFrame jFrame = null;
	private JPanel jPanel = null;
	
	private String path = System.getProperty("user.dir");
	
	//下側右側面板畫圖時的引數
    private int startX,startY,endX,endY;
	
    public void showGui(){
    	jFrame = new JFrame();
    	jPanel = new JPanel();
    	
    	//設定jPanel大小
    	jPanel.setPreferredSize(new Dimension(400,400));
    	jPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
    	
    	jPanel.addMouseListener(new MouseAdapter(){
            //滑鼠按下事件,重置startX,startY
			public void mousePressed(MouseEvent e){
				startX = e.getX();
				startY = e.getY();
			}
			
			//雙擊面板是儲存繪圖區
			public void mouseClicked(MouseEvent e){
				if(e.getClickCount() == 2){
					savePic(path+"/pic.jpg");
				}
			}
		}); 

        //滑鼠拖動事件,自由畫圖
    	jPanel.addMouseMotionListener(new MouseAdapter(){
			public void mouseDragged(MouseEvent e){
				Graphics graphics = jPanel.getGraphics();
				endX = e.getX();
				endY = e.getY();
				((Graphics2D) graphics).setColor(new Color(144,242,41));
			        ((Graphics2D) graphics).setStroke(new BasicStroke(10));
				((Graphics2D)graphics).drawLine(startX,startY,endX,endY);
				startX=endX;
				startY=endY;
			}
		});
    	//設定jFrame的位置
    	jFrame.setLocation(400, 200);
    	jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	jFrame.add(jPanel);
        jFrame.pack();
        jFrame.setVisible(true);
    }
    
    public void savePic(String path){
		BufferedImage myImage = null;
		try {
			myImage = new Robot().createScreenCapture(
					new Rectangle(jFrame.getX()+8, jFrame.getY()+30, jPanel.getWidth(), jPanel.getHeight()));
			ImageIO.write(myImage, "jpg", new File(path));
		} catch (AWTException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
	public static void main(String[] args) {
		DrawSave drawAndSave = new DrawSave();
		drawAndSave.showGui();
	}

}