2 回答
TA贡献1842条经验 获得超21个赞
此代码替换图像流,而无需更改 COSWriter(这听起来很可怕),但是我尝试的 PDF 的经验是编码图像不正确,即 JPEG 2000 编码器中存在错误,因此请检查结果 PDF 。
public class SO57972743
{
public static void main(String[] args) throws IOException
{
System.out.println("supported formats: " + Arrays.toString(ImageIO.getReaderFormatNames()));
try (PDDocument doc = PDDocument.load(new File("test.pdf")))
{
// get 1st level images only here (there may be more in form XObjects!)
PDResources res = doc.getPage(0).getResources();
for (COSName name : res.getXObjectNames())
{
PDXObject xObject = res.getXObject(name);
if (xObject instanceof PDImageXObject)
{
replaceImageWithJPX(xObject);
}
}
doc.save("test-result.pdf");
}
}
private static void replaceImageWithJPX(PDXObject xObject) throws IOException
{
PDImageXObject img = (PDImageXObject) xObject;
BufferedImage bim = img.getOpaqueImage(); // the mask (if there) won't be touched
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean written = ImageIO.write(bim, "JPEG2000", baos);
if (!written)
{
System.err.println("write failed");
return;
}
// replace image stream
try (OutputStream os = img.getCOSObject().createRawOutputStream())
{
os.write(baos.toByteArray());
}
img.getCOSObject().setItem(COSName.FILTER, COSName.JPX_DECODE); // replace filter
img.getCOSObject().removeItem(COSName.COLORSPACE); // use the colorspace in the image itself
}
}
TA贡献1871条经验 获得超13个赞
通过使用处理所有图像流的自定义并使用 JPXDecode 过滤器重新编码它们, pdfbox
可以压缩所有图像。无法这样做,但带有插件的 JAI 库可以生成 JPEG2000 图像。压缩因子是可配置的,并且可以在不损失太多质量的情况下实现高压缩比。COSWriter
pdfbox
通过另外使用FlateDecode
滤波器,可以获得更多的压缩,而不会造成质量损失。
添加回答
举报