在Itextsharp中旋转,同时保留评论位置&取向

时间:2014-02-19 04:25:46

标签: .net pdf itextsharp

总而言之,我正在使用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)

抱歉,伪代码有点碎片,试图保持简短。如果我能提供任何其他信息,请告诉我。并提前感谢!

1 个答案:

答案 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版本的查看器中都不起作用。