如何将iText Image转换为AWT BufferedImage(iText 2.1.7环境)
iText 2.1.7 版本Image转BufferedImage实现方案
iText 2.1.7 没有提供直接转BufferedImage的公开API,核心实现分两步:优先提取原始图像字节直接解析,拿不到原始字节时先转AWT Image再重绘为BufferedImage,全程用公开API,不存在版本兼容问题。
完整转换代码
import com.lowagie.text.Image; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; public class ItextImageConverter { public static BufferedImage toBufferedImage(Image itextImage) throws Exception { // 优先读取原始图像字节,无画质损失、性能最好 byte[] rawImageData = itextImage.getRawData(); if (rawImageData != null && rawImageData.length > 0) { try (ByteArrayInputStream inputStream = new ByteArrayInputStream(rawImageData)) { return ImageIO.read(inputStream); } } // 无原始字节的场景(如iText生成的条码、矢量转光栅图像),走重绘逻辑 java.awt.Image awtImage = itextImage.getAwtImage(); int width = awtImage.getWidth(null); int height = awtImage.getHeight(null); // 用ARGB色彩模式兼容透明通道 BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); bufferedImage.getGraphics().drawImage(awtImage, 0, 0, null); return bufferedImage; } }
压缩图片体积的参考实现
拿到BufferedImage后就可以自由控制压缩参数,比iText自带的压缩配置灵活度高很多,以下是JPG压缩示例:
import com.sun.image.codec.jpeg.JPEGImageWriteParam; import javax.imageio.IIOImage; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.ImageOutputStream; import java.io.ByteArrayOutputStream; import java.util.Iterator; // 转换得到BufferedImage后,压缩为质量0.3的JPG BufferedImage sourceImage = ItextImageConverter.toBufferedImage(originalItextImage); ByteArrayOutputStream compressedBaos = new ByteArrayOutputStream(); Iterator<ImageWriter> jpgWriters = ImageIO.getImageWritersByFormatName("jpg"); ImageWriter jpgWriter = jpgWriters.next(); JPEGImageWriteParam writeParam = new JPEGImageWriteParam(null); writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 压缩质量范围0-1,数值越小体积越小 writeParam.setCompressionQuality(0.3f); try (ImageOutputStream ios = ImageIO.createImageOutputStream(compressedBaos)) { jpgWriter.setOutput(ios); jpgWriter.write(null, new IIOImage(sourceImage, null, null), writeParam); } // 用压缩后的字节重新生成iText Image对象即可写入PDF Image compressedImage = Image.getInstance(compressedBaos.toByteArray());
注意事项
- 不要用反射读取iText内部私有字段实现转换,2.1.7不同小修订版的内部字段名有差异,容易出兼容问题
- 带透明通道的图片不要转JPG格式,会出现黑底异常,这类图可以转PNG后通过降低色深、调整采样率压缩体积
内容的提问来源于stack exchange,提问作者wytten
相关产品推荐
相关产品推荐

