【问题标题】:Pdf Merge issue in itextsharp - PDF looks distorted after Mergeitextsharp 中的 Pdf 合并问题 - 合并后 PDF 看起来失真
【发布时间】:2015-08-28 09:18:30
【问题描述】:

我有一个简单的场景,我从 PDF 文档中提取页面(或将文档分成两部分,如果您愿意的话)并将这些部分合并回一个新文档,并可选择在其间添加新页面。

但是,在一种特定情况下,生成的文档与原始文档的不同之处在于,与源文档相比,这几页(在本例中为第 4 页和第 5 页)看起来扭曲了。

如何避免页面失真?下面的复制代码已经用 iTextSharp 版本 5.5.0.0 和 5.5.6.0(目前最新)进行了测试。 你可以找到我使用的输入文件here

void Main()
{              
                var pathPrefix = @"C:\temp"; // TODO change
                var inputDocPath = @"input.pdf";

                var part1 = ExtractPages(Path.Combine(pathPrefix, inputDocPath), 1, 2);
                var outputPath1 = Path.Combine(pathPrefix, "part1.pdf");
                File.WriteAllBytes(outputPath1, part1);

                var part2 = ExtractPages(Path.Combine(pathPrefix, inputDocPath), 3);
                var outputPath2 = Path.Combine(pathPrefix, "part2.pdf");
                File.WriteAllBytes(outputPath2, part2);

                var merged = Merge(new[] {
                                                                                                                             outputPath1, 
                                                                                                                             outputPath2
                                                                                                              });

                var mergedPath = Path.Combine(pathPrefix, "output.pdf");
                File.WriteAllBytes(mergedPath, merged);
}

//Page sizes:
//  input: 8,26x11,68; 8,26x11,69; 8,26x11,69; 8,26x11,69; 8,26x11,69; 8,26x11,68; 8,26x11,68
// output: 8,26x11,68; 8,26x11,69; 8,26x11,69; 8,26x11,69; 8,26x11,69; 8,26x11,68; 8,26x11,68

public static byte[] Merge(string[] documentPaths)
{
                byte[] mergedDocument;

                using (MemoryStream memoryStream = new MemoryStream())
                using (Document document = new Document())
                {
                               PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document, memoryStream);
                               document.Open();

                               foreach (var docPath in documentPaths)
                               {
                                               PdfReader reader = new PdfReader(docPath);
                                               try
                                               {
                                                               reader.ConsolidateNamedDestinations();
                                                               var numberOfPages = reader.NumberOfPages;
                                                               for (int page = 0; page < numberOfPages;)
                                                               {
                                                                              PdfImportedPage pdfImportedPage = pdfSmartCopy.GetImportedPage(reader, ++page);
                                                                              pdfSmartCopy.AddPage(pdfImportedPage);
                                                               }
                                               }
                                               finally
                                               {
                                                               reader.Close();
                                               }
                               }

                               document.Close();
                               mergedDocument = memoryStream.ToArray();
                }

                return mergedDocument;
}


public static byte[] ExtractPages(string pdfDocument, int startPage, int? endPage = null)
{
                var reader = new PdfReader(pdfDocument);
                var numberOfPages = reader.NumberOfPages;
                var endPageResolved = endPage.HasValue ? endPage.Value : numberOfPages;
                if (startPage > numberOfPages || endPageResolved > numberOfPages)
                               string.Format("Error: page indices ({0}, {1}) out of bounds. Document has {2} pages.", 
                                                                                 startPage, endPageResolved, numberOfPages).Dump();

                byte[] outputDocument;
                using (var doc = new Document()) // NOTE use reader.GetPageSizeWithRotation(startPage) ?
                using (var msOut = new MemoryStream())
                {
                               var pdfCopyProvider = new PdfCopy(doc, msOut);                       
                               doc.Open();
                               for (var i = startPage; i <= endPageResolved; i++)
                               {
                                               var page = pdfCopyProvider.GetImportedPage(reader, i);
                                               pdfCopyProvider.AddPage(page);
                               }
                               doc.Close();
                               reader.Close();                
                               outputDocument = msOut.ToArray();
                }

                return outputDocument;
}

【问题讨论】:

  • 这确实很奇怪。顺便说一句,这些图像不仅失真,还被其他图像替换。不知何故,PdfSmartCopy 似乎在这里比自己聪明,而是使用PdfCopy 来创建预期的结果......
  • 谢谢!这行得通。 itextsharp 中的错误?
  • 这是我的假设,是的,但也可能是文档中的一些错误仅在非常特定的情况下导致问题。 IMO 这需要更深入地分析。
  • 我尝试使用 Java/iText 重现该问题,参见。 SmartMerging.java。不幸的是,问题并没有在那里发生。因此,这看起来像是 iTextSharp 或 .Net 的问题。
  • 我将发布我的 cmets 作为答案。这将使这个问题再次成为人们关注最近活动的焦点。也许一些 ITextSharp 工程师会读到它

标签: pdf pdf-generation itextsharp


【解决方案1】:

我可以通过 iTextSharp 5.5.6 使用您的代码和 test file 重现该问题。但实际上,这些图像不仅失真,它们还被其他图像替换!在内部检查结果 PDF,观察到:

  • 最初,第 3 页到第 5 页各有自己的 Resource 字典,其中包含彼此不同的条目。
  • 拆分后,作为part2.pdf的第1页到第3页,他们仍然拥有不同的Resource字典。
  • 不过,在最终的合并结果中,第 3 页到第 5 页都引用了同一个 Resource 字典对象,即原始第 3 页资源的副本!

(由于第 3 页包含与第 4 页和第 5 页上的图像同名的图像,这导致第 3 页的图像显示在第 4 页和第 5 页上。)

不知何故,PdfSmartCopy 似乎在这里比自己聪明,而是使用 PdfCopy 来创建预期的结果。

我假设 PdfSmartCopy 错误地认为这些源字典相同,可能是一些没有实际相等性检查的哈希冲突。

值得注意的是,使用 Java 和 iText 进行的等效测试SmartMerging.java没有显示相同的问题,其结果符合预期。

因此,这看起来像是 iTextSharp 端口或一般 .Net 的问题。

【讨论】:

  • 这是一个错误,在 iText 和 iTextSharp 中,直到版本 5.5.7。将在下一个版本中修复。
猜你喜欢
  • 2012-08-25
  • 2012-10-22
  • 2012-11-21
  • 2013-03-09
  • 2023-03-22
  • 1970-01-01
  • 2011-01-15
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多