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

使用iText7提取pdf文件中包含的签名图像,pdf,signature,itext7,Pdf,Signature,Itext7,我想知道如何使用ITEXT7提取与数字签名相关的图像信息。我知道过去也有过类似的问题,但大部分都是关于ITEXT5的,这与软件经过所有更新和修改后的ITEXT7大不相同。您可以使用低级API从签名外观提取图像。 完整的Java代码: private void saveImageFromSignature(PdfDocument document, String fieldName) throws IOException { PdfAcroForm acroForm = PdfAcroFo

我想知道如何使用ITEXT7提取与数字签名相关的图像信息。我知道过去也有过类似的问题,但大部分都是关于ITEXT5的,这与软件经过所有更新和修改后的ITEXT7大不相同。

您可以使用低级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;
}
private void saveImageFromSignature(PdfDocument文档,字符串字段名)引发IOException{
PdfAcroForm acroForm=PdfAcroForm.getAcroForm(文档,false);
PdfDictionary xObject=acroForm.getField(名称)
.getWidgets()
.get(0)
.getNormalAppearanceObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(新PdfName(“FRM”))
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject);
PdfStream-stream=xObject.getAsStream(新的PdfName(“Im1”));
PdfImageXObject image=新的PdfImageXObject(流);
BuffereImage结果=createImageFromBytes(image.getImageBytes());
//pdf允许在签名外观中使用遮罩图像
PdfStream maskStream=(PdfStream)stream.getAsStream(PdfName.SMask);
if(maskStream!=null){
PdfImageXObject maskImage=新的PdfImageXObject(maskStream);
BuffereImage maskBimage=createImageFromBytes(maskImage.getImageBytes());
String fileMask=String.format(getOutputFolder()+“/file\u mask\u%d.%s”,
image.getPdfObject().getIndirectReference().getObjNumber(),
image.identifimagefileextension());
ImageIO.write(maskBimage,
image.identifImageFileExtension(),
新文件(文件掩码));
//遮罩定义了一个阿尔法通道
图像传输=转换传输(maskBimage);
结果=应用透明度(结果、透明度);
}
String filenameComp=String.format(getOutputFolder()+“/file\u comp\u%d.%s”,
image.getPdfObject().getIndirectReference().getObjNumber(),
image.identifimagefileextension());
ImageIO.write(结果,
image.identifImageFileExtension(),
新文件(filenameComp));
document.close();
}
私有映像转换透明度(BuffereImage bi){
ImageFilter过滤器=新的RGBImageFilter(){
@凌驾
公共整型过滤器rgb(整型x、整型y、整型rgb){

return(rgb您可以使用低级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;
}
private void saveImageFromSignature(PdfDocument文档,字符串字段名)引发IOException{
PdfAcroForm acroForm=PdfAcroForm.getAcroForm(文档,false);
PdfDictionary xObject=acroForm.getField(名称)
.getWidgets()
.get(0)
.getNormalAppearanceObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(新PdfName(“FRM”))
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject);
PdfStream-stream=xObject.getAsStream(新的PdfName(“Im1”));
PdfImageXObject image=新的PdfImageXObject(流);
BuffereImage结果=createImageFromBytes(image.getImageBytes());
//pdf允许在签名外观中使用遮罩图像
PdfStream maskStream=(PdfStream)stream.getAsStream(PdfName.SMask);
if(maskStream!=null){
PdfImageXObject maskImage=新的PdfImageXObject(maskStream);
BuffereImage maskBimage=createImageFromBytes(maskImage.getImageBytes());
String fileMask=String.format(getOutputFolder()+“/file\u mask\u%d.%s”,
image.getPdfObject().getIndirectReference().getObjNumber(),
image.identifimagefileextension());
ImageIO.write(maskBimage,
image.identifImageFileExtension(),
新文件(文件掩码));
//遮罩定义了一个阿尔法通道
图像传输=转换传输(maskBimage);
结果=应用透明度(结果、透明度);
}
String filenameComp=String.format(getOutputFolder()+“/file\u comp\u%d.%s”,
image.getPdfObject().getIndirectReference().getObjNumber(),
image.identifimagefileextension());
ImageIO.write(结果,
image.identifImageFileExtension(),
新文件(filenameComp));
document.close();
}
私有映像转换透明度(BuffereImage bi){
ImageFilter过滤器=新的RGBImageFilter(){
@凌驾
公共整型过滤器rgb(整型x、整型y、整型rgb){

返回(rgb您可能想提到,此代码仅适用于非常特殊的签名外观构建,将其内容包含在名为FRM的XObject中,就像Adobe创建它们一样,但与Adobe通常所做的不同,将图像作为其名为Im1的直接资源。对于一般解决方案,我建议将解析器应用于签名外观arance,正在侦听
RENDER_IMAGE
事件。您可能需要指出,此代码仅适用于非常特殊的签名外观构建,将其内容包含在名为FRM-like Ad的XObject中