当前位置: 首页 > 面试题库 >

是否可以更快地替代java.awt.Robot.createScreenCapture?

梁丘琛
2023-03-14
问题内容

我正在制作一个程序,要求至少每秒捕获24个屏幕截图。目前,使用下面的代码,我每94毫秒仅获得1个,因此大约为10毫秒。

我不想使用任何第三方库,因为我试图将其保持尽可能小,但是如果我希望获得显着的性能提升,我会愿意的。我也试图保持该平台独立,但是,如果确实能够显着提高性能,我愿意将其限于Windows。

编辑:我现在也尝试了两种不同的方法;使用在oracles网站上找到的代码段,并在下面的注释中指出了该代码段。这三者都花了大约2.1-220万纳秒的时间,实在是太低效了。

public abstract class Benchmark {

    private final int iterations;

    public Benchmark(int iterations) {
        this.iterations = iterations;
    }

    public abstract void logic();

    public void start() {
        long start = System.nanoTime();
        for (int iteration = 0; iteration < iterations; iteration++) {
            long iterationStart = System.nanoTime();
            logic();
            System.out.println("iteration: " + iteration + " took: " + (System.nanoTime() - iterationStart) + " nanoseconds.");
        }
        long total = (System.nanoTime() - start);
        System.out.println(iterations + " iterations took: " + total + " nanoseconds.  Average iteration was: " + (total / iterations));
    }
}

_

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;

public class RobotBenchmark extends Benchmark {

    private final Robot robot;
    private final Rectangle screen;

    public static void main(String[] args) {
        Benchmark benchmark;
        try {
            benchmark = new RobotBenchmark(24);
            benchmark.start();
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    public RobotBenchmark(int iterations) throws AWTException {
        super(iterations);
        robot = new Robot();
        screen = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    }

    @Override
    public void logic() {
        robot.createScreenCapture(screen);
    }

}

_

import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.HeadlessException;
import java.awt.Rectangle;

public class DirectRobotBenchmark extends Benchmark {

    private final GraphicsDevice device;
    private final Rectangle screenRectangle;
    private final DirectRobot robot;

    private int[] screen;

    public static void main(String[] args) {
        Benchmark benchmark;
        try {
            benchmark = new DirectRobotBenchmark(24);
            benchmark.start();
        } catch (HeadlessException | AWTException e) {
            e.printStackTrace();
        }
    }

    public DirectRobotBenchmark(int iterations) throws HeadlessException, AWTException {
        super(iterations);
        device = DirectRobot.getDefaultScreenDevice();
        screenRectangle = new Rectangle(1920, 1080);
        robot = new DirectRobot(device);
        screen = new int[screenRectangle.width * screenRectangle.height];
    }

    @Override
    public void logic() {
        screen = robot.getRGBPixels(screenRectangle);
    }
}

_

import java.awt.AWTException;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.peer.RobotPeer;

import sun.awt.SunToolkit;

@SuppressWarnings("restriction")
public class RobotPeerBenchmark extends Benchmark {

    private final SunToolkit toolkit;
    private final RobotPeer peer;
    private final Rectangle screenRectangle;

    private int[] screen;

    public static void main(String[] args) {
        try {
            Benchmark robotPeerBenchmark = new RobotPeerBenchmark(24);
            robotPeerBenchmark.start();
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    public RobotPeerBenchmark(int iterations) throws AWTException {
        super(iterations);
        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
        peer = toolkit.createRobot(new Robot(), GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
        screenRectangle = new Rectangle(toolkit.getScreenSize());
        screen = new int[screenRectangle.width * screenRectangle.height];
    }

    @Override
    public void logic() {
        screen = peer.getRGBPixels(screenRectangle);
    }
}

问题答案:

唯一的方法就是通过JNI或JNA。我做了一些基准测试和本机屏幕捕获API,与Robots 8 FPS相比,它能够维持约45
FPS。我可能会开始从事JNI项目,以在不久的将来解决此问题。如果可以的话,我将使用项目URL更新此帖子。



 类似资料:
  • 问题内容: 题 Java 8 MIME编码器和解码器是否可以 _ 替代_ 不支持的内部Java API 和? 编辑(澄清):通过直接 _ 替换,_ 我的意思是我可以使用或透明地将任何其他现有客户端代码的Java 8 MIME Base64编码器/解码器切换为旧代码。 我到目前为止的想法以及原因 根据我的调查和快速测试(请参见下面的代码), _ 它应该是直接替代品,_ 因为 基于其JavaDoc的是

  • 问题内容: 假设我有以下示例: 例子一 现在,可能是: 例子二 关键不是实际的代码,而是使用一次以上,两次/三次或三次以上的时间。 上午我更好的性能,明智使用 例如两个 比 例如一个 (也许与解释为什么或者为什么不)? 编辑/注意 我怀疑两个更好。当我不可避免地忘记将事件处理程序添加到事件处理程序时,我有点担心的是在添加代码,而不是无意中引入了一个潜在的难以诊断的错误。那么我应该使用还是为此? 谢

  • 我知道我不应该优化我的程序的每一个点,所以请考虑这个问题是“学术性的” 我最大有100个字符串和整数,每个都是这样的: 这个集合是预先初始化的,这意味着一旦创建,它就永远不会更改。在集合初始化之后,我会非常密集地使用它,所以快速查找很好。字符串很短,最多30个字符。映射的int也有限,介于1和100之间。 至少知道字符串是预初始化的,并且永远不会更改,应该可以“找到”导致“一篮子一项”映射的哈希函

  • 问题内容: 我有一个3d数组,其中填充了从0到N的整数。我需要一个与该数组等于1、2、3,… N的位置对应的索引列表。我可以使用np.where进行如下操作: 但这很慢。根据这个问题 快速python numpy在哪里功能? 应该可以大大加快索引搜索的速度,但是我无法将那里提出的方法转移到我获取实际索引的问题上。加快上述代码的最佳方法是什么? 作为附加组件:我想稍后存储索引,使用np.ravel_

  • 问题内容: 我知道这个话题已经解决了上千次。但是我找不到解决办法。 我正在尝试计算列表(df2.list2)的列中出现列表(df1.list1的每一行)的频率。所有列表仅包含唯一值。List1包含约300.000行,list2包含30.000行。 我有一个有效的代码,但是它的运行速度非常慢(因为我使用的是迭代程序)。我也尝试过itertuples(),但它给了我一个错误(“要解压缩的值太多(预期2

  • 问题内容: 您可以在Python中执行此操作,但是在PHP中可以吗? 例如: 问题答案: 这 有点 晚了,但我只想指出,自PHP 5.3起,实际上有可能在不使用PHP扩展的情况下覆盖内部函数。 诀窍是您可以在名称空间内重新定义内部PHP函数。它基于PHP对函数进行名称解析的方式: 在名称空间(例如A \ B)内部,对不合格函数的调用在运行时解决。解决调用foo()的方法如下: 它从当前名称空间中查