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;
}
答案 0 :(得分:2)
页面定义的一部分是&#34; MediaBox&#34;它控制页面的大小。此属性采用两个位置来指定矩形的两个相对角的坐标。虽然不是必需的,但大多数PDF指定左下角,然后是右上角。此外,大多数PDF使用左下角的0x0
,然后使用页面顶角的宽度和高度。因此,一个8.5x11英寸的PDF将是0,0
和612,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。
另外,正如我在第一段中所说,大多数应用程序使用左上角,但这不是一个严格的规则。有人可以指定右上角和左下角,甚至是左上角和右下角。这是一个很难考虑的因素,但至少应该注意这一点。