itext获取内容大小

时间:2013-07-26 10:05:49

标签: pdf size itextsharp

我只花了几个小时在网上搜索。似乎其他人也有这个问题,但我找不到答案。

我有大量的PDF文件需要我们测量,即它们的高度和页面内容。

在Adobe Illustrator中,导入PDF时,您可以选择转到“边界框”。这正是我所需要的。

我尝试了很多方法,这里是大杂烩:

Dim pdfStream = IO.File.OpenRead(FilePath)
Dim img = PdfImages(pdfStream)
Dim pdfReader = New PdfReader(pdfStream)
Dim pdfDictionary = pdfReader.GetPageN(1)
Dim mediaBox = pdfDictionary.GetAsArray(PdfName.MEDIABOX)
Dim b = pdfReader.GetPageSize(pdfDictionary)
Dim ms = New MemoryStream
Dim document = New Document(pdfReader.GetPageSizeWithRotation(1))
Dim writer = PdfWriter.GetInstance(document, ms)
document.Open()
document.SetPageSize(pdfReader.GetPageSize(1))
document.NewPage()
Dim cb = writer.DirectContent
cb.Clip()
Dim pageImport = writer.GetImportedPage(pdfReader, 1)
pdfReader.Close()
pdfStream.Close()

我设法获得的是页面大小,这是无用的。我在一大堆PDF上试过这个,所以它不像一个腐败的文件或其他东西。

3 个答案:

答案 0 :(得分:7)

为了实现目标,

  

转向“边界框”。这正是我需要的

你实际上必须解决两个问题:

  1. 您必须更改某些PDF文档的各个页面的裁剪框。
  2. 您必须确定某个页面的边界框,即(我假设)包含页面所有可见内容的最小框(包含水平和垂直边)。
  3. 广告1)更改各个页面的裁剪框

    您不应该使用为该任务找到的代码。操作单个文档几乎总是最好使用PdfStamper,而不是PdfWriter.

    iText in Action — 2nd Edition示例CropPages.java / CropPages.cs显示了如何执行此操作。核心方法:

    public byte[] ManipulatePdf(byte[] src)
    {
      PdfReader reader = new PdfReader(src);
      int n = reader.NumberOfPages;
      PdfDictionary pageDict;
      PdfRectangle rect = new PdfRectangle(55, 76, 560, 816);
      for (int i = 1; i <= n; i++)
      {
        pageDict = reader.GetPageN(i);
        pageDict.Put(PdfName.CROPBOX, rect);
      }
      using (MemoryStream ms = new MemoryStream())
      {
        using (PdfStamper stamper = new PdfStamper(reader, ms))
        {
        }
        return ms.ToArray();
      }
    }
    

    (代码在内存中工作,即需要一个byte []并返回一个,但可以很容易地修改为在文件系统中工作。)

    如您所见,您实际操作PDF PdfReader中存在的PDF,然后仅使用PdfStamper存储更改的Pdf。

    但是,在您的情况下,所有页面都没有固定的矩形,而是您必须确定每个页面的矩形...

    广告2)确定某个网页的边界框

    要确定边界框,您实际上必须解析整个页面内容并确定每个绘制元素的尺寸。

    不幸的是,iText(Sharp)只在一定程度上以一种舒适的方式支持它:它提供了一个内容解析框架,但是这个框架还没有开箱即用的矢量图形。

    iText in Action — 2nd Edition示例ShowTextMargins.java / ShowTextMargins.cs显示了如何使用该框架来确定裁剪框(忽略了矢量图形)。基本代码:

    PdfReaderContentParser parser = new PdfReaderContentParser(reader);
    [...]
    TextMarginFinder finder = parser.ProcessContent(i, new TextMarginFinder());
    

    执行finderfinder.GetLlx(), finder.GetLly(), finder.GetUrx(),通过finder.GetUry()ProcessContent提供页面{{1}的边界框左下角和右上角的坐标}(矢量图形被忽略)。您可以使用这些数据构建一个矩形,用于在上面的代码中输入i

    如果你还需要考虑矢量图形,你必须在某种程度上扩展解析器命名空间类,以便为矢量图形操作符创建解析事件,并pageDict.Put(PdfName.CROPBOX, rect)也将这些事件带入帐户。有关此内容的更多信息,请阅读this answer

答案 1 :(得分:0)

Necromancing:
mkl的代码付诸实践(只需将一些小的白色文本放入矢量图形的左上角和右下角):

public static void StartManipulation()
{
    byte[] ba = System.IO.File.ReadAllBytes(@"D:\username\Documents\Downloads\itextsharp-master\itextsharp-master\src\CropTest\Files\dwg305.pdf");
    // FindBoundingBox(ba);
    ba = ManipulatePdf(ba);
    System.IO.File.WriteAllBytes(@"D:\username\Downloads\mysizedpdf.pdf", ba);
} // End Sub StartManipulation



public static byte[] ManipulatePdf(byte[] src)
{
    byte[] byteBuffer = null;

    using (iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(src))
    {
        iTextSharp.text.pdf.parser.PdfReaderContentParser parser = new iTextSharp.text.pdf.parser.PdfReaderContentParser(reader);
        int n = reader.NumberOfPages;
        iTextSharp.text.pdf.PdfDictionary pageDict;

        for (int pageNumber = 1; pageNumber <= n; pageNumber++)
        {
            pageDict = reader.GetPageN(pageNumber);

            iTextSharp.text.pdf.parser.TextMarginFinder finder = parser.ProcessContent(pageNumber, new iTextSharp.text.pdf.parser.TextMarginFinder());

            // iTextSharp.text.Rectangle pageSize = reader.GetPageSize(pageNumber);

            // Get Content Size
            float Llx = finder.GetLlx();
            float Lly = finder.GetLly();
            float Urx = finder.GetUrx();
            float Ury = finder.GetUry();
            //iTextSharp.text.pdf.PdfRectangle rect = new iTextSharp.text.pdf.PdfRectangle(55, 76, 560, 816);
            //iTextSharp.text.pdf.PdfRectangle rectTextContentSize = new iTextSharp.text.pdf.PdfRectangle(Llx, Lly, Urx, Ury);

            int SafetyMargin = 100;
            iTextSharp.text.pdf.PdfRectangle rectTextContentSize = new iTextSharp.text.pdf.PdfRectangle(Llx - SafetyMargin, Lly - SafetyMargin, Urx + SafetyMargin, Ury + SafetyMargin);

            pageDict.Put(iTextSharp.text.pdf.PdfName.CROPBOX, rectTextContentSize);
        } // Next i 

        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            using (iTextSharp.text.pdf.PdfStamper stamper = new iTextSharp.text.pdf.PdfStamper(reader, ms))
            { }

            byteBuffer = ms.ToArray();
        } // End Using ms

    } // End Using reader 

    return byteBuffer;
} // End Function ManipulatePdf 


public static System.Drawing.Size FindBoundingBox(byte[] src)
{
    System.Drawing.Size sze = default(System.Drawing.Size);
    // iTextSharp.text.pdf
    // iTextSharp.text.pdf.parser

    using (iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(src))
    {
        iTextSharp.text.pdf.parser.PdfReaderContentParser parser = new iTextSharp.text.pdf.parser.PdfReaderContentParser(reader);

        for (int pageNumber = 1; pageNumber <= reader.NumberOfPages; pageNumber++)
        {
            iTextSharp.text.pdf.parser.TextMarginFinder finder = parser.ProcessContent(pageNumber, new iTextSharp.text.pdf.parser.TextMarginFinder());

            iTextSharp.text.Rectangle pageSize = reader.GetPageSize(pageNumber);
            float Llx = finder.GetLlx();
            float Lly = finder.GetLly();
            float Urx = finder.GetUrx();
            float Ury = finder.GetUry();

            float PdfSharpLly = pageSize.Height - Lly;
            float PdfSharpUry = pageSize.Height - Ury;


            sze = new System.Drawing.Size((int)(Urx - Llx), (int)(Ury - Lly));


            System.Console.WriteLine("Width: {0}<r\nHeight: {1}", pageSize.Width, pageSize.Height);
            System.Console.WriteLine("Llx: {0}\r\nLly: {1}\r\nUrx: {2}\r\nUry: {3}\r\n", Llx, Lly, Urx, Ury);
        } // Next pageNumber 

    } // End Using reader 

    return sze;
} // End Function FindBoundingBox 

答案 2 :(得分:0)

我有一个代码,也许我可以帮助你

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BarcodeQRCode;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfDocument;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfRectangle;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.TextMarginFinder;
import com.itextpdf.text.pdf.qrcode.EncodeHintType;

public static void sign(String src){
        try {
            String line1 = "Sign By: (VINICIUS)";
            String line2 = "Security Seal Number: 123545678";


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] array = Files.readAllBytes(new File(src).toPath());
            int size = 36;
            String docUrl = "https://website.com";
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            BarcodeQRCode qrCode = new BarcodeQRCode(docUrl, size, size, hints);
            PdfReader reader = new PdfReader(array);
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            PdfGState gs1 = new PdfGState();
            gs1.setFillOpacity(0.5f);
            int pageCount = reader.getNumberOfPages();

            Float y1 = 30f;
            Float y2 = 20f;
            Float y3 = 10f;
            PdfArray cropbox;
            PdfDictionary pageDict = null;
            float resultX = 30 + size;
            float imgX = 15f;
            for (int i = 1; i <= pageCount; i++) {
                PdfContentByte contentByte = stamper.getOverContent(i);
                Rectangle pgSize = reader.getPageSizeWithRotation(i);
                if(pgSize.getHeight() > 842){
                    y1 = (float) (pgSize.getHeight() - 812);
                    y2 = (float) (pgSize.getHeight() - 822);
                    y3 = (float) (pgSize.getHeight() - 832);
                }
                pageDict = reader.getPageN(i);
                cropbox = pageDict.getAsArray(PdfName.CROPBOX);
                if(cropbox != null){
                    float wDoc     = pgSize.getWidth();
                    float hDoc     = pgSize.getHeight();
                    PdfNumber wCropboxNumber = cropbox.getAsNumber(2);
                    PdfNumber hCropboxNumber = cropbox.getAsNumber(3);
                    float wCropbox = wCropboxNumber.floatValue();
                    float hCropbox = hCropboxNumber.floatValue();
                    resultX = (wDoc - wCropbox)+30+size;
                    y1   = (hDoc - hCropbox) + 30;
                    y2   = (hDoc - hCropbox) + 20;
                    y3   = (hDoc - hCropbox) + 10;
                    imgX = (wDoc - wCropbox) + 15; 
                }


                contentByte.beginText();
                contentByte.setFontAndSize(FontFactory.getFont(FontFactory.HELVETICA).getBaseFont(), 7);
                contentByte.setColorFill(BaseColor.DARK_GRAY);
                contentByte.showTextAligned(Element.ALIGN_LEFT, line1, resultX, y1 , 0); // 30
                contentByte.showTextAligned(Element.ALIGN_LEFT, line2, resultX, y2 , 0); // 20

                //contentByte.showTextAligned(Element.ALIGN_LEFT, line1, resultX, y1 , 0); // 30 


                contentByte.endText();

                Image image = qrCode.getImage();
                image.setScaleToFitHeight(true);
                image.setAbsolutePosition(imgX , y3); // 10
                image.setBorder(Image.NO_BORDER);
                image.setSpacingAfter(0);
                image.setSpacingBefore(0);
                contentByte.addImage(image);
            }

            stamper.close();

            File assinado = new File("sign.pdf");
            if(assinado.exists()){
                assinado.delete();
            }

            FileUtils.writeByteArrayToFile(new File("sign.pdf"), outputStream.toByteArray());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }