C# 使用ITextSharp合并PDF并删除空白

C# 使用ITextSharp合并PDF并删除空白,c#,winforms,pdf,itextsharp,C#,Winforms,Pdf,Itextsharp,我在处理图像PDF文件(仅包含图像的PDF文件,无文本)时遇到问题。有两个PDF文件img1、img2,我想将其中两个合并为一个A4页的PDF文件 我试过下面的代码 string Img1 = "C:/temp/image1.pdf"; string Img2 = "C:/temp/image2.pdf"; string MergedFile = "C:/temp/Combo.pdf"; //Create our PDF readers PdfReader r1 = new PdfReader

我在处理图像PDF文件(仅包含图像的PDF文件,无文本)时遇到问题。有两个PDF文件img1、img2,我想将其中两个合并为一个A4页的PDF文件

我试过下面的代码

string Img1 = "C:/temp/image1.pdf";
string Img2 = "C:/temp/image2.pdf";
string MergedFile = "C:/temp/Combo.pdf";

//Create our PDF readers
PdfReader r1 = new PdfReader(Img1);
PdfReader r2 = new PdfReader(Img2);

//Our new page size, an A3 in landscape mode
iTextSharp.text.Rectangle NewPageSize = PageSize.A3.Rotate();

using (FileStream fs = new FileStream(MergedFile, FileMode.Create, 
                                  FileAccess.Write, FileShare.None))
{
    //Create our document without margins
    using (Document doc = new Document(NewPageSize, 0, 0, 0, 0))
    {
        using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
        {
            doc.Open();
            //Get our imported pages
            PdfImportedPage imp1 = w.GetImportedPage(r1, 1);
            PdfImportedPage imp2 = w.GetImportedPage(r2, 1);
            //Add them to our merged document at specific X/Y coords
            **w.DirectContent.AddTemplate(imp1, 0, 0);
            w.DirectContent.AddTemplate(imp2, 0, -350);**
            doc.Close();
        }
    }
}
r1.Close();
r2.Close();
所以当我执行上面的代码时,因为我提到了y坐标,它将结合pdf,两个图像将仅在一个页面上

但我不想那样做

这里我只是举两个图像的例子,但实际上有20多个图像(转换成PDF)

因此,根据图像大小,它应该组合文件。我不能为每个文件提供修复y坐标

有谁能帮我把多个PDF合并成一个没有空格的PDF吗


从结构上讲,以下是您想要做的:

  • 分配一个“合适”大小的新页面
  • 合并页面的内容流
  • 合并页面的资源
  • 调整所有注释(如果有)
第一步很容易,其余的,第二步很容易,第三步不太容易(并且会有使第二步复杂化的副作用)。我会提前告诉你我在订单上撒了谎

合并内容流将是直截了当的。您需要做的是一个四步流程(我将在这里介绍我对PDF非常了解,但iTextSharp不太了解):

  • 插入gsave运算符(q)
  • 插入变换运算符(cm)以变换到要显示内容的位置。在您的情况下,它将是
    1 0 0 1 X Y cm
  • 从当前页面复制内容流
  • 插入grestore操作符(Q)
  • 要合并资源,您必须查看新创建页面的资源,对于当前页面,对PDF页面中每类资源中的每个资源执行以下三项操作之一(XObject、字体、颜色空间、ExtGState、图案、着色、ProcSet-尽管对于ProcSet,您可以将每个ProcSet设置为整个套件,并且不会造成任何伤害):

  • 如果资源存在于新创建的页面中,但名称不同,请将其标记为重命名
  • 如果新创建的页面中不存在该资源,并且没有同名资源,请将其复制到中
  • 如果新创建的页面中不存在资源,并且存在名称冲突,请将资源重命名为不在新创建页面中的合成名称,然后将其复制到中
  • 现在回到我的谎言。在资源合并中,您可能需要为当前页面构建一个映射,将旧资源名称映射到新资源名称。在将内容流从一个复制到下一个的过程中,需要将内容流中引用的所有资源名称映射到资源合并步骤中构建的新名称

    要调整注释,必须通过调整每个注释中的Rect属性将注释移动到新位置。您还需要重置/Parent属性。对于任何文本标记批注,都需要调整四边形


    现在,在这里,所有这些工作都将陷入困境。如果页面旋转,这将不起作用。如果页面有裁剪框,则必须查看它并调整裁剪区域以模拟裁剪。如果页面已旋转且具有文本批注,则需要注意批注标志,以确保纵横比正确。如果文档在任何具有转到操作/目标的页面上都有链接注释,则需要调整这些注释

    那么,原始PDF中是否存在空白,而您只想裁剪图像,然后合并?@ChrisHaas是的,没错,但我不想这样做-您不想这样做只是因为您不知道y坐标?还是有其他原因?如果只是因为y坐标,您可以简单地将iTextSharp解析器类应用于源页面,以确定每个页面的y坐标范围,并由此计算
    AddTemplate
    调用的y。@Prashant Bhojani:您解决问题了吗。这对我来说很有趣。@Higune我还是没有得到我想要的。