在旋转文档上添加签名字段
Add signature field on rotated document
我正在尝试在旋转后的文档上添加签名字段,但我不想在签名字段上应用任何旋转,它应该添加到旋转后的页面上,旋转为 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);
我使用了您的示例文件中的修订版,它有两个空的签名字段并且尚未签名。此外,我使用了您签名图像的重建版本。
使用 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
应用旋转变换以抵消页面旋转,然后 select Canvas
矩形根据该旋转进行旋转。
我正在尝试在旋转后的文档上添加签名字段,但我不想在签名字段上应用任何旋转,它应该添加到旋转后的页面上,旋转为 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);
我使用了您的示例文件中的修订版,它有两个空的签名字段并且尚未签名。此外,我使用了您签名图像的重建版本。
使用 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
应用旋转变换以抵消页面旋转,然后 select Canvas
矩形根据该旋转进行旋转。