You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用iText7仅移除PDF每页的QR码且不破坏其他内容?

使用iText7移除PDF中的QR码且避免页面内容变形的解决方案

问题分析

你当前的代码直接调用stream.clear()清空QR码对应的PdfStream,这会破坏PDF的资源引用结构——页面内容流仍然保留着对该XObject的绘制指令,但资源本身已失效,导致渲染时出现文本或组件变形。此外,仅通过尺寸判断QR码的逻辑极易误删其他方形图片,准确性不足。

解决方案

正确的做法是修改页面内容流,移除对目标QR码XObject的绘制指令,而非直接清空资源流。同时,建议结合图像内容识别(如ZXing库)来精准判断QR码,避免误操作。

步骤1:精准识别QR码

使用ZXing库检测图像是否为QR码,替代仅靠尺寸判断的逻辑:

import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;

private static boolean isQRCode(PdfImageXObject image) {
    try {
        BufferedImage bufferedImage = image.getBufferedImage();
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
        Result result = new MultiFormatReader().decode(bitmap);
        return result != null;
    } catch (Exception e) {
        return false;
    }
}

步骤2:修改页面内容流,移除QR码绘制指令

通过PdfCanvasProcessor遍历页面内容流,拦截并移除绘制QR码XObject的Do指令:

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvasProcessor;
import com.itextpdf.kernel.pdf.canvas.parser.EventType;
import com.itextpdf.kernel.pdf.canvas.parser.IEventListener;
import com.itextpdf.kernel.pdf.canvas.parser.data.IEventData;
import com.itextpdf.kernel.pdf.canvas.parser.data.XObjectDoEvent;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;
import java.util.HashSet;
import java.util.Set;

public void removeQRCodes(PdfDocument pdfDoc) {
    for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
        PdfPage page = pdfDoc.getPage(i);
        Set<PdfName> qrXObjectNames = new HashSet<>();

        // 识别页面中的QR码XObject
        var resources = page.getResources().getPdfObject();
        var xObjects = resources.getAsDictionary(PdfName.XObject);
        if (xObjects != null) {
            for (PdfName name : xObjects.keySet()) {
                var obj = xObjects.get(name);
                if (obj instanceof com.itextpdf.kernel.pdf.PdfStream stream) {
                    var image = new PdfImageXObject(stream);
                    if (isQRCode(image)) {
                        qrXObjectNames.add(name);
                    }
                }
            }
        }

        // 修改内容流,移除QR码的绘制指令
        if (!qrXObjectNames.isEmpty()) {
            var newContentStream = new com.itextpdf.kernel.pdf.PdfStream();
            var processor = new PdfCanvasProcessor(new IEventListener() {
                @Override
                public void eventOccurred(IEventData data, EventType type) {
                    if (type == EventType.XOBJECT_DO) {
                        XObjectDoEvent doEvent = (XObjectDoEvent) data;
                        if (qrXObjectNames.contains(doEvent.getXObjectId())) {
                            // 跳过绘制QR码的指令
                            return;
                        }
                    }
                    // 将其他指令写入新内容流
                    data.getCanvas().writeCommandsToStream(newContentStream);
                }

                @Override
                public Set<EventType> getSupportedEvents() {
                    return Set.of(EventType.ALL);
                }
            });
            processor.processPageContent(page);
            // 替换原页面内容流
            page.put(PdfName.Contents, newContentStream);
        }
    }
}

关键说明

  • 直接清空资源流会导致PDF结构损坏,修改内容流移除绘制指令才是安全的方式。
  • 结合ZXing识别QR码能大幅提升准确性,避免误删普通方形图片。
  • 处理完成后,记得保存修改后的PdfDocument:pdfDoc.save(new FileOutputStream("output.pdf"));

内容的提问来源于stack exchange,提问作者Vivek Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:57:16