本文介绍了使用Java和awt.Robot时提高屏幕捕获速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If anyone also has any other recommendations for increasing performance of screen capture please feel free to share as it might fully address my problem!

Hello Fellow Developers,

Hello Fellow Developers,

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

I'm working on some basic screen capture software for myself. As of right now I've got some proof of concept/tinkering code that uses java.awt.Robot to capture the screen as a BufferedImage. Then I do this capture for a specified amount of time and afterwards dump all of the pictures to disk. From my tests I'm getting about 17 frames per second.

长度:15秒
图像捕获:255

Length: 15 secondsImages Captured: 255

长度:15秒
图像捕获:229

Length: 15 secondsImages Captured: 229

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

Obviously this isn't nearly good enough for a real screen capture application. Especially since these capture were me just selecting some text in my IDE and nothing that was graphically intensive.

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

I have two classes right now a Main class and a "Monitor" class. The Monitor class contains the method for capturing the screen. My Main class has a loop based on time that calls the Monitor class and stores the BufferedImage it returns into an ArrayList of BufferedImages.If I modify my main class to spawn several threads that each execute that loop and also collect information about the system time of when the image was captured could I increase performance? My idea is to use a shared data structure that will automatically sort the frames based on capture time as I insert them, instead of a single loop that inserts successive images into an arraylist.

代码:

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



Main

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);

}
}


推荐答案

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

Re-using the screen rectangle and robot class instances will save you a little overhead. The real bottleneck is storing all your BufferedImage's into an array list.

我首先要测试你的robot.createScreenCapture(screenRect)的速度;呼叫没有任何IO(不保存或存储缓冲的图像)。这将为您提供机器人类的理想吞吐量。

I would first benchmark how fast your robot.createScreenCapture(screenRect); call is without any IO (no saving or storing the buffered image). This will give you an ideal throughput for the robot class.

long frameCount = 0;
while( (System.currentTimeMillis() - startTimeMillis) <= recordTimeMillis ) {
    image = m1.captureScreen();
    if(image !== null) {
        frameCount++;
    }
    try {
        Thread.yield();
    } catch (Exception ex) {
    }
}

如果事实证明captureScreen可以达到你想要的FPS,那么不需要来实现多线程机器人实例。

If it turns out that captureScreen can reach the FPS you want there is no need to multi-thread robot instances.

而不是拥有一个数组缓冲图像列表我有一个来自AsynchronousFileChannel.write的Futures数组列表。

Rather than having an array list of buffered images I'd have an array list of Futures from the AsynchronousFileChannel.write.


  • 捕获循环


    • 获取BufferedImage


    • 转换包含JPEG数据的字节数组的BufferedImage


    • 创建输出文件的异步通道


    • 开始写入并将立即返回值(将来)添加到ArrayList


    • 浏览期货的ArrayList和确保它们全部完成

    这篇关于使用Java和awt.Robot时提高屏幕捕获速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 11:54