无法标记某些PDF

时间:2014-08-11 17:32:01

标签: pdf itextsharp

PDF标记适用于我尝试过的几乎所有文档。但是,客户扫描了一些页面,他的计算机生成了一个耐冲压的PDF文档。嵌入的图像文件是JBIG2格式,但我不确定这是否重要。我用Apache的pdfbox调试了PDF,我可以看到文本是嵌入式的。它只是没有出现。

以下是不会盖章的PDF:http://demo.clearvillageinc.com/plans.pdf

我的代码:

static void Main(string[] args) {
    string stamp = "<div style=\"color:#F00;\">Reviewed for Code Compliance</div>";
    string fileName = @"C:\temp\source.pdf";
    string outputFileName = @"C:\temp\source-output.pdf";

    // Open a destination stream.
    using (var destStream = new System.IO.MemoryStream()) {
        using (var sourceReader = new PdfReader(fileName)) {

            // Convert the HTML into a stamp.
            using (var stampData = FromHtml(stamp)) {
                using (var stampReader = new PdfReader(stampData)) {
                    using (var stamper = new PdfStamper(sourceReader, destStream)) {
                        stamper.Writer.CloseStream = false; 
                        // Add the stamp stream to the source document.
                        var stampPage = stamper.GetImportedPage(stampReader, 1);

                        // Process all of the pages in the source document.
                        for (int i = 1; i <= sourceReader.NumberOfPages; i++) {
                            var canvas = stamper.GetOverContent(i);
                            canvas.AddTemplate(stampPage, 0, -50);
                        }
                    }
                }
            }
        }

        // Finished.  Save the file.    
        using (var fs = new System.IO.FileStream(outputFileName, FileMode.Create)) {
            destStream.Position = 0;
            destStream.CopyTo(fs);
        }
    }
}

public static System.IO.Stream FromHtml(string html) {
    var ms = new System.IO.MemoryStream();

    // Convert html to pdf.
    using (var document = new iTextSharp.text.Document()) {
        var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, ms);
        writer.CloseStream = false;

        document.Open();

        using (var sr = new System.IO.StringReader(html)) {
            XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, sr);
        }
    }

    ms.Position = 0; // Reset for reading.
    return ms;
}

1 个答案:

答案 0 :(得分:2)

页面定义的一部分是&#34; MediaBox&#34;它控制页面的大小。此属性采用两个位置来指定矩形的两个相对角的坐标。虽然不是必需的,但大多数PDF指定左下角,然后是右上角。此外,大多数PDF使用左下角的0x0,然后使用页面顶角的宽度和高度。因此,一个8.5x11英寸的PDF将是0,0612,792(8.5 * 72 = 612和11 * 72 = 792),这将被写为0,0,612,792

但是,您扫描的PDF因任何原因决定将0,7072视为左下角,将614,7864视为右上角。这仍然给我们(几乎)一个8.5x11的页面大小,但如果你试图在0,0绘制一些东西,它将比实际页面低7,772像素。您可以在Acrobat Pro中通过向外缩小(我为1%),选择“工具”,“编辑对象”然后执行“全选”来查看此内容。你也应该看到一些远远被选中的东西。

要解决这个问题,您需要尊重页面的界限。

for (int i = 1; i <= sourceReader.NumberOfPages; i++) {
    //Get the page to be stamped
    var pageToBeStamped = sourceReader.GetPageSize(i);

    var canvas = stamper.GetOverContent(i);

    //Offset our new page by 50 pixels off of the destination page's bottom
    canvas.AddTemplate(stampPage, pageToBeStamped.Left, pageToBeStamped.Bottom - 50);
}

上面的代码获取导入页面的矩形,并使用底部偏移50像素(来自原始代码)。此外,虽然在您的情况下不是问题,但我们使用导入的页面的实际左边缘而不是零。

但是,此代码仍然可以破解。第一段中的数学使用72,这是PDF的默认值,但可以更改。大多数人都不会改变它,但大多数人也不会改变0,0。目前,您的-50假定为72,它提供了从顶部边缘移动印章大约七分之一英寸的视觉感知。如果您遇到这种情况,您将要查看retrieving the user unit

另外,正如我在第一段中所说,大多数应用程序使用左上角,但这不是一个严格的规则。有人可以指定右上角和左下角,甚至是左上角和右下角。这是一个很难考虑的因素,但至少应该注意这一点。