如何用C#的iText html2Pdf提取JBIG2Decode过滤的PDF单色扫描图像?
解决iText提取JBIG2格式单色扫描图像的报错问题
问题描述
使用C#基于iText html2Pdf库提取PDF中的单色扫描图像时,尽管官方说明支持JBIG2模式,但运行代码时抛出错误:iText.Kernel.Exceptions.PdfException: 'Filter /JBIG2Decode is not supported.',原代码示例如下:
PdfReader reader = new PdfReader(pdfFilePath); try { using (var pdfDoc = new PdfDocument(reader)) { for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++) { PdfDictionary pageDict = pdfDoc.GetPage(i).GetPdfObject(); PdfDictionary pageResources = pageDict.GetAsDictionary(PdfName.Resources); PdfDictionary pageXObjects = pageResources.GetAsDictionary(PdfName.XObject); PdfName imgName = pageXObjects.KeySet().First(); PdfStream imgStream = pageXObjects.GetAsStream(imgName); imgStream.SetData(reader.ReadStreamBytesRaw(imgStream)); PdfArray array = new PdfArray(); array.Add(PdfName.JBIG2Decode); imgStream.Put(PdfName.Filter, array); result = imgStream.GetBytes(); } } } catch (Exception ex) { } finally { reader.Close(); }
原因及解决方案
iText核心库默认不包含JBIG2解码实现,需额外引入依赖包才能支持该格式:
- 安装NuGet包:
iText.Jbig2和iText.BouncyCastle-adapter(JBIG2解码依赖BouncyCastle加密库的适配组件)
原代码存在两个关键问题:
- 手动设置
Filter为JBIG2Decode属于多余操作,会干扰iText的自动解码逻辑,应保留PDF原有Filter设置 - 直接操作
PdfStream获取字节的方式不正确,需使用PdfImageXObject统一处理图像解码
修正后的代码
using iText.Kernel.Pdf; using iText.Kernel.Pdf.Xobject; using System.Linq; byte[] result = null; PdfReader reader = new PdfReader(pdfFilePath); try { using (var pdfDoc = new PdfDocument(reader)) { for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++) { PdfDictionary pageDict = pdfDoc.GetPage(i).GetPdfObject(); PdfDictionary pageResources = pageDict.GetAsDictionary(PdfName.Resources); PdfDictionary pageXObjects = pageResources.GetAsDictionary(PdfName.XObject); if (pageXObjects != null && pageXObjects.Size() > 0) { PdfName imgName = pageXObjects.KeySet().First(); PdfStream imgStream = pageXObjects.GetAsStream(imgName); // 使用PdfImageXObject自动处理解码,包括JBIG2格式 PdfImageXObject imageXObject = new PdfImageXObject(imgStream); // 获取解码后的图像字节 result = imageXObject.GetImageBytes(); } } } } catch (Exception ex) { // 可添加自定义异常处理逻辑 } finally { reader.Close(); }
内容的提问来源于stack exchange,提问作者Pawel
相关产品推荐
相关产品推荐

