首页 > 解决方案 > 在旋转的文档上添加签名字段

问题描述

我正在尝试在旋转的文档上添加签名字段,但我不想在签名字段上应用旋转,它应该以 0 旋转添加到旋转页面上。

我尝试了以下方法,但它对我不起作用。

page.SetIgnorePageRotationForContent(true);

谁能提供这个问题的解决方案?

屏幕截图

签名外观代码片段:

    PdfFormXObject layer2Object = _pdfSignatureAppearance.GetLayer2();

    PdfCanvas pdfCanvas = new PdfCanvas(layer2Object, _pdfSigner.GetDocument());
    PdfPage page = _pdfSigner.GetDocument().GetPage(signingRequest.Page <= 0 ? 
    signingRequest.PageNumber : signingRequest.Page);
    page = page.SetIgnorePageRotationForContent(false);
    int pageRotation = page.GetRotation();
    Canvas appearanceCanvas = new Canvas(pdfCanvas, _pdfSigner.GetDocument(), 
    layer2Object.GetBBox().ToRectangle());

    ImageData signatureImageData = 
    ImageDataFactory.Create(signingRequest.SignatureImage);
    Image signatureImage = new Image(signatureImageData);
    signatureImageData.SetRotation(0f);
    ImageData logoImageData = 
    ImageDataFactory.Create(Convert.FromBase64String(signingRequest.Logo));
    Image logoImage = new Image(logoImageData);
 logoImageData.SetRotation(0f);

KeyValuePair<string, SignatureAppearanceField> handSignatureKey = appearanceFieldSettings.Where(o => o.Key == SignatureAppearanceAttributes.HAND_SIGNATURE.ToString()).FirstOrDefault();
 appearanceAttributes = new Paragraph().SetWidth(UnitValue.CreatePercentValue(100)).SetHeight(UnitValue.CreatePercentValue(100)).SetMargin(0.01f).SetStrokeWidth(0.1f);
 handSignatureImage.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.LEFT);
 handSignatureImage = handSignatureImage.SetAutoScale(true);
 handSignatureImage.SetMarginLeft((handSignatureKey.Value.X / aspectRatio) + 10);
 if (appearanceFieldSettings.ContainsKey("COMPANY_LOGO"))
 {
 if (fieldSettings.Key == SignatureAppearanceAttributes.COMPANY_LOGO.ToString())
 {
 IList<Image> images = new List<Image>();
 KeyValuePair<string, SignatureAppearanceField> companySignatureKey = appearanceFieldSettings.Where(o => o.Key == SignatureAppearanceAttributes.COMPANY_LOGO.ToString()).FirstOrDefault();
 companyLogoImage.SetAutoScale(true);
 companyLogoImage.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.RIGHT);
 companyLogoImage.SetMarginLeft((companySignatureKey.Value.Width / aspectRatio) - 20);
 images.Add(handSignatureImage);
 images.Add(companyLogoImage);
 appearanceAttributes.AddAll(images);
if (pageRotation > 0)
 {
 handSignatureImage.SetRotationAngle((Math.PI / 180) * pageRotation);
 companyLogoImage.SetRotationAngle((Math.PI / 180) * pageRotation);
 appearanceAttributes.SetRotationAngle((Math.PI / 180) * pageRotation);
 }
appearanceCanvas.Add(appearanceAttributes);
 }
 }
 else
 {
 if (pageRotation > 0)
 {
 handSignatureImage.SetRotationAngle((Math.PI / 180) * pageRotation);
 appearanceAttributes.SetRotationAngle((Math.PI / 180) * pageRotation);
 }
 appearanceAttributes.Add(handSignatureImage);
 appearanceCanvas.Add(appearanceAttributes);
 }

设置签名者和签名原因;

    KeyValuePair<string, SignatureAppearanceField> signingReasonKey = appearanceFieldSettings.Where(o => o.Key == SignatureAppearanceAttributes.SIGNING_REASON.ToString()).FirstOrDefault();
 string reason = !string.IsNullOrEmpty(signingRequest.WitnessReason) ? signingRequest.WitnessReason : signingRequest.SigningReason;
 if (reason.Length > 25)
 reason = reason.Substring(0, 25) + " ...";
 Text signingReasonText = null;
 appearanceAttributes = new Paragraph().SetFontSize(signingReasonKey.Value.Font.FontSize / aspectRatio).SetMargin(0.01f).SetStrokeWidth(0.1f);
 if (signingReasonKey.Value.ShowLabel)
 {
 signingReasonText = new Text(signingReasonKey.Value.LabelName + ": " + reason);
 }
 else
 {
 signingReasonText = new Text(reason);
 }
if (pageRotation > 0)
 {
 appearanceAttributes.SetRotationAngle((Math.PI / 180) * pageRotation);
 }
appearanceAttributes.Add(signingReasonText);
 appearanceCanvas.Add(appearanceAttributes);

在此处输入图像描述

标签: c#.netpdfitext7

解决方案


我使用了您的示例文件中的修订版,它有两个空的签名字段并且尚未签名。此外,我使用了您签名图像的重建版本。

使用 iText 默认外观

作为第一次检查,我应用了常规 iText 签名代码,其中 iText 本身填充了签名的外观:

using (PdfReader pdfReader = new PdfReader(PDF_SOURCE))
{
    PdfSigner pdfSigner = new PdfSigner(pdfReader, File.Create(PDF_DEST), new StampingProperties().UseAppendMode());
    ImageData imageData = ImageDataFactory.Create(IMAGE_SOURCE);

    pdfSigner.SetFieldName("SH_SIGNATURE_417868");

    PdfSignatureAppearance sigAppearance = pdfSigner.GetSignatureAppearance();
    sigAppearance.SetContact("ContactInfo");
    sigAppearance.SetLocation("Location");
    sigAppearance.SetReason("SigningReason");
    sigAppearance.SetLayer2Text("Muddassir Awan");
    sigAppearance.SetSignatureGraphic(imageData);
    sigAppearance.SetRenderingMode(RenderingMode.GRAPHIC_AND_DESCRIPTION);
    sigAppearance.SetSignatureCreator("Muddassir Awan");

    int estimatedSize = 12000;
    pdfSigner.SignExternalContainer(new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached), estimatedSize);
}

结果:

截屏

因此,这是可行的。

但是,显然,您希望数据以不同的方式排列,因此我们必须尝试在本质上与 iText 的外观生成代码相同,只是组件的排列方式不同。

使用自定义外观

由于 iText 代码有效(如上所示)并且您的代码引用了我在此处没有的许多变量,因此我从头开始编写此代码,从 iText 借用代码(PdfSignatureAppearance.GetAppearance()更准确地说),旨在创建有点类似于您的非旋转文档的屏幕截图:

using (PdfReader pdfReader = new PdfReader(PDF_SOURCE))
{
    PdfSigner pdfSigner = new PdfSigner(pdfReader, File.Create(PDF_DEST), new StampingProperties().UseAppendMode());

    ImageData signatureImageData = ImageDataFactory.Create(IMAGE_SOURCE);
    Image signatureImage = new Image(signatureImageData);

    pdfSigner.SetFieldName("SH_SIGNATURE_417868");

    PdfSignatureAppearance sigAppearance = pdfSigner.GetSignatureAppearance();
    sigAppearance.SetContact("ContactInfo");
    sigAppearance.SetLocation("Location");
    sigAppearance.SetReason("SigningReason");
    sigAppearance.SetSignatureCreator("Muddassir Awan");

    PdfPage page = pdfSigner.GetDocument().GetPage(sigAppearance.GetPageNumber());
    int rotation = page.GetRotation();

    PdfFormXObject layer2Object = sigAppearance.GetLayer2();
    Rectangle rect = layer2Object.GetBBox().ToRectangle();
    PdfCanvas pdfCanvas = new PdfCanvas(layer2Object, pdfSigner.GetDocument());

    if (rotation == 90)
        pdfCanvas.ConcatMatrix(0, 1, -1, 0, rect.GetWidth(), 0);
    else if (rotation == 180)
        pdfCanvas.ConcatMatrix(-1, 0, 0, -1, rect.GetWidth(), rect.GetHeight());
    else if (rotation == 270)
        pdfCanvas.ConcatMatrix(0, -1, 1, 0, 0, rect.GetHeight());

    Rectangle rotatedRect = 0 == (rotation / 90) % 2 ? new Rectangle(rect.GetWidth(), rect.GetHeight()) : new Rectangle(rect.GetHeight(), rect.GetWidth());
    Canvas appearanceCanvas = new Canvas(pdfCanvas, pdfSigner.GetDocument(), rotatedRect);

    Paragraph text = new Paragraph();
    text.SetFontSize(7).Add("Signed by: Muddassir Awan\nReason: I approve this document\nSigned at: 2020-02-20 16:55:20 +05:00");
    appearanceCanvas.Add(text);

    signatureImage.ScaleToFit(rotatedRect.GetWidth(), 40);
    appearanceCanvas.Add(signatureImage);

    int estimatedSize = 12000;
    pdfSigner.SignExternalContainer(new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached), estimatedSize);
}

结果:

截屏

这大约是您想要的,除了位置微调。

因此,只需将旋转变换应用于PdfCanvas抵消页面旋转,然后Canvas根据该旋转选择矩形。


推荐阅读