【发布时间】:2013-11-19 12:26:03
【问题描述】:
编辑:如果有人对提高屏幕捕获性能还有其他建议,请随时分享,因为它可能会完全解决我的问题!
各位开发者您好,
我正在为自己开发一些基本的屏幕捕捉软件。截至目前,我已经获得了一些使用 java.awt.Robot 将屏幕捕获为 BufferedImage 的概念证明/修补代码。然后我在指定的时间内进行此捕获,然后将所有图片转储到磁盘。根据我的测试,我每秒获得大约 17 帧。
试验#1
时长:15 秒 捕获的图像:255
试验#2
时长:15 秒 捕获的图像:229
显然,这对于真正的屏幕捕获应用程序来说还不够好。特别是因为这些捕获只是我在我的 IDE 中选择了一些文本,而没有任何图形密集型。
我现在有两个类,一个主类和一个“监视器”类。 Monitor 类包含捕获屏幕的方法。我的 Main 类有一个基于时间的循环,它调用 Monitor 类并将它返回的 BufferedImage 存储到 BufferedImages 的 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;
}
}
主要
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);
}
}
【问题讨论】:
-
你不断创造新的矩形和新的机器人。尝试为实例制作最终版本,并仅使用该字段而不是制作新字段。这应该会有所帮助。
-
@Obicere 我做到了,我仍然获得类似的表现。但是你知道或认为多线程的想法值得追求吗?
-
我不太了解您在做什么,但似乎如果您创建了一个机器人/核心,您将能够遍历每个机器人并在不同的核心上截取屏幕截图而主核心正忙。
-
如果你做多线程也许你可以使用一个队列并在你去添加图像时同步它。您可以在以这种方式输入图像时避免对图像进行排序。或者,您可以在所有图像完成后进行排序。如果您关心的是 FPS,您不想在添加图像时执行任何排序计算。
-
不是awt.Robot,而是更快stackoverflow.com/a/4843247/1018903。
标签: java java-2d javax.imageio awtrobot