当前位置: 首页 > 知识库问答 >
问题:

使用iText7提取pdf文件中包含的签名图像

萧阳波
2023-03-14

我想知道我们如何使用ITEXT7来提取与数字签名相关的图像信息。我知道过去也有人问过类似的问题,但它们大多是围绕ITEXT5提出的,在对软件进行了所有更新和修改后,这与ITEXT7大不相同。

共有1个答案

贺雪松
2023-03-14

可以使用低级API从签名外观中提取图像。完整的Java代码:

private void saveImageFromSignature(PdfDocument document, String fieldName) throws IOException {
    PdfAcroForm acroForm = PdfAcroForm.getAcroForm(document, false);
    PdfDictionary xObject = acroForm.getField(name)
                                    .getWidgets()
                                    .get(0)
                                    .getNormalAppearanceObject()
                                    .getAsDictionary(PdfName.Resources)
                                    .getAsDictionary(PdfName.XObject)
                                    .getAsStream(new PdfName("FRM"))
                                    .getAsDictionary(PdfName.Resources)
                                    .getAsDictionary(PdfName.XObject);
    PdfStream stream = xObject.getAsStream(new PdfName("Im1"));


    PdfImageXObject image      = new PdfImageXObject(stream);
    BufferedImage   result     = createImageFromBytes(image.getImageBytes());
    //pdf allows using masked image in the signature appearance 
    PdfStream       maskStream = (PdfStream) stream.getAsStream(PdfName.SMask);
    if (maskStream != null) {
        PdfImageXObject maskImage = new PdfImageXObject(maskStream);

        BufferedImage maskBimage = createImageFromBytes(maskImage.getImageBytes());
        String fileMask = String.format(getOutputFolder() + "/file_mask_%d.%s",
                                        image.getPdfObject().getIndirectReference().getObjNumber(),
                                        image.identifyImageFileExtension());
        ImageIO.write(maskBimage,
                      image.identifyImageFileExtension(),
                      new File(fileMask));
        //the mask defines an alfa channel 
        Image transpImg = transformToTransperency(maskBimage);
        result = applyTransperency(result, transpImg);
       


    }
    String filenameComp = String.format(getOutputFolder() + "/file_comp_%d.%s",
                                        image.getPdfObject().getIndirectReference().getObjNumber(),
                                        image.identifyImageFileExtension());


    ImageIO.write(result,
                  image.identifyImageFileExtension(),
                  new File(filenameComp));
    document.close();
}
private Image transformToTransperency(BufferedImage bi) {
    ImageFilter filter = new RGBImageFilter() {
        @Override
        public int filterRGB(int x, int y, int rgb) {
            return (rgb << 8) & 0xFF000000;
        }
    };
    ImageProducer ip = new FilteredImageSource(bi.getSource(), filter);
    return Toolkit.getDefaultToolkit().createImage(ip);

}
private BufferedImage applyTransperency(BufferedImage bi, Image mask) {
    BufferedImage dest = new BufferedImage(
            bi.getWidth(), bi.getHeight(),
            BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = dest.createGraphics();
    g2.drawImage(bi, 0, 0, null);
    AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0F);
    g2.setComposite(ac);
    g2.drawImage(mask, 0, 0, null);
    g2.dispose();
    return dest;
}

Upd:这只适用于非常有限的情况。谢谢@mkl。

 类似资料:
  • 我有一个签名的PDF文件。有了这个功能,它利用了iTextSharp库,我找到了证书p7m签名: 现在...我如何提取与签名相关的图像(位图)?可能吗?谢谢,路易吉

  • 我有一个场景,我需要用iText7库从pdf中获取签名信息。签名可能存在,也可能不存在。当我为没有任何数字签名的PDF实例化一个新的对象时,会出现异常 “没有相关的PdfWriter用于进行间接操作。” .如果有签名,就很好用。我不确定如何纠正这个异常。 更新为包含代码示例

  • 我有一个私人钥匙在档案里。“privatekey.pem”并且不知道如何创建谁能帮助我吗?我正在尝试使用IText7签名pdf。

  • 我需要将一个使用iText5进行PDF签名验证/创建的Java程序移植到iText7。 旧代码显然不能按原样工作,因为iText的大部分内容都经过了重组。 我找到的所有关于如何做到这一点的例子和教程都是针对iText5的。(非常好的)白皮书也是如此。它们依赖于通过方法返回的列表,在该方法上执行所有与签名相关的操作。 在iText7中,不再具有该方法。 有人知道iText7的例子/文档吗?

  • 我必须从PDF签名文档中提取签名字段,以创建打印签名版本。到目前为止,我已经能够使用以下iText代码恢复签名者证书、原因、签名日期和其他字段: 据我所知,PDF签名是使用iText PdfPkcs7类制作的,使用setExternalDigest方法添加在外部应用程序中创建的PKCS1字节数组。文件看起来已由外部工具正确签名和验证。 但是,打印版本所需的字段之一是“签名数字戳”,它是签名文档哈希

  • 我正在将代码从iText5迁移到iText7,目前我正在努力将一个签名添加到已经包含另一个签名的PDF中。这些签名是用我们的国民身份证(公民卡)进行的。 在iText5中,我使用了PdfStamper,但它在Itext7中丢失了... 这是我目前所掌握的: POReID(https://github.com/POReID/POReID)是用于与智能卡交互的库。 当第一次签署文件时,它工作得很好。再