前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Java制作的截屏小工具

基于Java制作的截屏小工具

原创
作者头像
流年Felix
修改2023-05-14 16:08:02
9400
修改2023-05-14 16:08:02
举报

最近公司的用例执行需要截图,而且要求比较详细,一个case执行下来动不动十几张,二十张甚至三四十张图片,平时都是截完一张就贴到word文档中,一个case执行完了就把所有的截图整理好放在一个word文档下,既拖累了用例执行速度,操作起来又很麻烦。这里用Java实现了一个截屏的功能,并且自动把截取的图片按照用户设定好的路径和case名字存到对应的文件夹下,case执行完成之后手动点击合成,就可以将一个执行一个case所截的图片按先后顺序合成为一张图片,能提升效率。同时截图除了支持手动点击截图外,还支持快捷键截屏(Ctrl+K),支持快捷键显示弹框和隐藏弹框(Ctrl+H),由于Java原生不支持全局的键盘时间监听,这里引入了第三方JIntellitype包来实现,JIntellitype最好用1.4.1版本的

代码语言:javascript
复制
<dependency>
      <groupId>com.melloware</groupId>
      <artifactId>jintellitype</artifactId>
      <version>1.4.1</version>
    </dependency>

最后实现的效果如下:

运行效果如下
运行效果如下
代码语言:javascript
复制
文件路径是截屏后图片保存的路径,用例编号是标识截的图片关联哪个用例的如
路径填写:C:\Program Files\Java\AWT
用例编号填写:case1653
那么截屏成功后的图片就保存在 C:\Program Files\Java\AWT\case1653下,合成的图片也在这里

实现起来就一个类,代码如下:

代码语言:javascript
复制
import com.melloware.jintellitype.JIntellitype;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class SuperCaptureTool {
    private JFrame frame;
    private Robot robot;
    private JTextField pathTextField;
    private JTextField filenameTextField;
    private JButton countButton;
    private String savePath;
    private int screenshotCount = 0;
    public static final JIntellitype instance = JIntellitype.getInstance();

    public SuperCaptureTool(String savePath) throws AWTException {
        this.robot = new Robot();
        this.savePath = savePath;
        createWindow();
    }

    private void createWindow() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(320, 150);

        frame.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.insets = new Insets(3, 3, 3, 3);

        // 文件路径标题
        JLabel pathLabel = new JLabel("文件路径:");
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.weightx = 1;
        constraints.anchor = GridBagConstraints.CENTER;
        frame.add(pathLabel, constraints);

        // 文件路径输入框
        pathTextField = new JTextField(20);
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 2;
        pathTextField.setText(savePath);
        frame.add(pathTextField, constraints);

        // 用例编号标题
        JLabel filenameLabel = new JLabel("用例编号:");
        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.weightx = 1;
        frame.add(filenameLabel, constraints);

        // 用例编号输入框
        filenameTextField = new JTextField(20);
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.weightx = 2;
        frame.add(filenameTextField, constraints);

        // 序号展示按钮
        countButton = new JButton();
        this.countButton.setText("序号: " + screenshotCount);
        constraints.gridx = 2;
        constraints.gridy = 0;
        constraints.weightx = 0.5;
        frame.add(this.countButton, constraints);

        JButton captureButton = new JButton("截屏");
        constraints.gridx = 1;
        constraints.gridy = 2;
        constraints.weightx = 2;
        frame.add(captureButton, constraints);

        JButton mergeButton = new JButton("合成");
        constraints.gridx = 2;
        constraints.gridy = 1;
        constraints.weightx = 0.5;
        frame.add(mergeButton, constraints);

        JButton resetButton = new JButton("重置");
        constraints.gridx = 0;
        constraints.gridy = 2;
        constraints.weightx = 1;
        frame.add(resetButton, constraints);
        frame.setVisible(true);

        captureButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                    captureScreen(false);
            }
        });

        mergeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mergeScreenshots();
            }
        });

        resetButton.addActionListener(e -> {
            this.screenshotCount = 0;
            this.countButton.setText("序号: " + this.screenshotCount);
        });

        instance.registerHotKey(75, JIntellitype.MOD_CONTROL, (int) 'K');
        instance.registerHotKey(72, JIntellitype.MOD_CONTROL, (int) 'H');
        // 添加热键监听器
        instance.addHotKeyListener((hotKeyID) -> {
            if (hotKeyID == 75) { // Ctrl+K热键被触发
                try {
                    captureScreen(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (hotKeyID == 72) {
                boolean visible = frame.isVisible();
                frame.setVisible(!visible);
            }
        });

    }

    public static void main(String[] args)  {
        int targetWidth = 0;
        int targetHeight = 0;
        String path = "D:\\caseimages";
        try {
            SuperCaptureTool tool = new SuperCaptureTool(path);
        } catch (AWTException e) {
            throw new RuntimeException(e);
        }
    }

    private void captureScreen(boolean isKeyEvent)  {
        String inputPath = pathTextField.getText().trim();
        if (!inputPath.isEmpty()) {
            this.savePath = inputPath;
        }
        File savePath = new File(this.savePath);
        if (!savePath.isDirectory()) {
            return;
        }
        String filename = filenameTextField.getText().trim();
        if (filename.isEmpty()) {
            return;
        }
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle screenRect = new Rectangle(screenSize);
        BufferedImage capture = robot.createScreenCapture(screenRect);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
        String timestamp = dateFormat.format(new Date());
        String fullFilename = filename + "-" + timestamp + "-" + screenshotCount + ".png";
        String path = savePath + File.separator + filenameTextField.getText().trim();
        File f = new File(path);
        if (!f.exists()) {
            f.mkdir();
        }
        File outputFile = new File(path, fullFilename);
        screenshotCount++;
        this.countButton.setText("序号: " + screenshotCount);
        try {
            ImageIO.write(capture, "png", outputFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (isKeyEvent) {
            frame.setVisible(!frame.isVisible());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            frame.setVisible(!frame.isVisible());
        }
    }

    void mergeImages(String folderPath, String outputImagePath, int targetWidth, int targetHeight) {
        try {
            File folder = new File(folderPath);
            File[] files = folder.listFiles();
            if (targetWidth == 0 || targetHeight == 0) {
                for (File file : files) {
                    BufferedImage image = ImageIO.read(file);
                    if (targetWidth < image.getWidth()) {
                        targetWidth = image.getWidth();
                    }
                    targetHeight += image.getHeight();
                }
            }
            BufferedImage mergedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = mergedImage.createGraphics();
            int y = 0;
            for (File file : files) {
                BufferedImage image = ImageIO.read(file);
                g2d.drawImage(image, 0, y, null);
                y += image.getHeight();
            }
            g2d.dispose();
            File outputFile = new File(outputImagePath);
            boolean png = ImageIO.write(mergedImage, "png", outputFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void mergeScreenshots() {
        String path = savePath + File.separator + filenameTextField.getText().trim();
        File f = new File(path);
        if (!f.exists()) {
            f.mkdir();
        }
        File folder = new File(path);
        if (!folder.exists() || !folder.isDirectory()) {
            return;
        }
        File[] files = folder.listFiles();
        if (files.length == 0) {
            return;
        }
        int targetWidth = 0;
        int targetHeight = 0;
        for (File file : files) {
            if (file.getName().contains("merged")) {
                continue;
            }
            BufferedImage image;
            try {
                image = ImageIO.read(file);
                if (image != null) {
                    targetWidth = Math.max(targetWidth, image.getWidth());
                    targetHeight += image.getHeight();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        BufferedImage mergedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = mergedImage.createGraphics();
        int y = 0;
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (file.getName().contains("merged")) {
                continue;
            }
            BufferedImage image;
            try {
                image = ImageIO.read(file);
                if (image != null) {
                    g2d.drawImage(image, 0, y, null);
                    y += image.getHeight();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        g2d.dispose();
        String filename = filenameTextField.getText().trim();
        String path2 = savePath + File.separator + filename;
        File f2 = new File(path2);
        if (!f.exists()) {
            f.mkdir();
        }
        String outputImagePath = f.getAbsolutePath() + File.separator + filename + "-merged" + (screenshotCount + 1) + ".png";
        File outputFile = new File(outputImagePath);
        try {
            ImageIO.write(mergedImage, "png", outputFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这里需要注意JIntellitype的一些用法

1、首先是热键的注册用法,这里JIntellitype.getInstance()是一个单例模式,然后注册了两个快捷键:Ctrl+K和Ctrl+H

代码语言:javascript
复制
JIntellitype.getInstance().registerHotKey(75, JIntellitype.MOD_CONTROL, (int) 'K');
JIntellitype.getInstance().registerHotKey(72, JIntellitype.MOD_CONTROL, (int) 'H'); 

2、注册热键后,就可以给快捷键绑定监听事件

代码语言:javascript
复制
 instance.addHotKeyListener((hotKeyID) -> {
     if (hotKeyID == 75) { // Ctrl+K热键被触发
         //do Somethiing 
     }
     if (hotKeyID == 72) { // Ctrl+H热键被触发
         //do Somethiing 
     }
 }

然后项目打包📦这块,项目只有一个SuperCaptureTool类,还有一个依赖第三方依赖包JIntellitype,使用idea打包时记得添加JIntellitype,打包成一个整体,打包生成的AWT.jar就是我们需要的

选择MainClass入口
选择MainClass入口
添加第三方依赖包JIntellitype
添加第三方依赖包JIntellitype
Bulid Artifacts就会生成jar包
Bulid Artifacts就会生成jar包

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现起来就一个类,代码如下:
  • 这里需要注意JIntellitype的一些用法
  • 然后项目打包📦这块,项目只有一个SuperCaptureTool类,还有一个依赖第三方依赖包JIntellitype,使用idea打包时记得添加JIntellitype,打包成一个整体,打包生成的AWT.jar就是我们需要的
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档