我在尝试在iText(例如90度)中旋转PdfSignatureAppearance时遇到了一个大问题。我正在使用MakeSignature.signDetached方法签署PDF,并为外观设置我自己的文本和图像。
以下是一些代码:
PdfReader reader = new PdfReader("my input file");
FileOutputStream fout = new FileOutputStream("my output file");
PdfStamper stamper = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stamper.getSignatureAppearance();
sap.setLayer2Text("Signed by someone");
sap.setAcro6Layers(true);
sap.setSignatureGraphic("my signature image", null));
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
Rectangle pageSize = reader.getPageSize(1); //the page to sign: 1 is the 1st one
Rectangle rect = new Rectangle(llx, lly, urx, ury, rotation);
//llx, lly ... come from a GUI. They are working fine, but the rotation is not considered
sap.setVisibleSignature(rect, 1, null); //1 is the page to sign
MakeSignature.signDetached(sap, ...); //sign the document
我的问题是“轮换”参数。无论我设置什么,文字和图像都不会旋转。查看iText代码(我使用的是iText 5.3.2),签名图层边界框的旋转参数将被丢弃,因此,以这种方式设置旋转根本没有效果。
现在的问题是:有没有办法旋转我的签名图层而不重写整个PdfSignatureAppearance和MakeSignature类?
只是为了澄清:对文档进行数字签名的代码工作正常。我唯一的问题是签名的可视层:我无法旋转它。
感谢。
答案 0 :(得分:1)
使用setRenderingMode(),setLayer2Text(),setSignatureGraphic()等便捷方法创建签名时,目前不支持设置旋转...
所以你有两个选择: 1.要么我们提供该功能。数字签名白皮书的前90页草案刚刚发布给新闻信的订阅者,所以我们正在研究这些课程。但是:使用智能卡进行签名,重构验证过程等......暂时具有绝对优先权,因此您可能需要等待一段时间。 2.使用getLayer()方法以任何方向绘制内容。对于背景中的图像,这将是getLayer(0);和getLayer(2)的文本。
请注意,曾经有过第1,3,4层,但它们只有在acro6Layers等于true时才有效;这是你的情况,但不鼓励使用acro6Layers(它已经过时了:你不应该再使用它了)。事实上,我现在就弃用该方法,默认情况下将该值设置为false。
答案 1 :(得分:1)
允许重用com.itextpdf.text.pdf.PdfSignatureAppearance
中代码的工作示例(例如,自动计算字体大小):
public class RotateVisualSignature {
public static void main(String[] args) throws IOException, DocumentException, GeneralSecurityException {
// Loading private key and certificates.
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("signer.p12"), "secret".toCharArray());
String alias = keyStore.aliases().nextElement();
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, "secret".toCharArray());
Certificate[] certificateChain = keyStore.getCertificateChain(alias);
PdfReader reader = new PdfReader("sample.pdf");
FileOutputStream os = new FileOutputStream("sample-signed.pdf");
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setCertificate(certificateChain[0]);
// This method has to be called as an alternative to 'com.itextpdf.text.pdf.PdfSignatureAppearance.setVisibleSignature'.
setVisibleSignatureRotated(stamper, appearance, new Rectangle(120, 650, 170, 770), 1, null);
// Perform the signature.
ExternalSignature externalSignature = new PrivateKeySignature(privateKey, "SHA-256", null);
ExternalDigest externalDigest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, externalDigest, externalSignature, certificateChain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);
}
private static void setVisibleSignatureRotated(PdfStamper stamper, PdfSignatureAppearance appearance, Rectangle pageRect, int page, String fieldName) throws DocumentException, IOException {
float height = pageRect.getHeight();
float width = pageRect.getWidth();
float llx = pageRect.getLeft();
float lly = pageRect.getBottom();
// Visual signature is configured as if it were going to be a regular horizontal visual signature.
appearance.setVisibleSignature(new Rectangle(llx, lly, llx + height, lly + width), page, null);
// We trigger premature appearance creation, so independent parts of it can be modified right away.
appearance.getAppearance();
// Now we correct the width and height.
appearance.setVisibleSignature(new Rectangle(llx, lly, llx + width, lly + height), page, fieldName);
appearance.getTopLayer().setWidth(width);
appearance.getTopLayer().setHeight(height);
PdfTemplate n2Layer = appearance.getLayer(2);
n2Layer.setWidth(width);
n2Layer.setHeight(height);
// Then we rotate the n2 layer. See http://developers.itextpdf.com/question/how-rotate-paragraph.
PdfTemplate t = PdfTemplate.createTemplate(stamper.getWriter(), height, width);
ByteBuffer internalBuffer = t.getInternalBuffer();
internalBuffer.write(n2Layer.toString().getBytes());
n2Layer.reset();
Image textImg = Image.getInstance(t);
textImg.setInterpolation(true);
textImg.scaleAbsolute(height, width);
textImg.setRotationDegrees((float) 90);
textImg.setAbsolutePosition(0, 0);
n2Layer.addImage(textImg);
}
}
结果如下:
要使用此功能,您只需按原样复制setVisibleSignatureRotated
方法,并通过调用com.itextpdf.text.pdf.PdfSignatureAppearance#setVisibleSignature
替换setVisibleSignatureRotated
来电。