• TwelveMonkeys处理图片


    TwelveMonkeys处理图片

    项目中用到图片处理功能,主要是调整tiff图片的dpi,并进行图片压缩。

    之前用的是jai的方式处理的,主要jar包是jai_imageio、jai_codec等。

    因为jai的包名为com.sun开头。甲方认为后续如果调整jdk可能会出问题(我了解的情况是:jai作为单独jar包引入,并未和jdk绑定,只是包名是com.sun开头),让调整为TwelveMonkeys的ImageIO-tiff。

    jai处理图片

    import javax.imageio.ImageIO;
    import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi;
    import com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriterSpi;
    import com.sun.media.jai.codec.ImageCodec;
    import com.sun.media.jai.codec.ImageEncoder;
    import com.sun.media.jai.codec.TIFFEncodeParam;
    import com.sun.media.jai.codec.TIFFField;
    import com.sun.media.jai.codecimpl.TIFFImageDecoder;
    import javax.imageio.spi.IIORegistry;
    import java.awt.image.RenderedImage;
    import java.io.ByteArrayInputStream;
    
    public class ImageUtil {
    
        private final static Logger logger = LoggerFactory.getLogger(ImageUtil.class);
    
        private static final double PRINTER_RESOLUTION = 300.0;
        private static final String COMPRESSION_TYPE = "CCITT T.6";
        private static final long[] DPI_DATA = {300L, 300L};
    
        static {
            IIORegistry registry = IIORegistry.getDefaultInstance();
            registry.registerServiceProvider(new TIFFImageWriterSpi());
            registry.registerServiceProvider(new TIFFImageReaderSpi());
        }
    
        /**
         * 修改tiff的像素值
         *
         * @param bout
         * @throws IOException
         */
        public static ByteArrayOutputStream changeResolution(byte[] bout) {
    
            try {
                RenderedImage renderedImage = ImageIO.read(new ByteArrayInputStream(bout));
                TIFFEncodeParam param = new TIFFEncodeParam();
                param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
                if (DPI_DATA[0] > 0 || DPI_DATA[1] > 0) {
                    int fieldCount = 1;
                    if (DPI_DATA[0] > 0 && DPI_DATA[1] > 0) {
                        fieldCount = 2;
                    }
                    TIFFField[] tiffFields = new TIFFField[fieldCount];
                    int index = 0;
                    if (DPI_DATA[0] > 0) {
                        long xdpiArray[][] = new long[1][2];
                        xdpiArray[0] = new long[]{DPI_DATA[0], 1};
                        TIFFField xRes = new TIFFField(TIFFImageDecoder.TIFF_X_RESOLUTION,
                                TIFFField.TIFF_RATIONAL, 1, xdpiArray);
                        tiffFields[index++] = xRes;
                    }
                    if (DPI_DATA[1] > 0) {
                        long ydpiArray[][] = new long[1][2];
                        ydpiArray[0] = new long[]{DPI_DATA[1], 1};
                        TIFFField yRes = new TIFFField(TIFFImageDecoder.TIFF_Y_RESOLUTION,
                                TIFFField.TIFF_RATIONAL, 1, ydpiArray);
                        tiffFields[index] = yRes;
                    }
                    param.setExtraFields(tiffFields);
                }
                // 输出到文件流
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageEncoder enc = ImageCodec.createImageEncoder("TIFF", out, param);
                enc.encode(renderedImage);
                out.close();
                return out;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    TwelveMonkeys ImageIO-tiff

    maven坐标

    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-tiff</artifactId>
        <version>3.6</version>
    </dependency>
    

    网上关于使用TwelveMonkeys ImageIO-tiff调整tiff的dpi的介绍不是很多,还是在TwelveMonkeys的github仓库issue中找到了启发。

    import com.twelvemonkeys.imageio.metadata.Entry;
    import com.twelvemonkeys.imageio.metadata.tiff.Rational;
    import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
    import com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry;
    import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadata;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.metadata.IIOMetadata;
    import javax.imageio.stream.ImageOutputStream;
    import java.awt.image.RenderedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class ImageUtil {
    
        private final static Logger logger = LoggerFactory.getLogger(ImageUtil.class);
    
        private static final double PRINTER_RESOLUTION = 300.0;
        private static final String COMPRESSION_TYPE = "CCITT T.6";
        private static final long DPI_DATA = 300L;
        private static final String FORMAT = "TIFF";
    
        /**
         * 修改tiff的像素值
         *
         * @param bout
         * @throws IOException
         */
        public static ByteArrayOutputStream changeResolution(byte[] bout) throws IOException {
            RenderedImage renderedImage = ImageIO.read(new ByteArrayInputStream(bout));
            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(FORMAT);
            ImageWriter writer = writers.next();
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionType(COMPRESSION_TYPE);
            param.setCompressionQuality(1f);
            final List<Entry> entries = new ArrayList<Entry>();
            entries.add(new TIFFEntry(TIFF.TAG_X_RESOLUTION, new Rational(DPI_DATA)));
            entries.add(new TIFFEntry(TIFF.TAG_Y_RESOLUTION, new Rational(DPI_DATA)));
            final IIOMetadata tiffImageMetadata = new TIFFImageMetadata(entries);
            // 输出到流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageOutputStream output = ImageIO.createImageOutputStream(out);
            writer.setOutput(output);
            writer.write(null, new IIOImage(renderedImage, null, tiffImageMetadata), param);
            out.close();
            return out;
        }
    
    }
    

    github issue地址https://github.com/haraldk/TwelveMonkeys/issues/439

    注意issue中回答的代码是错误的。正确的应该是 writer.write(null, new IIOImage(renderedImage, null, tiffImageMetadata), param);

  • 相关阅读:
    ArcGIS Engine开发之地图浏览
    ArcGIS Engine开发之地图文档保存
    ArcGIS Engine开发之地图基本操作(4)
    ArcGIS Engine开发之地图基本操作(3)
    ArcGIS Engine开发之地图基本操作(2)
    ArcGIS Engine开发之地图基本操作(1)
    ArcGIS Engine开发前基础知识(4)
    C#读取Excel的三种方式以及比较
    XtraGrid RepositoryItemCheckEdit 显示状态以及单选多选问题
    Dev GridControl数据修改后实时更新数据源
  • 原文地址:https://www.cnblogs.com/jimmyfan/p/13552445.html
Copyright © 2020-2023  润新知