Pdf合并问题在itextsharp - Pdf合并后看起来扭曲



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

然而,在一个特定的情况下,结果文档与原始文档不同,因为有几个页面(在本例中为第4页和第5页)与源文档相比看起来是扭曲的。

我怎样才能避免书页变形?下面的复制代码已经在iTextSharp 5.5.0.0和5.5.6.0版本(目前最新版本)上进行了测试。您可以在这里找到我使用的输入文件。

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;
}

我可以用iTextSharp 5.5.6的代码和测试文件重现这个问题。实际上,这些图像不仅扭曲了,而且被其他图像所取代!在内部检查结果PDF,可以看到:

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

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

不知何故,PdfSmartCopy似乎在这里胜过了自己,而使用PdfCopy却产生了预期的结果。

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

值得注意的是,使用Java和iText的等效测试smartmerge . Java是否没有显示相同的问题,其结果与预期一致。

因此,这看起来像是iTextSharp端口或。net的问题。

最新更新