版权声明:转载时请务必保留以下作者信息和链接 作者:陈维(chenweionline@hotmail.com )作者的网站:http://www.chenwei.mobi
通常我们使用Java 编码输出图像默认的图像分辨率是72dpi(关于图像分辨率可以看我转载的一篇文章《图片分辨率介绍 》),PC显示器的设备分辨率一般在60~120dpi之间,而熟悉印刷行业的朋友都知道,印刷一张图像需要的图像分辨率一般是300dpi,就是说这样的图像在显示器上显示可能很细腻但是印刷输出的效果却非常粗糙。那么我们针对印刷或者其他需要高分辨率的应用场合,就需要输出更高分辨率的图像,可是纵观Java SE 中标准的ImageIO 库并没有提供设置DPI值的方法,那么怎么使用Java生成适合印刷或者更高分辨率的图像呢?
幸好,JAI_ImageIO 为我们解决了这个难题,或者只能说部分解决。目前JAI_ImageIO_1.1 对于设置DPI 信息的支持仅限于TIFF格式,我并没有在JAI_ImageIO_1.1 中找到针对其他图像格式(例如常见的JPEG)设置DPI 的方法。
JAI_ImageIO_1.1 中对于的TIFF 格式提供了2种途径(DOM 和 API)可以在图像编码时将DPI 信息设置进Meatadata。下面是一段创建图像并且以300dpi 编码输出的样例程序,它分别就这两种方法都做了实现,可以提供大家学习参考。编译运行需要引用JAI_ImageIO_1.1,可以从https://jai-imageio.dev.java.net/ 下载。
import
com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet;
import
com.sun.media.imageio.plugins.tiff.TIFFDirectory;
import
com.sun.media.imageio.plugins.tiff.TIFFField;
import
com.sun.media.imageio.plugins.tiff.TIFFTag;
import
java.awt.image.BufferedImage;
import
java.awt.image.RenderedImage;
import
java.io.File;
import
java.util.Iterator;
import
javax.imageio.IIOImage;
import
javax.imageio.ImageIO;
import
javax.imageio.ImageTypeSpecifier;
import
javax.imageio.ImageWriter;
import
javax.imageio.metadata.IIOInvalidTreeException;
import
javax.imageio.metadata.IIOMetadata;
import
javax.imageio.metadata.IIOMetadataNode;
import
javax.imageio.stream.FileImageOutputStream;
/***/
/** *设置自定义dpi值到TIFF格式图像的样例程序。 *需要JAI_ImageIO_1.1提供支持。*/
public
class
SetDPI4TIFF
...
{ private static StringMETADATA_NAME = " com_sun_media_imageio_plugins_tiff_image_1.0 " ; private static int DPI_X = 300 ; private static int DPI_Y = 300 ; public static void main(String[]args) throws Throwable ... { // Createsampleimage. RenderedImageimage = new BufferedImage( 256 , 256 ,BufferedImage.TYPE_3BYTE_BGR); // GetTIFFwriter. Iteratorwriters = ImageIO.getImageWritersByFormatName( " TIFF " ); if (writers == null || ! writers.hasNext()) ... { throw new IllegalStateException( " NoTIFFwriters! " ); } ImageWriterwriter= (ImageWriter)writers.next(); // Getthedefaultimagemetadata. ImageTypeSpecifierimageType = ImageTypeSpecifier.createFromRenderedImage(image); IIOMetadataimageMetadata = writer.getDefaultImageMetadata(imageType, null ); // SetDPI. StringfileName; Stringmethodology; if (args.length == 0 || args[ 0 ].equalsIgnoreCase( " DOM " )) ... { fileName = " dpi_dom.tif " ; setDPIViaDOM(imageMetadata); methodology = " DOM " ; } else ... { fileName = " dpi_api.tif " ; imageMetadata = setDPIViaAPI(imageMetadata); methodology = " API " ; } System.out.println(" Writing " + fileName + " using " + methodology + " methodology " ); // Writeimage. writer.setOutput( new FileImageOutputStream( new File(fileName))); writer.write( new IIOImage(image, null ,imageMetadata)); } /***/ /** *SetDPIusingDOMnodes.*/ private static void setDPIViaDOM(IIOMetadataimageMetadata) throws IIOInvalidTreeException ... { // GettheDOMtree. IIOMetadataNoderoot = (IIOMetadataNode)imageMetadata.getAsTree(METADATA_NAME); // GettheIFD. IIOMetadataNodeifd = (IIOMetadataNode)root.getElementsByTagName( " TIFFIFD " ).item( 0 ); // Get{X,Y}Resolutiontags. BaselineTIFFTagSetbase = BaselineTIFFTagSet.getInstance(); TIFFTagtagXRes = base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION); TIFFTagtagYRes = base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION); // Create{X,Y}Resolutionnodes. IIOMetadataNodenodeXRes = createRationalNode(tagXRes.getName(),tagXRes.getNumber(),DPI_X, 1 ); IIOMetadataNodenodeYRes = createRationalNode(tagYRes.getName(),tagYRes.getNumber(),DPI_Y, 1 ); // Append{X,Y}ResolutionnodestoIFDnode. ifd.appendChild(nodeXRes); ifd.appendChild(nodeYRes); // Setmetadatafromtree. imageMetadata.setFromTree(METADATA_NAME,root); } /***/ /** *CreatesanodeofTIFFdatatypeRATIONAL.*/ private static IIOMetadataNodecreateRationalNode(StringtagName, int tagNumber, int numerator, int denominator) ... { // Createthefieldnodewithtagnameandnumber. IIOMetadataNodefield = new IIOMetadataNode( " TIFFField " ); field.setAttribute( " name " ,tagName); field.setAttribute( " number " , "" + tagNumber); // CreatetheRATIONALnode. IIOMetadataNoderational = new IIOMetadataNode( " TIFFRational " ); rational.setAttribute( " value " ,numerator + " / " + denominator); // CreatetheRATIONALnodeandappendRATIONALnode. IIOMetadataNoderationals = new IIOMetadataNode( " TIFFRationals " ); rationals.appendChild(rational); // AppendRATIONALSnodetofieldnode. field.appendChild(rationals); return field; } /***/ /** *SetDPIusingAPI.*/ private static IIOMetadatasetDPIViaAPI(IIOMetadataimageMetadata) throws IIOInvalidTreeException ... { // DerivetheTIFFDirectoryfromthemetadata. TIFFDirectorydir = TIFFDirectory.createFromMetadata(imageMetadata); // Get{X,Y}Resolutiontags. BaselineTIFFTagSetbase = BaselineTIFFTagSet.getInstance(); TIFFTagtagXRes = base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION); TIFFTagtagYRes = base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION); // Create{X,Y}Resolutionfields. TIFFFieldfieldXRes = new TIFFField(tagXRes,TIFFTag.TIFF_RATIONAL, 1 , new long [][] ... { ... {DPI_X, 1 } } ); TIFFFieldfieldYRes = new TIFFField(tagYRes,TIFFTag.TIFF_RATIONAL, 1 , new long [][] ... { ... {DPI_Y, 1 } } ); // Append{X,Y}Resolutionfieldstodirectory. dir.addTIFFField(fieldXRes); dir.addTIFFField(fieldYRes); // Converttometadataobjectandreturn. return dir.getAsMetadata(); } }