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);