5

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

我有一大堆 PDF 文件,我需要获得它们的测量值,即它们的高度和页面内容的宽度。

在 Adob​​e 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上试过这个,所以它不像一个损坏的文件或其他东西。

4

3 回答 3

7

为了实现你的目标,

修剪到“边界框”。这正是我需要的

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

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

广告 1)更改各个页面的裁剪框

您不应使用为该任务找到的代码。处理单个文档几乎总是最好使用PdfStamper,not aPdfWriter.

iText in Action — 第 2 版示例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 中存在的 PDF,PdfReader然后仅使用PdfStamper来存储更改后的 Pdf。

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

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

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

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

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

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

finderviafinder.GetLlx(), finder.GetLly(), finder.GetUrx(),finder.GetUry()after that ProcessContentexecution 提供页面边界框的左下角和右上角的坐标(i忽略矢量图形)。您可以使用这些数据来构造一个矩形,用它来pageDict.Put(PdfName.CROPBOX, rect)输入上面的代码。

但是,如果您还需要考虑矢量图形,则必须在某种程度上扩展解析器命名空间类,以便为矢量图形运算符创建解析事件,并且TextMarginFinder还要考虑这些事件。有关更多信息,请阅读此答案

于 2013-07-26T12:16:26.290 回答
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 
于 2016-03-23T11:41:05.557 回答
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();
        }

    }
于 2018-03-20T21:13:03.103 回答