Java 打印图形的一致性

4
我在屏幕上绘制了一些矩形,它们重叠在一起,看起来像一行一列的网格。在屏幕上一切都正常。
我尝试过多种打印方法(实现可打印接口),但无法获得相同的质量。
  • 使用JComponents的打印方法会出现颗粒状(即使关闭缓冲区也是如此)。
  • 直接重新绘制打印方法的Graphics对象会导致矩形重叠处出现较暗的线条,而矩形未重叠处则出现较浅的线条(无论Alpha Composite是什么)。我已经尝试了各种RenderingHints。
  • 将构建的缓冲图像直接打印到打印图形中可以保证质量的一致性,但某些线条似乎比其他线条更粗,因此整个列或行只有一侧有一条粗边框。有人知道这可能是为什么吗?
    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
        throws PrinterException {
    if(pageIndex > 2) {
        return Printable.NO_SUCH_PAGE;
    }

    RepaintManager currentManager = RepaintManager.currentManager(this);
    currentManager.setDoubleBufferingEnabled(false);

    Graphics2D g2d = (Graphics2D) graphics;
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
            RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
            RenderingHints.VALUE_DITHER_ENABLE);
    g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
            RenderingHints.VALUE_STROKE_NORMALIZE);
    g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                                RenderingHints.VALUE_FRACTIONALMETRICS_ON);    

    g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    g2d.scale(.5, .5);    
    if(pageIndex == 0) {
        this.paint(g2d);
    } else if(pageIndex == 1) {
        g2d.drawImage(onScreenBuffer, null, 0, 0);
    } else {
        g2d.setColor(new Color(51, 98, 140));
        g2d.setStroke(new BasicStroke(1f));
        //GridCell inherits from Rectangle2D.Double
        for (final GridCell cell : model.getCells()) {
            g2d.draw(cell);
        }
    }
    return Printable.PAGE_EXISTS;
}

检查一下您如何构建缓冲图像,特别是任何drawLine或fillRect方法。正如您所说,构建自己的缓冲图像将提供最一致的打印结果。 - Gilbert Le Blanc
请问为什么要使用 currentManager.setDoubleBufferingEnabled(false) ? - mKorbel
@mrKorbel - 我看到过 JComponents 的双缓冲可能会在调用 JComponent.print() 时对打印机造成负面影响。 - Dodd10x
@GilbertLeBlanc - 在上面的代码中,onScreenBuffer图像与我在paintComponent方法中呈现的图像相同 - 对于此示例的目的,这些图像以与上面的最终else块相同的方式绘制。 - Dodd10x
你尝试过使用 currentManager.setDoubleBufferingEnabled(true); 吗? - sampopes
1个回答

1
我遇到了几乎相同的问题。无法回忆所有细节,但打印 DPI 是主要问题。您必须确保使用最高可能的 DPI 进行打印,而不是屏幕 DPI(默认值)。
(顺便说一下,您需要考虑更大的 DPI 来生成图形)。
这里有一个 javax.print.attribute.standard.PrinterResolution
PrinterResolution 类是一个打印属性类,用于指定打印机支持的精确分辨率或用于打印作业的分辨率。此属性假定打印机具有一小组设备分辨率,可以在这些分辨率下运行,而不是连续的分辨率。
PrinterResolution 有多种用途:
1. 跳过 2. 当客户端需要使用客户端所需的分辨率完全打印作业时(既不多也不少),客户端将 PrinterResolution 类的实例指定为打印作业的属性。如果打印作业不支持该精确分辨率,则此操作将失败,并且 Fidelity 设置为 true。

有很多示例可用,例如:使用300dpi在Java中打印到硬件打印机


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接