zoukankan      html  css  js  c++  java
  • 用java imageio调整图片DPI,例如从96调整为300

    因项目需求把图片的DPI值提升到300,否则OCR识别产生错乱:直接上源码:
    1、图片处理接口:

    package util.image.dpi;
    
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    
    /**
     * 图片处理接口设计
     * @author jffan
     *
     */
    public interface ImageDPIProcessor {
    
        /**
         * 根据文件后缀扩展名判断是否能进行处理
         * @param fileName
         * @return
         */
        public boolean canHandle(String fileName);
    
        /**
         * 处理图片,设置图片DPI值
         * @param path
         * @param dpi dot per inch
         * @return
         * @throws IOException
         */
        public byte[] process(final BufferedImage srcimage, final int dpi) throws Exception;
    }
    

    2、JEPG图片的实现类

    package util.image.dpi;
    
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.Iterator;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageTypeSpecifier;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.metadata.IIOMetadata;
    import javax.imageio.stream.ImageOutputStream;
    
    import org.w3c.dom.Element;
    
    /**
     * JPEG 处理方式
     * @author jffan
     *
     */
    public class JpegDPIProcessor implements ImageDPIProcessor {
    
        private String formatName = "jpeg";
    
        /**
         * 处理图片,设置图片DPI值
         * @param path
         * @param dpi dot per inch
         * @return
         * @throws IOException
         */
        @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;
    
        }
    
        /**
         * 根据文件后缀扩展名判断是否能进行处理
         * @param fileName
         * @return
         */
        @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");
        }
    }
    

     3、PNG图片的实现类

    package util.image.dpi;
    
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.util.Iterator;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageTypeSpecifier;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.metadata.IIOInvalidTreeException;
    import javax.imageio.metadata.IIOMetadata;
    import javax.imageio.metadata.IIOMetadataNode;
    import javax.imageio.stream.ImageOutputStream;
    
    /**
     * PNG图片的实现类
     * @author jffan
     *
     */
    public class PngDPIProcessor implements ImageDPIProcessor {
    	/**
    	 * 1英寸是2.54里面
    	 */
        private static final double INCH_2_CM = 2.54d;
    
        /**
         * 根据文件后缀扩展名判断是否能进行处理
         * @param fileName
         * @return
         */
        @Override
        public boolean canHandle(String fileName) {
            assert fileName != null : "fileName should not be null";
            return fileName.endsWith("png") || fileName.endsWith("PNG");
        }
    
        /**
         * 处理图片,设置图片DPI值
         * @param path
         * @param dpi dot per inch
         * @return
         * @throws IOException
         */
        @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;
        }
    
        /**
         * 设置图片的DPI值
         * @param metadata
         * @param dpi
         * @throws IIOInvalidTreeException
         * @author 范继峰
         * @date 2019年7月30日上午10:53:18
         * @return void
         */
        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);
        }
    }
    

      

  • 相关阅读:
    JAVA_SWT 事件的四种写法
    JAVA静态数据的初始化;
    Centos 安装freesurfer fsl matlab 等软件---转自网络
    ROC和AUC————摘在网络
    转自网络用LIBSVM进行回归预测的粗浅认识————————作者师梦
    fmri格式相关简介————转自网络
    fMRI数据分析处理原理及方法————转自网络
    装机、做系统必备:秒懂MBR和GPT分区表____转载网络
    【转】Thymeleaf自动在URL后加了;jsessionid=的问题
    LeetCode (85): Maximal Rectangle [含84题分析]
  • 原文地址:https://www.cnblogs.com/fanblogs/p/11268660.html
Copyright © 2011-2022 走看看