论坛首页 Java企业应用论坛

Swing 实现截图小软件 (一)

浏览 7510 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-02-23  

软件功能:            
             1.全屏、区域截图
             2.涂鸦功能
             3.画线,花圈,
             4.水印
             5.可保存本地硬盘

 

 

本节先考虑第一个功能:全屏,区域截图

 

第一步: 首先需要解决的问题是,如何让截取的图像,全屏显示。

一般的截图软件都是,点击截图后,首先动态抓取整个屏幕,然后全屏显示在整个屏幕--模拟屏幕,之后再在该模拟屏幕上进行其他动作。

 

所以我们先考虑两个动作

A. 抓取整个屏幕图片

B. 将抓取的屏幕图片全屏显示

 

对于A,Java有自带的方法可以使用:

 

java.awt.Robot robot = new Robot();
//截取指定区域部分的屏幕图像
BufferedImage screen = robot.createScreenCapture(new Rectangle(x, y, w, h));

 

对于B,则先考虑如何让窗口全屏显示。

我提供的方案为:

 

/**
 * 全屏显示的窗口, 按 Alt + F4 退出
 * @author pengranxiang
 */
class ScreenWindow extends JFrame {
	private static final long serialVersionUID = -1;
	

	public ScreenWindow() {
		this.setUndecorated(true);	//去掉窗口装饰
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setExtendedState(JFrame.MAXIMIZED_BOTH);	//窗口最大化
	}
	
	public static void main(String[] args) {
		new ScreenWindow();
	}
}
 

有了全屏显示的窗口后,就只需要考虑如何将屏幕的截图加入窗口中显示。

要显示图片,Swing中一般使用 JLabel,那么将截图展示在JLabel中,然后再全屏显示,即可完成第一步

同时将鼠标光标设置为 “十字”,当出现模拟屏幕时,鼠标光标会变为“十字”作为提示,同时为下一步做准备。

完整代码:

 

 

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * 全屏显示的窗口, 按 Alt + F4 退出
 * @author pengranxiang
 */
public class ScreenWindow extends JFrame {
	private static final long serialVersionUID = -3758062802950480258L;
	
	private Image image;
	private JLabel imageLabel;

	public ScreenWindow() throws AWTException, InterruptedException {
		//取得屏幕尺寸
		Dimension screenDims = Toolkit.getDefaultToolkit().getScreenSize();
		//取得全屏幕截图
		image = GraphicsUtils.getScreenImage(0, 0, screenDims.width, screenDims.height);
		//用于展示截图
		imageLabel = new JLabel(new ImageIcon(image));
		//当鼠标在imageLabel上时,展示为 十字形
		imageLabel.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		
		this.getContentPane().add(imageLabel);
		
		this.setUndecorated(true);	//去掉窗口装饰
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setExtendedState(JFrame.MAXIMIZED_BOTH);	//窗口最大化
	}
	
	public static void main(String[] args) throws AWTException, InterruptedException {
		new ScreenWindow();
	}
}

class GraphicsUtils {
	/**
     * 截图屏幕中制定区域的图片
     * @param x
     * @param y
     * @param w
     * @param h
     * @return 被截部分的BufferedImage对象
     * @throws AWTException
     * @throws InterruptedException
     */
    public static BufferedImage getScreenImage(int x, int y, int w, int h) throws AWTException, InterruptedException {
		Robot robot = new Robot();
		BufferedImage screen = robot.createScreenCapture(new Rectangle(x, y, w, h));
		return screen;
	}
}

 

 

第二步:既然全屏截图和展示解决了,接下来就考虑在 模拟屏幕 中进行区域截图了。

模拟屏幕做成后,只要在JLabel中设置鼠标监听,取得鼠标按下和弹起时的坐标即可实现区域截图,仍然使用 getScreenImage() 即可。

完整代码:

import java.awt.AWTException;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * 全屏显示的窗口, 按 Alt + F4 退出
 * @author pengranxiang
 */
public class ScreenWindow extends JFrame {
	private static final long serialVersionUID = -3758062802950480258L;
	
	private Image image;
	private JLabel imageLabel;
	
	private int x, y, xEnd, yEnd;	//用于记录鼠标点击开始和结束的坐标

	public ScreenWindow() throws AWTException, InterruptedException {
		//取得屏幕尺寸
		Dimension screenDims = Toolkit.getDefaultToolkit().getScreenSize();
		//取得全屏幕截图
		image = GraphicsUtils.getScreenImage(0, 0, screenDims.width, screenDims.height);
		//用于展示截图
		imageLabel = new JLabel(new ImageIcon(image));
		//当鼠标在imageLabel上时,展示为 十字形
		imageLabel.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		
		createAction();
		
		this.getContentPane().add(imageLabel);
		
		this.setUndecorated(true);	//去掉窗口装饰
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setExtendedState(JFrame.MAXIMIZED_BOTH);	//窗口最大化
	}
	
	/**
	 * 实现监听动作
	 */
	private void createAction() {
		imageLabel.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				x = e.getX();
				y = e.getY();
			}

			public void mouseReleased(MouseEvent e) {
				xEnd = e.getX();
				yEnd = e.getY();
				
				//鼠标弹起时,取得鼠标起始两点组成的矩形区域的图像
				try {
					//因为 xEnd 可能比  x 小 (由右网左移动)起始坐标取其中较小值,xEnd - x 取其绝对值, 同样处理y
					image = GraphicsUtils.getScreenImage(Math.min(x, xEnd), Math.min(y, yEnd), Math.abs(xEnd - x), Math.abs(yEnd - y));
				} catch (AWTException e1) {
					e1.printStackTrace();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				
				//为了查看截图效果,将区域截图的部分代替全屏的截图展示
				imageLabel.setIcon(new ImageIcon(image));
			}
		});
	}
	
	public static void main(String[] args) throws AWTException, InterruptedException {
		new ScreenWindow();
	}
}

class GraphicsUtils {
	/**
     * 截图屏幕中制定区域的图片
     * @param x
     * @param y
     * @param w
     * @param h
     * @return 被截部分的BufferedImage对象
     * @throws AWTException
     * @throws InterruptedException
     */
    public static BufferedImage getScreenImage(int x, int y, int w, int h) throws AWTException, InterruptedException {
		Robot robot = new Robot();
		BufferedImage screen = robot.createScreenCapture(new Rectangle(x, y, w, h));
		return screen;
	}
}
 

运行上面的程序,发现在抓取区域图像时,会搞不清截取的到底是那部分,所以接下来还需要为鼠标拖动时,画一个动态矩形来表示截取的部分,提高用户体验。

 

第三步:为截取图像时,鼠标所标示的截取区域用矩形表示出来。

 

   发表时间:2011-02-25  
几年前写了个。
功能和lz差不多,支持直接截图到剪切板。

后来改成了netbeans插件,放到了官网上,插件列表里面可以搜到,叫PigShot.

截图实际就是拍了张桌面的快照,然后在快照上的操作。这种方式没法抓鼠标,不知道有什么解决方案。
0 请登录后投票
   发表时间:2011-02-25  
Ivan_Pig 写道
几年前写了个。
功能和lz差不多,支持直接截图到剪切板。

后来改成了netbeans插件,放到了官网上,插件列表里面可以搜到,叫PigShot.

截图实际就是拍了张桌面的快照,然后在快照上的操作。这种方式没法抓鼠标,不知道有什么解决方案。

使用印屏幕鍵,程序監控剪切板和按鍵。有截圖了將圖片顯示出來
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics