【问题标题】:Robot().createScreenCapture captures image with print dialog in itRobot().createScreenCapture 捕获带有打印对话框的图像
【发布时间】:2013-06-11 09:04:05
【问题描述】:

我希望我的应用程序截取屏幕截图并显示一个打印对话框,以便用户可以打印屏幕截图。但是,截图太慢/对话框出现太快,导致截图中出现对话框(如下所示)。

BufferedImage image = new Robot().createScreenCapture(new Rectangle((int) frame.getLocationOnScreen().getX(), (int) frame.getLocationOnScreen().getY(), frame.getWidth(), frame.getHeight()));

...

if (printJob.printDialog()) {
    try {
        printJob.print();
    } catch (Exception PrintException) {
        PrintException.printStackTrace();
    }
}

有没有办法在显示打印对话框之前指示屏幕截图何时完成捕获,而不是使用人工 Thread.sleep()?


编辑:

好的,我想我知道我做错了什么。真正发生的情况是,在打印对话框显示并且用户单击“确定”之后,但在打印对话框动画消失之前,屏幕被捕获。这是由于以下代码:

// Print button action listener
public class printButtonPressed implements ActionListener {
    public void actionPerformed(ActionEvent arg0) {

        PrinterJob printJob = PrinterJob.getPrinterJob ();
        Book book = new Book ();
        PageFormat documentPageFormat = new PageFormat ();
        documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
        book.append(new Page(), documentPageFormat);
        printJob.setPageable(book);

        if (printJob.printDialog()) {
            try {
                printJob.print();
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }
        }
    }
}

// Create printable page
private class Page implements Printable {
    public int print (Graphics g, PageFormat pageFormat, int page) {

        JFrame frame = Main.frame;
        try { // THIS SHOULD NOT BE HERE
            screenShot = new Robot().createScreenCapture(new Rectangle((int) frame.getLocationOnScreen().getX(), (int) frame.getLocationOnScreen().getY(), frame.getWidth(), frame.getHeight());
        } catch (AWTException e) {
            e.printStackTrace();
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.translate (pageFormat.getImageableX (), pageFormat.getImageableY ());

        int pageWidth = (int) pageFormat.getImageableWidth();
        int newImageWidth = pageWidth;
        int newImageHeight = (int)((double)newImageWidth/screenShot.getWidth(null)*screenShot.getHeight(null));

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.drawImage(screenShot, 0, 0, newImageWidth, newImageHeight, 0, 0, screenShot.getWidth(), screenShot.getHeight(), null);

        return PAGE_EXISTS;
    }
}

如果 Robot().createScreenCapture 在任何 PrinterJob 内容之前被调用,那么屏幕将在打印对话框出现之前被捕获,从而解决了这个问题。

// Print button action listener
public class printButtonPressed implements ActionListener {
    public void actionPerformed(ActionEvent arg0) {

        JFrame frame = Main.frame;
        try { // MOVE THIS UP HERE
            screenShot = new Robot().createScreenCapture(new Rectangle((int) frame.getLocationOnScreen().getX(), (int) frame.getLocationOnScreen().getY(), frame.getWidth(), frame.getHeight());
        } catch (AWTException e) {
            e.printStackTrace();
        }

        PrinterJob printJob = PrinterJob.getPrinterJob ();
        Book book = new Book ();
        PageFormat documentPageFormat = new PageFormat ();
        documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
        book.append(new Page(), documentPageFormat);
        printJob.setPageable(book);

        if (printJob.printDialog()) {
            try {
                printJob.print();
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }
        }
    }
}

// Create printable page
private class Page implements Printable {
    public int print (Graphics g, PageFormat pageFormat, int page) {

        Graphics2D g2d = (Graphics2D) g;
        g2d.translate (pageFormat.getImageableX (), pageFormat.getImageableY ());

        int pageWidth = (int) pageFormat.getImageableWidth();
        int newImageWidth = pageWidth;
        int newImageHeight = (int)((double)newImageWidth/screenShot.getWidth(null)*screenShot.getHeight(null));

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.drawImage(screenShot, 0, 0, newImageWidth, newImageHeight, 0, 0, screenShot.getWidth(), screenShot.getHeight(), null);

        return PAGE_EXISTS;
    }
}

【问题讨论】:

  • 你能不能做一些事情,比如创建第二个对话框,说它完成了,当它关闭时,它会继续打印?

标签: java


【解决方案1】:

将其转储到一个数组中,然后解析整个数组,然后就可以保证一切都在那里

我的意思是这个

BufferedImage TestShot = iris.createScreenCapture(new Rectangle(0,0,width,height));
int[] ImgData = null;
TestShot.getRGB(0, 0, width, height, ImgData, 0, 0);
for(int i:ImgData){
    // count or something
}
// all of it is there in TestShot

应该可以。我不知道你为什么会遇到这个问题,我一直在使用机器人,我的截图功能可以立即使用。也许是您的 printJob 需要更多时间。

【讨论】:

  • 对数组进行迭代不会产生任何影响(除了可能会减慢您的代码)。您可以安全地移除该部分。
  • 我把它留在那里的原因是因为它会在那里抛出一个数组,因为如果它运行零次,那么你知道数组中没有数据并且屏幕截图不应该准备好那时,您可以做的是添加一个小计数器,如果计数器高于 10 或出现问题。只是为了仔细检查数据是否都在那里。
  • 解决了我的问题(参见我上面的编辑)。感谢您的帮助,但这是出于其他原因!
猜你喜欢
  • 2013-11-08
  • 1970-01-01
  • 2019-02-09
  • 2013-06-15
  • 1970-01-01
  • 2010-10-13
  • 2012-02-05
  • 2015-06-30
  • 1970-01-01
相关资源
最近更新 更多