iText7 C#.net核心从pdf文档中提取图像

时间:2019-02-28 23:49:59

标签: c# image pdf itext7

我知道之前也曾问过类似的问题,但是它们已经过时了(有些可以追溯到2006年)。

我有一个.net 3.5应用程序(带有iTextSharp 5),我正在转换为.net核心(iText 7),该内核从FedEx跟踪文档中提取签名,并通过SOAP服务以byte []数组的形式发送。多年来,此代码在进行较小的更新后一直运行良好。从Fedex返回的PDF文档中有几张图像,但签名块不是110x46图像(这是pdf文件中的fedex徽标,因此为什么我跳过它。)

PdfReader pdf = new PdfReader(FedexData);

for(Int32 iPage = 1; iPage <= pdfReader.NumberOfPages; iPage++)
{
   PdfDictionary pg = pdf.GetPageN(iPage);
   PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));
   PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));

   foreach(PdfName name in xobj.Keys)
   {
      PdfObject obj = xobj.Get(name);

      if(obj.IsIndirect())
      {
          PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
          String width = tg.Get(PdfName.WIDTH).ToString();
          String height = tg.Get(PdfName.HEIGHT).ToString();
          String decode = tg.Contains(PdfName.DECODEPARMS) ? tg.Get(PdfName.DECODEPARMS).ToString() : "";
          String bitspercomponent = tg.Contains(PdfName.BITSPERCOMPONENT) ? tg.Get(PdfName.BITSPERCOMPONENT).ToString() : "";
          String colorspace = tg.Contains(PdfName.COLORSPACE) ? tg.Get(PdfName.COLORSPACE).ToString() : "";
          if(width != "110" && height != "46" && bitspercomponent != "1")
          {
                ImageRenderInfo imgRI = ImageRenderInfo.CreateForXObject(new GraphicsState(), (PRIndirectReference)obj, tg);
                PdfImageObject image = imgRI.GetImage();
                Image dotnetImg = image.GetDrawingImage();

                if(dotnetImg != null)
                {
                // process image and update database

足以说明此代码不适用于iText7。我试图移植其中的一些,但似乎没有得到图像....所以我显然做错了一些事情,但我自己对iText7函数的无知,似乎并不能与旧版库向下兼容

有人可以给我指出iText7教程,该教程涉及提取存储在PDF文件中的图像吗?我找到了有关如何将PDF提取为图像(不是我想要的),如何将图像存储在PDF文档中(与我想要的相反)的教程,并且类似的问题答案都基于不再起作用的较早的库

谢谢, Vin

1 个答案:

答案 0 :(得分:0)

这是IEventListener的Java实现,可用于访问特定页面上的所有图像:

public class MyImageRenderListener implements IEventListener {

    protected String path;
    protected String extension;

    public MyImageRenderListener(String path) {
        this.path = path;
    }

    public void eventOccurred(IEventData data, EventType type) {
        switch (type) {
            case RENDER_IMAGE:
                try {
                    String filename;
                    FileOutputStream os;
                    ImageRenderInfo renderInfo = (ImageRenderInfo) data;
                    PdfImageXObject image = renderInfo.getImage();
                    if (image == null) {
                        return;
                    }

                    // You can access various value from dictionary here:
                    PdfString decodeParamsPdfStr = image.getPdfObject().getAsString(PdfName.DecodeParms);
                    String decodeParams = decodeParamsPdfStr != null ? decodeParamsPdfStr.toUnicodeString() : null;                      

                    byte[] imageByte = image.getImageBytes(true);
                    extension = image.identifyImageFileExtension();
                    // You can use raw image bytes directly, or write image to disk
                    filename = String.format(path, image.getPdfObject().getIndirectReference().getObjNumber(), extension);
                    os = new FileOutputStream(filename);
                    os.write(imageByte);
                    os.flush();
                    os.close();
                } catch (com.itextpdf.io.IOException | IOException e) {
                    System.out.println(e.getMessage());
                }
                break;

            default:
                break;
        }
    }

    public Set<EventType> getSupportedEvents() {
        return null;
    }
}

我已经评论了一些您可能感兴趣的部分。

这是实际上为所有页面或感兴趣的任何页面调用处理器的代码:

PdfDocument pdfDoc = new PdfDocument(new PdfReader(src));
IEventListener listener = new MyImageRenderListener(outPath);
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
    parser.processPageContent(pdfDoc.getPage(i));
}
pdfDoc.close();