使用ITextSharp获取PDF中图像的位置(X,Y,宽度,高度)

时间:2018-12-14 16:39:44

标签: c# pdf itext

我有一个问题是:画一个矩形以覆盖PDF中的所有图像。 我已经知道图像可以写为图像,但也可以写为图形矢量。

我想获取普通图像的位置(X,Y,宽度,高度)(例如保存为位图),并在其上绘制矩形,以不覆盖页面上的其他元素,例如该图像下的文字(我不如果图像仅覆盖整个页面的30%,则希望覆盖整个页面)。到目前为止,我已经编写了两个获取图像的功能:

request.form.getlist('check')

我调用函数 public List<Image> GetImagesFromPdf(string path) { List<Image> imageList = new List<Image>(); PdfReader reader = new PdfReader(path); for (int i=1;i<reader.NumberOfPages;i++) { PdfDictionary pdfDict = reader.GetPageN(i); imageList.AddRange(GetImagesFromDocument(pdfDict, reader)); } return imageList; } private List<Image> GetImagesFromDocument(PdfDictionary dict, PdfReader doc) { List<Image> imageList = new List<Image>(); PdfDictionary resources = (PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES))) as PdfDictionary; PdfDictionary objects = (PdfReader.GetPdfObject(resources.Get(PdfName.XOBJECT))) as PdfDictionary; if (objects != null) { foreach (PdfName objKey in objects.Keys) { PdfObject obj = objects.Get(objKey); if (obj.IsIndirect()) { PdfDictionary tg = (PdfDictionary)(PdfReader.GetPdfObject(obj)); PdfName objectType = (PdfName)(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE))); if ( PdfName.IMAGE.Equals(objectType) ||PdfName.IMAGEB.Equals(objectType) || PdfName.IMAGEC.Equals(objectType) || PdfName.IMAGEI.Equals(objectType) ) { int xrefIdx = ((PRIndirectReference)obj).Number; PdfObject pdfObj = doc.GetPdfObject(xrefIdx); PdfStream str = (PdfStream)(pdfObj); iTextSharp.text.pdf.parser.PdfImageObject pdfImage = new iTextSharp.text.pdf.parser.PdfImageObject((PRStream)str); System.Drawing.Image img = pdfImage.GetDrawingImage(); imageList.Add(img); } else if (PdfName.FORM.Equals(objectType) || PdfName.GROUP.Equals(objectType)) { imageList.AddRange(GetImagesFromDocument(tg, doc)); } } } } return imageList; } ,然后为每个Page i运行函数:GetImagesFromPdf。这导致以pdf格式显示正确数量的图像,但是我真的不知道如何获取位置(X,Y,宽度,高度)...。 我还能使用其他东西吗?还是我应该为此使用其他机制?

任何帮助将不胜感激。 PS。我注意到了一些... 我也尝试实现GetImagesFromDocument接口,并且我注意到当pdf中有图像时,将调用函数IExtRenderListener。 有一个函数无法调用对象RenderImage,结果很有趣,我得到了这些值(该函数称为GetImageCTM()):

The function is called GetImageCTM()

当我尝试覆盖以图形矢量形式编写的图像时,我失败了。没有图像被覆盖,但是我得到了15 000个非常小的矩形,不幸的是没有一个可见。 我使用了这段代码:

renderInfo

确定已经解决,解决方案在这里:

  public void ModifyPath(PathConstructionRenderInfo renderInfo)
    {
        if (renderInfo.Operation == PathConstructionRenderInfo.RECT)
        {
            float x = renderInfo.SegmentData[0];
            float y = renderInfo.SegmentData[1];
            float w = renderInfo.SegmentData[2];
            float h = renderInfo.SegmentData[3];
            Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
            Vector b = new Vector(x + w, y, 1).Cross(renderInfo.Ctm);
            Vector c = new Vector(x + w, y + h, 1).Cross(renderInfo.Ctm);
            Vector d = new Vector(x, y + h, 1).Cross(renderInfo.Ctm);

            Rectangle rect = new Rectangle(x,y,x+w, y+h); //is that correct ?
        }
        else
        {
            for (int i = 0; i < renderInfo.SegmentData.Count - 1; i += 2)
            {
                float x = renderInfo.SegmentData[i];
                float y = renderInfo.SegmentData[i + 1];
                Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
              //  Rectangle rect = new Rectangle(x, y, x + ..., y + ...); What to do here ?
            }
        }
        modifyPathCounter++;
    }

1 个答案:

答案 0 :(得分:1)

您的两种方法可以(直接或间接)为您提供与页面相关的资源,仅此而已,它们无法告诉您该资源在页面上的何处(或根本没有使用)。因此,这不会引起任何后果。

但是您的IExtRenderListener方法确实是您的选择。而且您的观察是正确的,ImageCtm是代表应用于原始图像的仿射变换的矩阵,与原点的1x1正方形相比。

只需将该变换应用于1x1单位正方形的角即可在页面上获得图像的角。