2012-02-27 187 views
5

JavaDocs指示GraphicsEnvironment支持“屏幕和打印机设备”。获取Java打印机GraphicsDevice

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

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

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

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

我试过搜索JavaDocs和Google没有运气。

有什么建议?

干杯

基于更多的想法

基于更多的想法更新,已建议使用类似的尝试...

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: 

这实际上不产生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); 
} 

,我可以用户无论是打印机Graphics上下文或其他Graphics上下文。

现在很明显,当打印到@ 72dpi的A4页面时,得到的图像尺寸为595x841,在600dpi(这已在上述示例中报告过),这导致图像为4970x7029。好了,这是好的,我只需要按比例缩小图片使用类似绘制目标打印机Graphics上下文时...

g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null); 

(这是测试,所以不要对我跳一下质量相关的问题,只是还没有)......

Printing

(通常在左边,BufferedImage右侧)...好了,不会做

所以,我后来想,我可以应用AffineTransform比例缓冲区Graphics上下文,使用类似...

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

这意味着我不会需要我们有潜在的现有油漆程序内申请任何“打印模式”式翻译...

这导致...

Not quite

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

所以我回去看了一下所有的测量...

GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration(); 
//... 
Rectangle bounds = conf.getBounds(); 
buffer = conf.createCompatibleImage(bounds.width, bounds.height); 

当时报告的4960x7015的图像大小,但它应该是4970x7029 ......别急,怎么样可以想象区...在600dpi应该是,3768x5827 ......所以不能依赖。

即使修正之后,结果仍然没有图像排队在任一位置,也没有质量的期望......

Still misaligned...

+0

这个问题的大小来了Java Graphics2D或输出到硬件打印机? – mKorbel 2012-08-23 08:10:47

+1

@mKorbel不是真的。就像你可以创建一个兼容的图像来渲染屏幕一样,我想用打印机来做同样的事情。基本上,如果你创建一个缓冲图像并将其绘制到打印机的图形上下文中,它会呈现(我认为)72dpi。在哪里好像您直接绘制图形,您获得打印机的dpi的分辨率 – MadProgrammer 2012-08-23 08:53:54

+0

谢谢,现在aaaach问题对我来说很明显:-) – mKorbel 2012-08-23 09:20:07

回答

0

Graphics2D提供一个方法来获得一个GraphicsConfiguration这是链接到GraphicsDevice。缺少的是信息,当您可以安全地假定在打印环境中GraphicsGraphics2D

E.g.下面的程序在我的设置中工作:

import java.awt.*; 
import java.awt.geom.*; 
import java.awt.image.BufferedImage; 
import java.awt.print.*; 
import javax.print.*; 

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

我鸣谢我试过这个,它没有工作。我会重新测试以确保 – MadProgrammer 2014-09-11 20:52:29

+0

其实,几个月前我尝试了类似的方法,但都没有成功。仍在测试 – MadProgrammer 2014-09-12 09:37:56

+0

因此,为了完整性,它在'Windows 7 32Bit','jdk 1.7.0_40'上工作... ... – Holger 2014-09-12 09:41:18