2015-08-28 130 views
2

後,我有一個簡單的場景,我提取從PDF文檔中的頁面(或兩個部分,拆分文檔,如果你願意)和部分合併到一個新的文件,可以選擇在兩者之間添加新頁面。PDF合併問題iTextSharp的 - 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; 
} 
+0

這確實很奇怪。順便說一句,圖像不僅僅是*失真*,它們已被*替換*其他的。不知何故,'PdfSmartCopy'似乎在這裏取勝,使用'PdfCopy'代替創建預期的結果... – mkl

+0

謝謝!這工作。 itextsharp中的錯誤? –

+0

這是我的假設,是的,但它也可能是文檔中的一些錯誤,僅在非常特定的情況下才會導致問題。 IMO需要更深入地分析。 – mkl

回答

1

我可以使用您的代碼和您的test file與iTextSharp 5.5.6重現該問題。其實,雖然圖片不僅僅是扭曲,它們已被替換成被其他人!內部檢查結果PDF,一個人觀察到:

  • 最初3頁至第5各自都有各自的資源含有比對方的那些不同的條目字典。
  • 通過part2.pdf 3拆分後,最多,爲1頁,他們仍然有不同的資源字典。
  • 在最後的合併結果,不過,第3頁至第5指的都是同一資源字典對象,原來的第3頁的資源的副本!

(如第3頁中包含具有相同的名稱作爲關於圖4和5的頁面圖像的圖像中,這導致頁面上示4和5的頁面3個圖像)

不知何故PdfSmartCopy似乎智取本身在這裏,使用PdfCopy代替創建預期結果。

我認爲PdfSmartCopy錯誤地認爲這些源字典相同,可能沒有實際的平等檢查一些哈希衝突。

請注意,使用Java和iText進行的等效測試而不是顯示相同問題,其結果與預期相同。

因此,這看起來像一般iTextSharp的端口或.Net的問題。

+0

這是iText和iTextSharp中的一個bug,版本高達5.5.7。將在下一個版本中修復。 – rhens