任何高于72 DPI的Java打印都不会填充页面

时间:2011-12-19 23:45:32

标签: java opengl printing dpi

我正在编写一个jOGL应用程序,允许用户打印当前渲染的屏幕截图。为了打印出渲染,我将OpenGL上下文的大小设置为纸张的可打印区域,然后将前缓冲区保存到绘制到Printable画布的图像。

应用程序还必须以尽可能高的质量打印出这些屏幕截图,所以我一直在尝试将DPI从72默认设置提高到300.但是,它不会增加图像的分辨率,而是保持不变现在才填满页面的1/4左右。知道为什么会这样吗?

这是打印代码:

    // Set up for printing
    PrinterJob job = PrinterJob.getPrinterJob();

    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    PrinterResolution pr =
      new PrinterResolution(300, 300, PrinterResolution.DPI);

    aset.add(pr);

    aset.add(PrintQuality.HIGH);

    boolean ok = job.printDialog(aset);
    if (ok) {
        try {
            Book book = new Book();

            PageFormat pf = job.getPageFormat(aset);
            Paper paper = pf.getPaper();

            // Halve margins
            paper.setImageableArea(pf.getImageableX()/2, pf.getImageableY()/2, pf.getImageableWidth() + pf.getImageableX(), pf.getImageableHeight() + pf.getImageableY());
            pf.setOrientation(PageFormat.LANDSCAPE);

            pf.setPaper(paper);

            book.append(glcanvas, pf, 2);

            job.setPageable(book);
            job.print(aset);
        }
    }

然后,在我的可打印对象中,我调整了OpenGL上下文的大小:

    glcanvas.reshape(0, 0, (int)pf.getImageableWidth(), (int) pf.getImageableHeight() - StaticViewerUtility.HEADER_HEIGHT);

然而,PageFormat的可想象的大小永远不会改变。它保持在72,72,468,648(这是72 DPI,在8.5“x11”纸张上有1“边距)。即使DPI设置为300,可成像区域也不会改变。强制它更高只是让打印机看到该页面为任意大小(例如:22.87232“x11.8892”),图像仍然只打印到页面的一角。我也尝试手动更改OpenGL上下文的大小,但打印输出仍然是切断它原来的确切尺寸。

问题的示例截图: http://img32.imageshack.us/img32/2708/capturedodg.jpg

我有什么遗失的吗?

1 个答案:

答案 0 :(得分:2)

  

所以我一直在尝试将DPI从72默认值提升到300

OpenGL创建一个光栅图像,这意味着你有一个固定数量的像素。分辨率(DPI)告诉打印机有多少像素到一英寸。如果增加DPI,固定的像素数将仅覆盖较短的长度。为了弥补这一点,您需要使用相应更高分辨率的OpenGL进行渲染。

从窗户拍摄照片有问题。我强烈建议使用屏幕外缓冲区,如PBuffer或帧缓冲区对象。


OpenGL是一款针对实时图形的光栅化器,无论如何都不适合打印机(打印机喜欢矢量图形作为数据输入,但OpenGL的输出是光栅图像)。

使用OpenGL进行高质量打印的常用方法如下:

  • 确定图像的目标大小和分辨率。例如。在300DPI下10英寸×20英寸。因此,所需的分辨率为3000×6000像素。

  • 帧缓冲区的最大大小; OpenGL要求至少支持4096×4096。有了像EyeFinity这样的功能,你就拥有了数万个像素。但是,假设您的实现只能处理4096×4096 max。所以你不能适应3000×6000。解决方案是平铺渲染。您将图片分成2×3000×3000

    for t in tiles:
        glViewport(0, 0, t.width, t.height)
        glMatrixMode(GL_PROJECTION)
        glScalef(total_width / t.width, total_height / t.height, 1)
        glTranslatef(-1 + 2*total_width / t.off_x, -1 + 2*total_height / t.off_y, 0)
        your_projection()
        render_scene()
    

    然后将图块合并成一张大图。

另一个不错的方法是将OpenGL转换为向量输出:http://geuz.org/gl2ps/(遗憾的是,这个库似乎只支持立即模式)。如果您仍想使用GPU并具有现代功能,您也可以使用变换反馈。