代码之家  ›  专栏  ›  技术社区  ›  Nathan

为什么这段代码运行得这么慢?

  •  2
  • Nathan  · 技术社区  · 10 年前

    我正在尝试使用这些方法在屏幕上的矩形区域中查找颜色。然而,屏幕上有时有数百万像素,我目前每秒只实现了大约35次getColor迭代。我的代码中一定有什么东西导致它运行异常缓慢。

    我怎么能比这更快地扫描屏幕?理想情况下,我希望在不到一秒钟的时间内扫描整个屏幕,而不是现在的8小时:P

    这是我的两种方法。

    public static int getColor(int x, int y){
        try{
            return(robot.getPixelColor(x, y).getRGB() * -1);
        }catch(Exception e){
            System.out.println("getColor ERROR");
            return 0;
        }
    }
    
    //returns first instance of color,
    //Begins top left, works way down to bottom right
    public static Point findColor(Box searchArea, int color){
        System.out.println("Test");
        if(searchArea.x1 > searchArea.x2){
            int temp = searchArea.x1;
            searchArea.x1 = searchArea.x2;
            searchArea.x2 = temp;
        }
        if(searchArea.y1 > searchArea.y2){
            int temp = searchArea.y1;
            searchArea.y1 = searchArea.y2;
            searchArea.y2 = temp;
        }
        for(int i = searchArea.x1;i <=searchArea.x2; i++){
            for(int j = searchArea.y1;j<=searchArea.y2;j++){
                if(getColor(i, j) == color){
                    return new Point(i, j);
    
                }
                System.out.println(i + " " + j);
            }
        }
        return new Point(-1, -1);
    }
    
    2 回复  |  直到 9 年前
        1
  •  6
  •   MadProgrammer    10 年前

    Robot#getColor 将非常缓慢,特别是当以这种方式使用时。

    更好的解决方案是抓取屏幕快照(即使是小块)并处理结果 BufferedImage .

    使用以下示例,我得到。。。

    Took 0 seconds to scan image
    Took 3 seconds to scan screen
    

    对于面积为 10x10

    示例代码。。。

    import java.awt.AWTException;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.Robot;
    import java.awt.image.BufferedImage;
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class TestColorGrab {
    
        private static Robot robot;
    
        public static void main(String[] args) {
            try {
                robot = new Robot();
            } catch (AWTException ex) {
                Logger.getLogger(TestColorGrab.class.getName()).log(Level.SEVERE, null, ex);
            }
            new TestColorGrab();
        }
    
        public TestColorGrab() {
            Rectangle bounds = new Rectangle(0, 0, 10, 10);
            long start = System.currentTimeMillis();
            scanImageArea(bounds);
            System.out.println("Took " + ((System.currentTimeMillis() - start) / 1000), TimeUnit.SECONDS) + " seconds to scan image");
    
            start = System.currentTimeMillis();
            scanRobotArea(bounds);
            System.out.println("Took " + ((System.currentTimeMillis() - start) / 1000) + " seconds to scan screen");
        }
    
        public static int getColor(int x, int y) {
            try {
                return (robot.getPixelColor(x, y).getRGB() * -1);
            } catch (Exception e) {
                System.out.println("getColor ERROR");
                return 0;
            }
        }
    
        public static void scanRobotArea(Rectangle searchArea) {
            for (int i = searchArea.x; i < searchArea.x + searchArea.width; i++) {
                for (int j = searchArea.y; j < searchArea.y + searchArea.height; j++) {
                    getColor(i, j);
                }
            }
        }
    
        public static void scanImageArea(Rectangle searchArea) {
            BufferedImage image = robot.createScreenCapture(searchArea);
            for (int x = 0; x < image.getWidth(); x++) {
                for (int y = 0; y < image.getHeight(); y++) {
                    image.getRGB(x, y);
                }
            }
        }
    
    }
    
        2
  •  2
  •   nicomp    10 年前

    取出印刷品。你给控制台写了一百万次。