/** * 接口设计 */ public interface ImageDPIProcessor { /** * 根据文件后缀扩展名判断是否能进行处理 * * @param fileName * @return */ public boolean canHandle(String fileName); /** * * @param path * @param dpi * dot per inch * @return * @throws IOException * @throws MalformedURLException */ public byte[] process(final BufferedImage srcimage, final int dpi) throws Exception;
JPEG 处理方式
public class JpegDPIProcessor implements ImageDPIProcessor { private String formatName = "jpeg"; @Override public byte[] process(BufferedImage image, int dpi) throws IOException { for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) { ImageWriter writer = iw.next(); ImageWriteParam writeParams = writer.getDefaultWriteParam(); writeParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); //调整图片质量 writeParams.setCompressionQuality(1f); IIOMetadata data = writer.getDefaultImageMetadata(new ImageTypeSpecifier(image), writeParams); Element tree = (Element) data.getAsTree("javax_imageio_jpeg_image_1.0"); Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0); jfif.setAttribute("Xdensity", dpi + ""); jfif.setAttribute("Ydensity", dpi + ""); jfif.setAttribute("resUnits", "1"); // density is dots per inch ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageOutputStream stream = null; try { stream = ImageIO.createImageOutputStream(out); writer.setOutput(stream); writer.write(data, new IIOImage(image, null, null), writeParams); } finally { stream.close(); } return out.toByteArray(); } return null; } @Override public boolean canHandle(String fileName) { assert fileName != null : "fileName should not be null"; return fileName.endsWith("jpg") || fileName.endsWith("jpeg") || fileName.endsWith("JPG") || fileName.endsWith("JPEG"); } }
PNG处理方式:
public class PngDPIProcessor implements ImageDPIProcessor { //1英寸是2.54里面 private static final double INCH_2_CM = 2.54d; @Override public boolean canHandle(String fileName) { assert fileName != null : "fileName should not be null"; return fileName.endsWith("png") || fileName.endsWith("PNG"); } @Override public byte[] process(BufferedImage image, int dpi) throws MalformedURLException, IOException { for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); 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; } ByteArrayOutputStream output = new ByteArrayOutputStream(); ImageOutputStream stream = null; try { setDPI(metadata, dpi); stream = ImageIO.createImageOutputStream(output); writer.setOutput(stream); writer.write(metadata, new IIOImage(image, null, metadata), writeParam); } finally { try { stream.close(); } catch (IOException e) { } } return output.toByteArray(); } return null; } private void setDPI(IIOMetadata metadata, int dpi) throws IIOInvalidTreeException { // 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); } }
原文:http://my.oschina.net/osgit/blog/530283