TwelveMonkeys處理圖片
阿新 • • 發佈:2020-08-24
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);