使用PDFBox 2.0.24移除PDF二维码后文件变大且未删除求助
问题分析与修复方案
核心问题
- 二维码未成功移除:依赖XMP元数据的标题字段识别二维码,若图片无该元数据或标题不匹配,就无法识别;直接操作COS字典移除资源,未更新PDFBox的对象缓存,导致资源未真正删除。
- 文件体积暴涨:创建新文档时未继承原文档的压缩配置,重新生成的内容流和资源未启用压缩,原压缩内容被解压后写入新文档,导致体积大幅增大。
修复步骤
1. 修复二维码识别与移除逻辑
- 替换资源移除方式:不要直接修改COS字典,使用PDFBox提供的
PDResources.removeXObject()方法,确保更新对象缓存:// 替换原COS字典移除代码 pdResources.removeXObject(propertyName); - 优化二维码识别方式:依赖XMP元数据不可靠,可通过ZXing库识别图片是否为二维码,或结合图片尺寸、格式等特征判断:
// 示例:用ZXing识别二维码 BufferedImage img = pdImageXObject.getImage(); try { BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(img))); Result result = new MultiFormatReader().decode(bitmap); // 能解码出内容,判定为二维码 pdResources.removeXObject(propertyName); qrCodeCosName = propertyName.getName(); hasQRCodeOnPage = true; } catch (NotFoundException e) { // 不是二维码,跳过 }
2. 解决文件体积增大问题
- 启用文档压缩:保存文档时使用
PDFSaveOptions开启内容流和图片压缩:PDFSaveOptions saveOptions = new PDFSaveOptions(); saveOptions.setCompressContentStreams(true); // 压缩内容流 saveOptions.setCompressImages(true); // 压缩图片 saveOptions.setImageQuality(0.9f); // 可调整图片质量,平衡体积与清晰度 newDocument.save(destPath, saveOptions); - 避免创建新文档:直接在原文档上修改页面,减少资源重复复制:
// 原代码创建新文档改为直接操作原文档 PDDocument pdDocument = PDDocument.load(new File(sourcePath)); boolean hasModified = false; for (int i = 0; i < pdDocument.getNumberOfPages(); i++) { PDPage page = pdDocument.getPage(i); if (removeQRCodeImage(pdDocument, page, imgUniqueId + i)) { hasModified = true; } } if (hasModified) { PDFSaveOptions options = new PDFSaveOptions(); options.setCompressContentStreams(true); options.setCompressImages(true); pdDocument.save(destPath, options); } pdDocument.close();
3. 完善内容流处理逻辑
确保完全移除所有引用二维码的Do操作:
// 遍历内容流token时,正确移除COSName和Do操作 for (int j = 0; j < tokens.size(); j++) { Object token = tokens.get(j); if (token instanceof Operator) { Operator op = (Operator) token; if ("Do".equals(op.getName())) { COSName cosName = (COSName) tokens.get(j - 1); if (cosName.getName().equals(qrCodeCosName)) { // 移除已添加的COSName if (!newTokens.isEmpty()) { newTokens.remove(newTokens.size() - 1); } // 跳过当前Do操作,不添加到newTokens continue; } } } newTokens.add(token); }
内容的提问来源于stack exchange,提问作者Ayush
相关产品推荐
相关产品推荐

