[英]Java - set DPI to print image
我有一堆.jpg图像,我想用固定尺寸(厘米)打印它们(用墨水在纸上)。 假设image1.png是400x600像素,我想以300 dpi打印它。 我尝试过使用PrinterJob和Printable实现,但似乎我无法指定DPI。 这是代码片段:
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new PrintableDeck(cardDB));
PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
attr.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
attr.add(new MediaPrintableArea(8,21,210-16,296-42,MediaPrintableArea.MM));
attr.add(MediaSizeName.ISO_A4);
attr.add(new Copies(1));
attr.add(OrientationRequested.PORTRAIT);
attr.add(PrintQuality.HIGH);
//attr.add(Fidelity.FIDELITY_TRUE);
job.print(attr);
和
public class PrintableDeck implements Printable {
BufferedImage image;
public PrintableDeck(DB cardDB){
// This load an image into 'image'
BufferedImage image = cardDB.getCard(5462).getBufferedImage();
}
public int print(Graphics graphics, PageFormat pf, int page)
throws PrinterException{
if(page>0){
return NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) graphics;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
double pageHeight = pf.getImageableHeight();
double pageWidth = pf.getImageableWidth();
// This print ONLY ~596x842, as if page is 72 DPI
System.out.println("Imageable WH: "+pageWidth+" x "+pageHeight);
// This print correctly 400x600
System.out.println("Image: "+images.get(0).getWidth(null)+" x "+images.get(0).getHeight(null));
g2.drawImage(image, 0, 0, null);
g2.dispose();
return PAGE_EXISTS;
}
}
正如你在上面看到的,我有PageFormat.getImageableHeight()~842和PageFormat.getImageableWidth()~595。如果页面是300 DPI,我预计这些值要高得多,大约3000 x 2500.我缺少什么?
非常感谢。
如果图像的元数据中没有先前定义的DPI,Java会将图像的DPI设置为默认的java 72dpi,因此最好将图像按照Java 72dpi默认分辨率调整到其尺寸,最好添加300dpi分辨率对于您的图像元数据,因此,它将在正确的可打印区域尺寸中以更好的分辨率进行调整,除了设置打印机分辨率,介质尺寸和介质可打印区域属性之外,您还可以将dpi设置为保存的图像。 http://www.javased.com/?post=321736中的这种方法:
private void saveGridImage(File output,BufferedImage gridImage) throws IOException {
output.delete();
final String formatName = "png";
for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) {
ImageWriter writer = iw.next();
ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
continue;
}
setDPI(metadata);
final ImageOutputStream stream = ImageIO.createImageOutputStream(output);
try {
writer.setOutput(stream);
writer.write(metadata, new IIOImage(gridImage, null, metadata), writeParam);
} finally {
stream.close();
}
break;
}
}
private void setDPI(IIOMetadata metadata) throws IIOInvalidTreeException {
double INCH_2_CM = 2.54;
// for PMG, it's dots per millimeter
double dotsPerMilli = 1.0 * DPI / 10 / INCH_2_CM;
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
horiz.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
vert.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
dim.appendChild(horiz);
dim.appendChild(vert);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
root.appendChild(dim);
metadata.mergeTree("javax_imageio_1.0", root);
}
然后添加打印属性:
attr.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
attr.add(new MediaPrintableArea(8,21,210-16,296-42,MediaPrintableArea.MM));
attr.add(MediaSizeName.ISO_A4);
获得更好的图像质量和视图分辨率。
这是我的代码,请注意我使用的是Scalr。
private String autoResizeImage(String image, int width, int dpi, String prefix) throws IllegalArgumentException, ImagingOpException, IOException {
File file = new File(image);
BufferedImage img = ImageIO.read(file);
BufferedImage result = Scalr.resize(img, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, width, Scalr.OP_ANTIALIAS);
File outputfile = new File(prefix);
PNGEncodeParam penc = PNGEncodeParam.getDefaultEncodeParam(result);
double meter2inchRatio = 1d / 0.0254d;
int dim = (int) (dpi * meter2inchRatio) + 1;
penc.setPhysicalDimension(dim, dim, 1);
// resize orginal image
JAI.create("filestore", result, outputfile.getAbsolutePath(), "PNG", penc);
return outputfile.getAbsolutePath();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.