总而言之,我正在使用Itextsharp从PDF导入特定页面,可能会旋转,调整大小或以其他方式更改该页面,并将其导出为新的PDF。为此,我正在使用Itext的PDFWriter类。我遇到的问题是,当使用writer类时,它似乎不包括在输出页面中出现在源页面上的可见注释(在我的例子中,它是注释)。有趣的是,它确实包括嵌入式OCR而没有问题。
此外,当使用Itext PDFcopy类时,它确实可以正常工作(将注释正确复制到源代码),遗憾的是,PDFcopy没有很多易于访问的功能,因为我需要处理各种各样的事情。页面(例如调整页面大小)。
所以我正在寻找两种解决方案之一:
- 我希望继续使用writer类,但需要它从源页面复制/复制任何可见的注释等,并将它们包含在输出中。
- 需要使用PDFCopy类调整页面大小的一些示例代码。有一个pdfcopy.Setpagesize函数(它不起作用,我怀疑这意味着我做错了),但我基本上不知道如何在需要调整大小时正确缩放源页面。
这里有一些伪代码可以让您了解我在使用PDFWriter类方面所处的位置:
'...
Dim MS As New MemoryStream()
Dim document As New Document
Dim WriterPDF As PdfWriter = PdfWriter.GetInstance(document, MS)
Dim reader As PdfReader = Nothing
Dim cb As PdfContentByte = WriterPDF.DirectContent
reader = New PdfReader(New MemoryStream(File.ReadAllBytes(FilePathList.Item(ItemNum))))
For Each PageItem As Integer In PageNumList
Dim page As PdfImportedPage = WriterPDF.GetImportedPage(reader, PageItem)
Dim PageSizeStandard As Rectangle = PageSize.LETTER
document.SetPageSize(PageSizeStandard)
Dim tm = New System.Drawing.Drawing2D.Matrix()
'code to resize, rotate etc... tm.scale, tm.rotate, etc.
cb.AddTemplate(page, tm)
document.NewPage()
next
作为替代方案,我用于轮换的PDFCopy代码涉及:
Dim MasterCopy As PdfCopy = New PdfCopy(document, New FileStream(outputPath, FileMode.Create))
'...
Dim PageDict As PdfDictionary = reader.GetPageN(PageItem)
' can get current rotation with this...
' Dim Rot As PdfNumber = PageDict.Get(PdfName.ROTATE)
'...
Dim RotatedPageSizeHeight As Single = reader.GetPageSizeWithRotation(PageItem).Height
Dim RotatedPageSizeWidth As Single = reader.GetPageSizeWithRotation(PageItem).Width
If RotatedPageSizeWidth > RotatedPageSizeHeight Then
PageDict.Put(PdfName.ROTATE, New PdfNumber(90))
'there is a Pdfname.Size, but no idea if that's even what I need or how to use it.
'with the writer class I use a matrix to scale the page, works fine.
End If
'...
MasterCopy.AddPage(page)
抱歉,伪代码有点碎片,试图保持简短。如果我能提供任何其他信息,请告诉我。并提前感谢!
答案 0 :(得分:3)
我创建了一个实现mkl建议的小样本:ScaleRotate。
PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfDictionary page;
for (int p = 1; p <= n; p++) {
page = reader.getPageN(p);
if (page.getAsNumber(PdfName.USERUNIT) == null)
page.put(PdfName.USERUNIT, new PdfNumber(2.5f));
page.remove(PdfName.ROTATE);
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
给定带有旋转页面,裁剪页面和注释的原始PDF pages.pdf。我们缩放并旋转某些页面,结果为pages_altered.pdf。
我们为所有尚未缩放的网页引入了2.5的 UserUnit 。如果您将 UserUnit 更改为0.5,您将看到它在Adobe Reader中没有任何效果。 PDF的ISO标准表明可用于用户单元的范围与实现无关。最初由Adobe编写的PDF规范1.7版说:“Acrobat 7.0支持的最大UserUnit值为75,000。”没有关于最小值的说法,但经验告诉我们Adobe Reader支持的最小值是1,这意味着你无法缩小。
对于旋转,您可以通过更改页面词典中的/Rotate
键来更改页面的旋转。在示例中,我删除了密钥,将横向显示的所有页面(/Rotate
的值为90)更改为纵向(/Rotate
的默认值为0)。您会注意到这对第4页没有任何影响。页面4未旋转。它看起来像横向页面,因为页面的尺寸是以宽度大于高度的方式创建的。
总结:在现有PDF中旋转页面是一块蛋糕,因此将页面缩放到更大的尺寸。如果要缩小页面大小,只能使用PdfWriter
(抛弃所有注释),并且需要在转换这些注释的所有/Rect
值之后单独复制注释注释。这是一项艰巨的任务。我们的一位客户需要几周的时间才能正确实现这一目标。如果那就是你想要的,请准备好花相同的时间。
免责声明:所有观看者都不支持 UserUnit 值。实现可能因使用的查看器而异。该功能是在PDF 1.6中引入的,这意味着该功能在任何仅支持较旧PDF版本的查看器中都不起作用。