【问题标题】:Signature appearance font color in layer2 (itext 7)layer2 中的签名外观字体颜色(itext 7)
【发布时间】:2018-01-26 18:44:09
【问题描述】:

我正在尝试使用 iText7 7.1.0 (java) 中的字体颜色生成具有外观的签名。

使用iText5,调用FontFactory.getFont()时包含fontColor,则:

Font font = FontFactory.getFont(fontName, encoding, embedFont, fontSize, style, bColor); 
appearance.setLayer2Font(font); 

但是,在 iText7 中,Font 似乎丢失了 fontSize 和 fontColor 信息。 fontSize 有一个新的appearance.setLayer2FontSize() 方法。 但是我找不到指示 layer2 字体颜色的方法。

我在文本或段落中找到了一个 setFontColor。

但是,在生成signatureApperance的时候,调用的方法好像是PdfSignatureAppearance.setLayer2Text(String),参数只是一个String。

如何在 iText7 中修改 layer2 字体颜色?

非常感谢。

【问题讨论】:

  • 从 itext7 7.1.3 版本开始,PdfSignatureAppearance 类有一个名为 setLayer2FontColor 的新方法

标签: java itext itext7


【解决方案1】:

在将PdfSignatureAppearance 从 iText 5 移植到 iText 7 时,显然没有考虑在 iText 5 字体对象中传输颜色的选项,至少我没有看到任何官方方法可以将所需颜色传输到外观创建过程。

在这种情况下,显而易见的选择是手动创建第 2 层。这样做,您可以根据需要设计外观。您可以复制和粘贴原始代码,包括所需的隐藏辅助方法,以从原始 iText 设计开始您的设计。

如果您不想这样做,即如果您仍然希望 iText 创建外观并且只是稍微调整一下,则有一种解决方法:您可以让 iText 创建外观,然后对它们进行操作位。

不幸的是,现在这需要反射,因为用于生成外观的PdfSignatureAppearance 方法getAppearance()protected。 (在 iText 5 中它曾经是 public...)

如果您对这样的解决方法感到满意,您可以像这样为您的文本着色:

PdfSigner signer = ...;
PdfSignatureAppearance appearance = signer.getSignatureAppearance();

[... customize the appearance using its usual methods ...]

// call appearance.getAppearance() using reflection
// this initializes the layers in the appearance object
Method getAppearanceMethod = PdfSignatureAppearance.class.getDeclaredMethod("getAppearance");
getAppearanceMethod.setAccessible(true);
getAppearanceMethod.invoke(appearance);

// add a fill color setting instruction
// at the start of layer 2
PdfFormXObject layer2 = appearance.getLayer2();
PdfStream layer2Stream = layer2.getPdfObject();
byte[] layer2Bytes = layer2Stream.getBytes();
layer2Stream.setData("1 0 0 rg\n".getBytes());
layer2Stream.setData(layer2Bytes, true);

signer.signDetached(...);

(CreateSpecialSignatureAppearance测试方法testColorizeLayer2Text)

由于最初生成的外观中的填充颜色未明确设置,而是默认为黑色,因此该前置指令将所有文本着色为红色(使用 100% 红色、0% 绿和 0% 蓝的 RGB 颜色)。


iText 7 仍然带有所有这些签名层的东西,实际上我有点惊讶。至少自从 ISO 32000-1 于 2008 年发布以来,除了支持 Adob​​e 查看器的特定行为之外,没有理由再使用这些层了,甚至 Adob​​e 自己在 ISO 32000-1 之前几年就宣布不推荐使用这些层。

是否有如此庞大的利益集团游说支持那些已弃用的行为?

【讨论】:

    【解决方案2】:

    您使用这种方式创建自定义第 2 层,然后对其进行修改。

    // Create the signature appearance
                Rectangle rect = new Rectangle(36, 50, 200, 100);
                PdfSignatureAppearance appearance = signer.getSignatureAppearance();
                appearance
                .setLocation(location)
    
                // Specify if the appearance before field is signed will be used
                // as a background for the signed field. The "false" value is the default value.
                .setReuseAppearance(false)
                .setPageRect(rect)
                .setPageNumber(r.getNumberOfPages());
                signer.setFieldName("sig");
                
                appearance.setLayer2Font(PdfFontFactory.createFont(StandardFonts.TIMES_ITALIC));
                
                // Get the background layer and draw a gray rectangle as a background.
                PdfFormXObject n0 = appearance.getLayer0();
                float x = n0.getBBox().toRectangle().getLeft();
                float y = n0.getBBox().toRectangle().getBottom();
                float width = n0.getBBox().toRectangle().getWidth();
                float height = n0.getBBox().toRectangle().getHeight();
                PdfCanvas canvas = new PdfCanvas(n0, signer.getDocument());
                canvas.setFillColor(ColorConstants.CYAN);
                canvas.rectangle(x, y, width, height);
                canvas.fill();
    
                // Set the signature information on layer 2
                PdfFormXObject n2 = appearance.getLayer2();
                Paragraph p = new Paragraph("This document was signed by Bruno Specimen.");
                new Canvas(n2, signer.getDocument()).add(p);
    
                // Creating the signature
                IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
                IExternalDigest digest = new BouncyCastleDigest();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      • 2023-04-09
      • 2021-10-03
      • 1970-01-01
      相关资源
      最近更新 更多