我只花了几个小时在网上搜索。似乎其他人也有这个问题,但我找不到答案。
我有大量的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上试过这个,所以它不像一个腐败的文件或其他东西。
答案 0 :(得分:7)
为了实现目标,
转向“边界框”。这正是我需要的
你实际上必须解决两个问题:
广告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());
执行finder
后finder.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();
}
}