我在C#.Net中使用iTextSharp创建了一个已签名的PDF。在已签名的PDF中,我想有一个有效的符号,这样当用户在Adobe Reader中打开它时,它就会显示一个绿色的勾号以及它的签名。
但在我的web应用程序中(一个带画布的html页面),我想从PDF中删除那个问号,这样它就不会像在这个屏幕上一样显示。
所以我想保留PDF的原始字节,其中 signatureappearance.Acro6Layers = false;
在代码中添加了这个符号。但是在我的查看器(带画布的html页面)中显示它之前,我想修改字节并删除这个黄色标记,这样它就不会显示 "签名未验证"。
我没有Aspose PDF-to-image渲染的经验,但看起来它可能只是简单地渲染了PDF中的签名外观。顺便说一下,这将是正确的做法。
由于Acrobat 6之前的额外图层都被绘制在保存文件的签名外观中,你必须清除它们。你可以像这样做。
using (PdfReader pdfReader = new PdfReader(source))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(dest, FileMode.Create, FileAccess.Write), '\0', true))
{
AcroFields fields = pdfStamper.AcroFields;
List<string> names = fields.GetSignatureNames();
foreach (string name in names)
{
PdfDictionary normal = PdfReader.GetPdfObject(fields.GetNormalAppearance(name)) as PdfDictionary;
PdfDictionary frm = normal?.GetAsDict(PdfName.RESOURCES)?.GetAsDict(PdfName.XOBJECT)?.GetAsStream(PdfName.FRM);
PdfDictionary frmResources = frm?.GetAsDict(PdfName.RESOURCES);
PdfDictionary frmXobjectResources = frmResources?.GetAsDict(PdfName.XOBJECT);
if (frmXobjectResources != null)
{
Console.WriteLine("Found XObject resources of FRM XObject");
clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N1);
clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N3);
clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N4);
pdfStamper.MarkUsed(frmXobjectResources);
pdfStamper.MarkUsed(frmResources);
pdfStamper.MarkUsed(frm);
}
}
}
用这个辅助方法:
void clearLayer(PdfWriter writer, PdfDictionary frmXobjectResources, PdfName layerName)
{
PdfStream existingLayer = frmXobjectResources.GetAsStream(layerName);
if (existingLayer != null)
{
PdfArray bBox = existingLayer.GetAsArray(PdfName.BBOX);
PdfTemplate newLayer = PdfTemplate.CreateTemplate(writer, 0, 0);
newLayer.BoundingBox = PdfReader.GetNormalizedRectangle(bBox);
frmXobjectResources.Put(layerName, newLayer.IndirectReference);
}
}
在不同的渲染器中, 你的原始示例文件的签名外观和上述代码所产生的文件的外观如下:
但有一点要提醒的是:如果文件有认证签名,而不仅仅是批准签名,特别是认证签名不允许修改,Acrobat很可能不喜欢这个结果。