首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用Java和awt.Robot时提高屏幕捕获速度

在使用Java和awt.Robot时提高屏幕捕获速度
EN

Stack Overflow用户
提问于 2013-11-08 01:49:43
回答 2查看 7.9K关注 0票数 12

编辑:如果任何人也有任何其他建议来提高屏幕截图的性能,请随时分享,因为它可能完全解决我的问题!

大家好,开发人员,

我正在为自己开发一些基本的屏幕捕获软件。到目前为止,我已经获得了一些概念证明/修改代码,这些代码使用java.awt.Robot将屏幕捕获为BufferedImage。然后,我在指定的时间量内执行此捕获,然后将所有图片转储到磁盘。从我的测试中,我得到了大约每秒17帧。

试验#1

长度: 15秒截图: 255

试验#2

长度: 15秒截图: 229

显然,对于一个真正的屏幕捕获应用程序来说,这还远远不够。特别是因为这些捕获是我在IDE中选择了一些文本,而不是图形密集的。

我现在有两个类,一个是主类,一个是"Monitor“类。Monitor类包含用于捕获屏幕的方法。我的主类有一个基于时间的循环,它调用Monitor类并将它返回的BufferedImage存储到BufferedImages的ArrayList中。如果我修改我主类以产生多个线程,每个线程都执行该循环,并收集有关捕获映像时的系统时间的信息,是否可以提高性能?我的想法是使用一个共享的数据结构,当我插入帧时,它将根据捕获时间自动对帧进行排序,而不是将连续的图像插入到数组列表中的单个循环。

代码:

监视器

代码语言:javascript
复制
public class Monitor {

/**
 * Returns a BufferedImage
 * @return
 */
public BufferedImage captureScreen() {
    Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    BufferedImage capture = null;

    try {
        capture = new Robot().createScreenCapture(screenRect);
    } catch (AWTException e) {
        e.printStackTrace();
    }

    return capture;
}
}

Main

代码语言:javascript
复制
public class Main {


public static void main(String[] args) throws InterruptedException {
    String outputLocation = "C:\\Users\\ewillis\\Pictures\\screenstreamer\\";
    String namingScheme = "image";
    String mediaFormat = "jpeg";
    DiscreteOutput output = DiscreteOutputFactory.createOutputObject(outputLocation, namingScheme, mediaFormat);

    ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
    Monitor m1 = new Monitor();

    long startTimeMillis = System.currentTimeMillis();
    long recordTimeMillis = 15000;

    while( (System.currentTimeMillis() - startTimeMillis) <= recordTimeMillis ) {
        images.add( m1.captureScreen() );
    }

    output.saveImages(images);

}
}
EN

回答 2

Stack Overflow用户

发布于 2013-11-19 23:57:37

重用屏幕矩形和机器人类实例将为您节省一些开销。真正的瓶颈是将所有的BufferedImage存储到一个数组列表中。

我将首先对您的robot.createScreenCapture(screenRect);调用在没有任何IO的情况下(不保存或存储缓冲图像)的速度进行测试。这将为robot类提供理想的吞吐量。

代码语言:javascript
复制
long frameCount = 0;
while( (System.currentTimeMillis() - startTimeMillis) <= recordTimeMillis ) {
    image = m1.captureScreen();
    if(image !== null) {
        frameCount++;
    }
    try {
        Thread.yield();
    } catch (Exception ex) {
    }
}

如果事实证明captureScreen可以到达您想要的FPS,那么就没有需要来处理多线程机器人实例。

我使用的不是缓冲图像的数组列表,而是来自AsynchronousFileChannel.write的Futures的数组列表。

  • Capture loop
    • Get BufferedImage

包含JPEG data的

    • Convert BufferedImage to byte数组

将异步通道

    • Create到输出file

    • Start a write并将立即返回值(未来)添加到ArrayList

  • 等待通过你的ArrayList of Futures并确保他们都是未来的

票数 4
EN

Stack Overflow用户

发布于 2013-11-15 07:53:00

我猜密集的内存使用是这里的一个问题。您在测试中捕获了大约250个屏幕截图。根据屏幕分辨率,这是:

代码语言:javascript
复制
1280x800 : 250 * 1280*800  * 3/1024/1024 ==  732 MB data
1920x1080: 250 * 1920*1080 * 3/1024/1024 == 1483 MB data

尝试在不将所有这些图像保存在内存中的情况下捕获。

正如@Obicere所说,让Robot实例保持活动状态是个好主意。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19843050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档