从PDF签章文件中提取印章以及印章图片

目录

1.SM2签章

2.RSA签章


1.SM2签章

国密签章是有签章结构的,遵循一定的标准,可以从签章结构中解析出印章,然后再从印章中保存图片

代码如下:

  public void getSealFromPDFStamp() throws Exception {
        String pdfStampPath = "F:/Netseal_Work/签章项目和主线总结/离职证明/适配子公司UKEY/上海信旋/安印工具签章.pdf";

        byte[] pdfData = FileUtil.getFile(pdfStampPath);

        PdfReader reader = null;
        try {
            reader = new PdfReader(pdfData);
            AcroFields af = reader.getAcroFields();

            ArrayList<String> names = af.getSignatureNames();
            // 获取每一个签名域的 Contents
            for (String name : names) {
                PdfDictionary dictionary = af.getSignatureDictionary(name);
                byte[] bytes = dictionary.getAsString(PdfName.CONTENTS).getBytes();
                String hexContents = HexUtil.byte2Hex(bytes);
                while (hexContents.endsWith("00"))
                    hexContents = hexContents.substring(0, hexContents.length() - 2);

                StampData sd = new StampData(bytes);
                byte[] stampData = sd.getEseal().getEncoded();

                FileUtil.storeFile("E:/1.asn1",stampData);
            }


        } catch (Exception e) {
            throw e;
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (Exception e) {
            }
        }
    }

解析保存下来的文件用asn1工具打开

 将图片数据保存成文件,就可以把印章图片提取出来了

2.RSA签章

RSA签章没有签章结构,笼统意义来说就是加盖图片进行签名,所以不能再用上面的方式进行提取印章图片,使用PDF源码进行提取

	public PdfImageObject extractImage(String signatureName) throws Exception {
		MyImageRenderListener listener = new MyImageRenderListener();

		PdfDictionary sigFieldDic = reader.getAcroFields().getFieldItem(signatureName).getMerged(0);
		PdfDictionary appearancesDic = sigFieldDic.getAsDict(PdfName.AP);
		PdfStream normalAppearance = appearancesDic.getAsStream(PdfName.N);

		PdfDictionary resourcesDic = normalAppearance.getAsDict(PdfName.RESOURCES);

		PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
		processor.processContent(ContentByteUtils.getContentBytesFromContentObject(normalAppearance), resourcesDic);

		return listener.image;
	}

	public static void main(String[] args) throws Exception {
		byte[] pdfData = FileUtil.getFile("F:/Netseal_Work/签章项目和主线总结/离职证明/适配子公司UKEY/上海信旋/安印工具签章.pdf");
		PdfReader reader = new PdfReader(pdfData);
		AcroFields acroFields = reader.getAcroFields();
		List<String> names = acroFields.getSignatureNames();

		ExtractPhoto ep = new ExtractPhoto(reader);
		for (String name : names) {
			PdfImageObject image = ep.extractImage(name);
			FileUtil.storeFile("f:/temp/pdf/" + name + ".png", image.getImageAsBytes());
		}

		reader.close();
	}
}

注意:解析出来的图片带背景,一般都是白色背景,然后再进行一次去背景的操作

	public static byte[] cleanBGColor(byte[] bs) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(bs);
		BufferedImage bi = ImageIO.read(bais);
		BufferedImage tmp = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
		for (int i = 0, width = bi.getWidth(); i < width; i++) {
			for (int j = 0, height = bi.getHeight(); j < height; j++) {
				int rgb = bi.getRGB(i, j);
				// if (((rgb & 0xff000000) >> 24 & 0xff) > 0x80)
				// tmp.setRGB(i, j, rgb);
				// else
				// tmp.setRGB(i, j, Color.WHITE.getRGB());

				byte[] d = HexUtil.int2Byte(rgb);
				int a = d[0] & 0xff;
				int r = d[1] & 0xff;
				int g = d[2] & 0xff;
				int b = d[3] & 0xff;
				if (r == 255 && g == 255 && b == 255) {
					d[0] = 0;
					rgb = HexUtil.byte2Int(d);
				}

				tmp.setRGB(i, j, rgb);
			}
		}

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ImageIO.write(tmp, "png", baos);

		return baos.toByteArray();
	}

以上步骤就可以获取RSA签章文件的印章图片了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值