刚才写了 Swing 实现截图小软件(一)后,点击“保存草稿”,回来再修改,点“编辑”在“可视化编辑器”中就出现了一堆的HTML代码了。 写不下去了,就直接转到(二)好了。
接上一节
第三步:为截取图像时,鼠标所标示的截取区域用矩形表示出来。
要实现根据鼠标的拖动,实时画矩形,可以采用
1. 取得鼠标的按下点和移动当前点坐标
2. 创建一个缓冲图形对象(BufferedImage) bi
3. 将原始图形画到 bi 中
4. 根据取得的坐标画一个矩形到 bi 中
5. 将 bi 画到屏幕上
imageLabel.addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
//1. 取得鼠标的按下点和移动当前点坐标
xEnd = e.getX();
yEnd = e.getY();
//2. 创建一个缓冲图形对象(BufferedImage) bi
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D)bi.getGraphics();
//3. 将原始图形画到 bi 中
g2d.drawImage(image, 0, 0, null);
g2d.setColor(Color.RED); //设置画笔颜色为红色
//4. 根据取得的坐标画一个矩形到 bi 中
//以鼠标按下点坐标和鼠标拖动的当前点坐标画矩形,作为截图区域的展示
//+1 与 -1 是为了防止截图时将矩形框也截进去
g2d.drawRect(Math.min(x, xEnd) - 1, Math.min(y, yEnd) - 1, Math.abs(xEnd - x) + 1, Math.abs(yEnd - y) + 1);
g2d.dispose();
//5. 将 bi 画到屏幕上
Graphics g = imageLabel.getGraphics();
g.drawImage(bi, 0, 0, null);
g.dispose();
}
public void mouseMoved(MouseEvent e) {
}
});
完整代码:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.event.MouseMotionListener;
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));
}
});
imageLabel.addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
//1. 取得鼠标的按下点和移动当前点坐标
xEnd = e.getX();
yEnd = e.getY();
//2. 创建一个缓冲图形对象(BufferedImage) bi
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D)bi.getGraphics();
//3. 将原始图形画到 bi 中
g2d.drawImage(image, 0, 0, null);
g2d.setColor(Color.RED); //设置画笔颜色为红色
//4. 根据取得的坐标画一个矩形到 bi 中
//以鼠标按下点坐标和鼠标拖动的当前点坐标画矩形,作为截图区域的展示
//+1 与 -1 是为了防止截图时将矩形框也截进去
g2d.drawRect(Math.min(x, xEnd) - 1, Math.min(y, yEnd) - 1, Math.abs(xEnd - x) + 1, Math.abs(yEnd - y) + 1);
g2d.dispose();
//5. 将 bi 画到屏幕上
Graphics g = imageLabel.getGraphics();
g.drawImage(bi, 0, 0, null);
g.dispose();
}
public void mouseMoved(MouseEvent e) {
}
});
}
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;
}
}
到这里,就可以有截图区域提示了。
然后,现在的截图显示,直接覆盖了前面的模拟屏幕,这只是一个演示。 软件中是需要一个按钮来开启这个模拟屏幕然后再去截图的。
第四步:创建程序主窗口,触发模拟屏幕,让截图的图像显示在主窗口中。
为了将截得的图像,传入到主窗口中,需要修改ScreenWindow, 增加 targetLabel 参数,用户接收主窗口中需要显示该截图的,目标组件。增加了一个右键点击退出模拟屏幕,所以增加了鼠标右键点击事件监听。
ScreenWindow完整代码:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.event.MouseMotionListener;
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 JLabel targetLabel;
private int x, y, xEnd, yEnd; //用于记录鼠标点击开始和结束的坐标
public ScreenWindow(JLabel targetLabel) throws AWTException, InterruptedException {
//目标组件初始化
this.targetLabel = targetLabel;
//取得屏幕尺寸
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 mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON3) { //鼠标右键单击事件
//退出ScreenWindow
ScreenWindow.this.dispose();
}
}
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));
//将所截得的图像,加载到目标组件targetLabel
targetLabel.setIcon(new ImageIcon(image));
//退出该ScreenWindow
ScreenWindow.this.dispose();
}
});
imageLabel.addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
//1. 取得鼠标的按下点和移动当前点坐标
xEnd = e.getX();
yEnd = e.getY();
//2. 创建一个缓冲图形对象(BufferedImage) bi
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D)bi.getGraphics();
//3. 将原始图形画到 bi 中
g2d.drawImage(image, 0, 0, null);
g2d.setColor(Color.RED); //设置画笔颜色为红色
//4. 根据取得的坐标画一个矩形到 bi 中
//以鼠标按下点坐标和鼠标拖动的当前点坐标画矩形,作为截图区域的展示
//+1 与 -1 是为了防止截图时将矩形框也截进去
g2d.drawRect(Math.min(x, xEnd) - 1, Math.min(y, yEnd) - 1, Math.abs(xEnd - x) + 1, Math.abs(yEnd - y) + 1);
g2d.dispose();
//5. 将 bi 画到屏幕上
Graphics g = imageLabel.getGraphics();
g.drawImage(bi, 0, 0, null);
g.dispose();
}
public void mouseMoved(MouseEvent e) {
}
});
}
// 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;
}
}
主程序 SanpShoot 完整代码:
import java.awt.AWTException;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
* 屏幕截图小程序
* @author pengranxiang
*
*/
public class SnapShoot extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton snapButton;
private JLabel imageLabel;
public SnapShoot() {
initUI();
initLayout();
createAction();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 400);
this.setTitle("截图小工具");
this.setLocationRelativeTo(null); //居中
this.setVisible(true);
}
private void initUI() {
snapButton = new JButton("开始截图(点右键退出)");
imageLabel = new JLabel();
}
private void initLayout() {
JPanel pane = new JPanel();
pane.add(imageLabel);
JScrollPane imgScrollPane = new JScrollPane(pane);
Container container = this.getContentPane();
GroupLayout layout = new GroupLayout(container);
container.setLayout(layout);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
GroupLayout.ParallelGroup hGroup = layout.createParallelGroup();
hGroup
.addComponent(snapButton)
.addComponent(imgScrollPane);
layout.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup
.addComponent(snapButton)
.addComponent(imgScrollPane);
layout.setVerticalGroup(vGroup);
}
private void createAction() {
snapButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
//开启模拟屏幕,将显示截图的目标组件传入
new ScreenWindow(imageLabel);
} catch (AWTException e1) {
e1.printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
});
}
public static void main(String[] args) {
new SnapShoot();
}
}
以上,就完成了软件中,全屏,区域截图的功能。
小软件还有其他四个功能,明天继续。。。。O(∩_∩)O~