获取Java Printer GraphicsDevice

Mad*_*mer 5 java printing graphics

JavaDocs表明GraphicsEnvironment支持"屏幕和打印机设备".

我可以看到如何获取有关屏幕设备的信息,但我似乎无法找到有关如何获取有关打印机设备的信息的信息.

基本上,在打印时,我希望能够使用GraphicsConfiguration设备创建兼容的缓冲图像.

想要这样做的主要原因是:

  1. 我们希望在页面的第一个请求上缓冲页面请求,并简单地在页面的后续请求上绘制缓冲区(因为页面包含许多图像和一些复杂的渲染 - 而不是浪费时间绘制每个页面请求,我们想要使用缓冲区)
  2. 保持打印机的高分辨率输出.我们发现,如果我们直接绘制到打印机图形上下文,我们会获得一个更高的质量输出,然后我们尝试使用相同大小的缓冲图像.

我试过没有运气地搜索JavaDocs和谷歌.

有什么建议??

干杯

根据其他想法进行了更新

基于其他想法,有人建议尝试使用像...

GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
assert conf.getDevice().getType() == GraphicsDevice.TYPE_PRINTER;
System.out.println("Device: " + conf.getDevice().getIDstring());

final AffineTransform trans = conf.getDefaultTransform();
double dpi = trans.transform(new Point2D.Float(72, 0), null).getX();
System.out.println(dpi + " DPI");

Rectangle bounds = conf.getBounds();
System.out.println("page size: " + bounds.width + "x" + bounds.height);
// now you could do
buffer = conf.createCompatibleImage(bounds.width, bounds.height);
// verify values, you wouldn’t do this in production code:
Run Code Online (Sandbox Code Playgroud)

实际上哪个会生成BufferedImage哪个将被转换为打印机DPI

为了使测试更容易,我写了一个简单的print方法......

public void print(Graphics2D g2d, double width, double height) {
    Font font = g2d.getFont();
    font = font.deriveFont(64f);
    g2d.setFont(font);
    FontMetrics fm = g2d.getFontMetrics();
    String text = "Hello World!";
    double x = (width - fm.stringWidth(text)) / 2;
    double y = (height - fm.getHeight()) / 2;
    g2d.drawString(text, (float) x, (float) y);
}
Run Code Online (Sandbox Code Playgroud)

我可以使用打印机Graphics上下文或其他Graphics上下文.

现在显而易见的是,当打印到A4页面@ 72dpi时,得到的图像尺寸为595x841,600dpi(上面的例子已经报道),这导致图像为4970x7029.好的,这很好,我只需要在Graphics使用类似的东西绘制到目标打印机上下文时缩小图像.

g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null);
Run Code Online (Sandbox Code Playgroud)

(这是测试,所以不要再谈论质量相关问题了)...

印花

(正常在左边,BufferedImage在右边)......好吧,那不行

所以,我接着想,我可以将一个AffineTransform比例应用于缓冲区Graphics上下文,使用类似......

double scale = dpi / 72d;
AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale);
g2d.setTransform(scaleAT);
print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth());
Run Code Online (Sandbox Code Playgroud)

这意味着我不需要在我们拥有的基础现有油漆程序中应用任何"打印模式"类型的翻译......

这导致......

不完全的

但是等一下,这里出了什么问题?

所以我回去看看所有测量结果......

GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
//...
Rectangle bounds = conf.getBounds();
buffer = conf.createCompatibleImage(bounds.width, bounds.height);
Run Code Online (Sandbox Code Playgroud)

报告的图像大小为4960x7015,但它应该是4970x7029 ......但是等等,可想象的区域...... 600dpi它应该是3768x5827 ......所以不能依赖它.

即使在对此进行校正之后,结果仍然没有在任何位置和质量上都有预期的图像...

仍然未对准......

Hol*_*ger 0

Graphics2DGraphicsConfiguration提供了一种获取链接到 的方法GraphicsDevice。当你可以放心地假设一个Graphics当您可以安全地假设 a是 aGraphics2D打印上下文中的

\n\n

例如,以下程序在我的设置中有效:

\n\n
import java.awt.*;\nimport java.awt.geom.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.print.*;\nimport javax.print.*;\n\npublic class PrintDev implements Printable {\n  public static void main(String[] args) throws PrintException {\n    final DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;\n    PrintService ps=PrintServiceLookup.lookupDefaultPrintService();\n    System.out.println(ps.getName());\n    ps.createPrintJob().print(new SimpleDoc(new PrintDev(), flavor, null), null);\n  }\n  @Override\n  public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)\n      throws PrinterException {\n    GraphicsConfiguration conf = ((Graphics2D)graphics).getDeviceConfiguration();\n    assert conf.getDevice().getType()==GraphicsDevice.TYPE_PRINTER;\n    System.out.println("Device: "+conf.getDevice().getIDstring());\n    final AffineTransform trans = conf.getDefaultTransform();\n    System.out.println(trans.transform(new Point2D.Float(72,0),null).getX()+" DPI");\n    Rectangle bounds = conf.getBounds();\n    System.out.println("page size: "+bounds.width+"x"+bounds.height);\n    // now you could do\n    BufferedImage bi=conf.createCompatibleImage(bounds.width, bounds.height);\n    // verify values, you wouldn\xe2\x80\x99t do this in production code:\n    try { trans.invert(); }\n    catch(NoninvertibleTransformException ex){ return NO_SUCH_PAGE; }\n    Point2D p=trans.transform(new Point2D.Float(bounds.width, bounds.height),null);\n    System.out.printf("page in inches: %.2fx%.2f%n", p.getX()/72, p.getY()/72);\n    return NO_SUCH_PAGE;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n