JavaDocs表明GraphicsEnvironment支持"屏幕和打印机设备"。
我可以看到如何获取有关屏幕设备的信息,但我似乎无法找到有关如何获取有关打印机设备的信息的信息。
基本上,在打印时,我希望能够使用GraphicsConfiguration设备创建兼容的缓冲图像。
想要这样做的主要原因是:
我试图在没有运气的情况下搜索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
上下文。
现在显而易见的是,当打印到A4页面@ 72dpi时,得到的图像尺寸为595x841,600dpi(上面的例子已经报告过),这导致图像为4970x7029。好的,这很好,我只需要在使用类似的东西绘制到目标打印机Graphics
上下文时缩小图像。
g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null);
(这是测试,所以不要在质量相关的问题上跳过我)...
(左侧是正常,右侧是BufferedImage
)...好吧,那不会做
所以,我接着想,我可以使用类似......之类的内容将AffineTransform
比例应用于缓冲区Graphics
上下文。
double scale = dpi / 72d;
AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale);
g2d.setTransform(scaleAT);
print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth());
这意味着我不需要应用任何"打印模式"在我们拥有的基础现有油漆例程中进行类型翻译......
这导致......
但是等一下,这里出了什么问题?
所以我回去看看所有的测量结果......
GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
//...
Rectangle bounds = conf.getBounds();
buffer = conf.createCompatibleImage(bounds.width, bounds.height);
报告图像尺寸为4960x7015,但它应该是4970x7029 ......但是等等,可想象的区域...... 600dpi应该是3768x5827 ......所以不能依赖它
即使在纠正了这个问题之后,结果仍然没有在任何位置和质量上都有预期的图像...
答案 0 :(得分:0)
Graphics2D
提供了一种获取与GraphicsConfiguration
相关联的GraphicsDevice
的方法。如果您可以安全地假设在打印环境中Graphics
是Graphics2D
,那么缺少的是信息。
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;
}
}