itextsharp中的Pdf合并问题-合并后Pdf看起来失真
我有一个简单的场景,从PDF文档中提取页面(或者将文档分成两部分,如果您愿意的话),然后将这些部分合并回一个新文档,并在其中添加新页面 但是,在一种特定情况下,生成的文档与原始文档的不同之处在于,与源文档相比,两页(在本例中为第4页和第5页)看起来失真 我怎样才能避免页面失真?下面的复制代码已使用iTextSharp版本5.5.0.0和5.5.6.0(目前最新版本)进行了测试。 您可以找到我使用的输入文件itextsharp中的Pdf合并问题-合并后Pdf看起来失真,pdf,pdf-generation,itextsharp,Pdf,Pdf Generation,Itextsharp,我有一个简单的场景,从PDF文档中提取页面(或者将文档分成两部分,如果您愿意的话),然后将这些部分合并回一个新文档,并在其中添加新页面 但是,在一种特定情况下,生成的文档与原始文档的不同之处在于,与源文档相比,两页(在本例中为第4页和第5页)看起来失真 我怎样才能避免页面失真?下面的复制代码已使用iTextSharp版本5.5.0.0和5.5.6.0(目前最新版本)进行了测试。 您可以找到我使用的输入文件 void Main() { var pathPrefix=@“
void Main()
{
var pathPrefix=@“C:\temp”;//TODO更改
var inputDocPath=@“input.pdf”;
var part1=ExtractPages(Path.Combine(pathPrefix,inputDocPath),1,2);
var outputPath1=Path.Combine(路径前缀,“part1.pdf”);
writealBytes(outputPath1,part1);
var part2=ExtractPages(Path.Combine(pathPrefix,inputDocPath),3);
var outputPath2=Path.Combine(路径前缀,“part2.pdf”);
writealBytes文件(outputPath2,part2);
var merged=Merge(新[]{
输出路径1,
输出路径2
});
var mergedPath=Path.Combine(路径前缀,“output.pdf”);
writealBytes(mergedPath,merged);
}
//页面大小:
//输入:8,26x11,68;8,26x11,69;8,26x11,69;8,26x11,69;8,26x11,69;8,26x11,68;8,26x11,68
//输出:8,26x11,68;8,26x11,69;8,26x11,69;8,26x11,69;8,26x11,69;8,26x11,68;8,26x11,68
公共静态字节[]合并(字符串[]文档路径)
{
字节[]合并文件;
使用(MemoryStream MemoryStream=new MemoryStream())
使用(文档=新文档())
{
PdfSmartCopy PdfSmartCopy=新的PdfSmartCopy(文档、内存流);
document.Open();
foreach(documentpath中的var docPath)
{
PdfReader reader=新PdfReader(docPath);
尝试
{
reader.consolidateNameDestinations();
var numberOfPages=reader.numberOfPages;
对于(int page=0;page页数| |结束页已解析>页数)
Format(“错误:页面索引({0},{1})超出范围。文档有{2}个页面。”,
startPage,endPageResolved,numberOfPages).Dump();
字节[]输出文件;
使用(var doc=new Document())//注意使用reader.GetPageSizeWithRotation(起始页)?
使用(var msOut=new MemoryStream())
{
var pdfCopyProvider=新的PdfCopy(doc,msOut);
doc.Open();
对于(var i=startPage;i我可以使用您的代码和您的iTextSharp 5.5.6重现该问题。事实上,尽管图像不仅失真,还被其他图像替换了!在内部查看结果PDF时,可以观察到:
- 最初,第3页到第5页各有各自的资源字典,其中包含不同的条目
- 拆分后,作为
part2.pdf
的第1页到第3页,它们仍然有不同的资源词典
- 不过,在最终的合并结果中,第3页到第5页都引用了相同的资源字典对象,即原始第3页资源的副本
(由于第3页包含与第4页和第5页图像同名的图像,因此第3页图像显示在第4页和第5页。)
在这里,PdfSmartCopy
似乎比自己更聪明,使用PdfCopy
反而创建了预期的结果
我假设PdfSmartCopy
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;
}