Eth*_*lis 12 java java-2d awtrobot javax.imageio
编辑:如果任何人还有任何其他建议,以提高屏幕捕获性能,请随意分享,因为它可能完全解决我的问题!
你好开发者,
我正在为自己制作一些基本的屏幕捕获软件.截至目前,我已经获得了一些概念/修补代码的证明,它使用java.awt.Robot将屏幕捕获为BufferedImage.然后我执行此捕获指定的时间,然后将所有图片转储到磁盘.从我的测试中我得到大约每秒17帧.
时长:15秒拍摄的图像:255
时长:15秒图像捕获:229
显然,这对于真正的屏幕捕获应用程序来说还不够好.特别是因为这些捕获只是在我的IDE中选择一些文本而没有任何图形密集的文本.
我现在有两个班级是Main类和一个"Monitor"类.Monitor类包含捕获屏幕的方法.我的Main类有一个基于时间的循环,它调用Monitor类并将它返回的BufferedImage存储到BufferedImages的ArrayList中.如果我修改我的主类来生成几个执行该循环的线程,并且还收集有关捕获图像的系统时间的信息,我可以提高性能吗?我的想法是使用一个共享数据结构,它将在插入时基于捕获时间自动对帧进行排序,而不是将连续图像插入到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;
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
重新使用屏幕矩形和机器人类实例将为您节省一些开销。真正的瓶颈是将所有 BufferedImage 存储到数组列表中。
我首先会基准测试你的 robots.createScreenCapture(screenRect); 的速度有多快。调用没有任何 IO(不保存或存储缓冲图像)。这将为您的机器人类别提供理想的吞吐量。
long frameCount = 0;
while( (System.currentTimeMillis() - startTimeMillis) <= recordTimeMillis ) {
image = m1.captureScreen();
if(image !== null) {
frameCount++;
}
try {
Thread.yield();
} catch (Exception ex) {
}
}
Run Code Online (Sandbox Code Playgroud)
如果事实证明 captureScreen 可以达到您想要的 FPS,则无需多线程机器人实例。
我不是拥有缓冲图像的数组列表,而是拥有来自 AsynchronousFileChannel.write 的 Futures 数组列表。
我想这里的一个问题是大量的内存使用。您在测试中捕获了大约 250 个屏幕截图。根据屏幕分辨率,这是:
1280x800 : 250 * 1280*800 * 3/1024/1024 == 732 MB data
1920x1080: 250 * 1920*1080 * 3/1024/1024 == 1483 MB data
Run Code Online (Sandbox Code Playgroud)
尝试捕获而不将所有这些图像保留在内存中。
正如@Obicere 所说,保持 Robot 实例处于活动状态是一个好主意。
| 归档时间: |
|
| 查看次数: |
6851 次 |
| 最近记录: |