更新时间:2023-12-03 17:15:16
不要使用 PageFormat#getWidth
或 PageFormat#getHeight
,请使用 PageFormat #getImageableWidth
和 PageFormat#getImageableHeight
而不是
Don't use PageFormat#getWidth
or PageFormat#getHeight
, use PageFormat#getImageableWidth
and PageFormat#getImageableHeight
instead
来自 JavaDocs
返回页面可成像区域的高度/宽度,以1/72英寸为单位。此方法考虑了页面的方向。
Return the height/width, in 1/72nds of an inch, of the imageable area of the page. This method takes into account the orientation of the page.
您还应该翻译打印机 Graphics
由 ImageableX / Y
...
You should also translate the printer Graphics
by the ImageableX/Y
...
g2.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());
可运行的示例
这是一个简单的可运行示例。这段代码能够拍摄原版(左图)并以纵向和横向打印,而不会出现问题......
This is a simple runnable example. This code was able to take the original (left) and print it both in portrait and landscape without issue...
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有一个问题,试图弄清楚如何从对话框中改变打印方向,最后,我放弃并通过更改 PageFormat
来强制它 PrintJob的
。我在无数应用程序中使用了相同类型的代码而没有问题...
nb: I had an issue with Yosemite, trying to figure out how to change the print orientation from the dialog, in the end, I gave up and forced it by changing the PageFormat
from the PrintJob
. I've used this same type of code in countless applications without issues before...
已更新
原始图片:1920x1200
Original Image: 1920x1200