我正在编写一个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
我有什么遗失的吗?
答案 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并具有现代功能,您也可以使用变换反馈。