java printerjob景观白色空间

我目前在打印机工作时遇到问题,它适用于人像图像,但对于风景图像,它会切割部分图像并填充白色空间。

这是我的代码

编辑

PrintService printService = PrintServiceLookup.lookupDefaultPrintService(); BufferedImage bufferedImage = ImageIO.read(new File("house.jpg")); boolean isLandscape = bufferedImage.getWidth() > bufferedImage.getHeight(); PrinterJob printerJob = PrinterJob.getPrinterJob(); printerJob.setPrintService(printService); printerJob.setCopies(copies); PageFormat pageFormat = printerJob.defaultPage(); pageFormat.setOrientation(isLandscape ? PageFormat.LANDSCAPE : PageFormat.PORTRAIT); Paper paper = new Paper(); paper.setSize(pageFormat.getWidth(), pageFormat.getHeight()); paper.setImageableArea(0.0, 0.0, paper.getWidth(), paper.getHeight()); pageFormat.setPaper(paper); printerJob.setPrintable(new Printable(){ @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException{ if (pageIndex == 0) { Graphics2D g2 = (Graphics2D)graphics; double xScale = 1; double xTranslate = 0; double yScale = 1; double yTranslate = 0; double widthScale = (pageFormat.getImageableWidth() / bufferedImage.getWidth()) * xScale; double heightScale = (pageFormat.getImageableHeight() / bufferedImage.getHeight()) * yScale; AffineTransform affineTransform = AffineTransform.getScaleInstance(widthScale, heightScale); affineTransform.translate(xTranslate, yTranslate); g2.drawRenderedImage(bufferedImage, affineTransform); g2.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY()); return PAGE_EXISTS; }else return NO_SUCH_PAGE; } }, pageFormat); printerJob.print(); 

这允许我打印肖像图片以适合给定的纸张和没有边框(适合纸张),我需要它来做相同的风景图片请。

这是我尝试使用肖像和风景图像时会发生什么的例子,所以你明白我的意思。 图像应始终适合纸张尺寸和无边框,在这种情况下为10×15厘米,

肖像图片:

景观图片:

不要使用PageFormat#getWidthPageFormat#getHeight ,而是使用PageFormat#getImageableWidthPageFormat#getImageableHeight

来自JavaDocs

返回页面可成像区域的高度/宽度,以1/72英寸为单位。 此方法考虑了页面的方向。

您还应该通过ImageableX/Y翻译打印机Graphics

 g2.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY()); 

可运行的例子

这是一个简单的可运行示例。 这段代码能够拍摄原件(左)并以纵向和横向打印,没有问题……

在此处输入图像描述

 import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class PrintTest100 { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } try { PrinterJob pj = PrinterJob.getPrinterJob(); pj.setJobName(" Print Component "); PageFormat pf = pj.defaultPage(); // pf.setOrientation(PageFormat.LANDSCAPE); // pf = pj.validatePage(pf); pj.setPrintable(new ImagePrintable(ImageIO.read(new File("..."))), pf); if (!pj.printDialog()) { return; } try { pj.print(); } catch (PrinterException ex) { ex.printStackTrace(); } } catch (IOException exp) { exp.printStackTrace(); } } }); } public static class ImagePrintable implements Printable { private int currentPage = -1; private Image cachedScaledImage = null; private BufferedImage master; public ImagePrintable(BufferedImage master) { this.master = master; } public double getScaleFactor(int iMasterSize, int iTargetSize) { double dScale = 1; if (iMasterSize > iTargetSize) { dScale = (double) iTargetSize / (double) iMasterSize; } else { dScale = (double) iTargetSize / (double) iMasterSize; } return dScale; } public double getScaleFactorToFit(BufferedImage img, Dimension size) { double dScale = 1; if (img != null) { int imageWidth = img.getWidth(); int imageHeight = img.getHeight(); dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size); } return dScale; } public double getScaleFactorToFit(Dimension original, Dimension toFit) { double dScale = 1d; if (original != null && toFit != null) { double dScaleWidth = getScaleFactor(original.width, toFit.width); double dScaleHeight = getScaleFactor(original.height, toFit.height); dScale = Math.min(dScaleHeight, dScaleWidth); } return dScale; } @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { int result = Printable.NO_SUCH_PAGE; if (pageIndex == 0) { result = Printable.PAGE_EXISTS; Graphics2D graphics2D = (Graphics2D) graphics; graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); int width = (int) Math.round(pageFormat.getImageableWidth()); int height = (int) Math.round(pageFormat.getImageableHeight()); if (currentPage != pageIndex || cachedScaledImage == null) { currentPage = pageIndex; double scaleFactor = getScaleFactorToFit(new Dimension(master.getWidth(), master.getHeight()), new Dimension(width, height)); int imageWidth = (int) Math.round(master.getWidth() * scaleFactor); int imageHeight = (int) Math.round(master.getHeight() * scaleFactor); cachedScaledImage = master.getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH); } double x = ((pageFormat.getImageableWidth() - cachedScaledImage.getWidth(null)) / 2); double y = ((pageFormat.getImageableHeight() - cachedScaledImage.getHeight(null)) / 2); graphics2D.drawImage(cachedScaledImage, (int) x, (int) y, null); graphics2D.setColor(Color.RED); graphics2D.drawRect(0, 0, width - 1, height - 1); } return result; } } } 

nb:我和Yosemite有一个问题,试图弄清楚如何从对话框中改变打印方向,最后,我放弃并通过从PrintJob更改PageFormat来强制它。 我在无数应用程序中使用了相同类型的代码而没有问题…

更新

原始图片:1920×1200

在此处输入图像描述