软件功能:
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;
}
}
运行上面的程序,发现在抓取区域图像时,会搞不清截取的到底是那部分,所以接下来还需要为鼠标拖动时,画一个动态矩形来表示截取的部分,提高用户体验。
第三步:为截取图像时,鼠标所标示的截取区域用矩形表示出来。