Java 如何检索PDFSTAMP批注的图像

Java 如何检索PDFSTAMP批注的图像,java,itext,itext7,Java,Itext,Itext7,我使用以下示例创建了一个pdf: pdf已正确创建并包含戳记批注 我可以使用以下方法获取注释: ... PdfStampAnnotation s = (PdfStampAnnotation) pdfDoc.getFirstPage().getAnnotations().get(0); s.????? 我怎样才能取回邮票的图像(itext.png)(例如:byte[])? 我对itext真的很陌生,经过几个小时的研究,我被困在这一点上 首先,您将无法恢复原始图像。PDF只支持很少的位图图像格式

我使用以下示例创建了一个pdf:

pdf已正确创建并包含戳记批注

我可以使用以下方法获取注释:

...
PdfStampAnnotation s = (PdfStampAnnotation) pdfDoc.getFirstPage().getAnnotations().get(0);
s.?????
我怎样才能取回邮票的图像(itext.png)(例如:byte[])?
我对itext真的很陌生,经过几个小时的研究,我被困在这一点上

首先,您将无法恢复原始图像。PDF只支持很少的位图图像格式:JPEG、JPEG2000、某些传真格式,但绝对不支持PNG。PNG转换为PDF内部位图格式,提取后最好转换回PNG

此外,在
PdfStampAnnotation
类中没有简单的
getImage
方法的原因是戳记的外观可以像普通页面的内容一样构造,它可以包含文本,它可以包含向量图形,它可以包含位图图像,它可能包含这些元素的任意混合物。因此,您只能从注释中检索其外观

如果您确定批注只包含图像(或者您至少对图像以外的任何内容都不感兴趣),则可以使用iText解析器框架提取该图像,例如:

Map<byte[], String> extractAnnotationImages(PdfStream xObject) {
    final Map<byte[], String> result = new HashMap<>();
    IEventListener renderListener = new IEventListener() {
        @Override
        public Set<EventType> getSupportedEvents() {
            return Collections.singleton(RENDER_IMAGE);
        }

        @Override
        public void eventOccurred(IEventData data, EventType type) {
            if (data instanceof ImageRenderInfo) {
                ImageRenderInfo imageRenderInfo = (ImageRenderInfo) data;
                byte[] bytes = imageRenderInfo.getImage().getImageBytes();
                String extension = imageRenderInfo.getImage().identifyImageFileExtension();
                result.put(bytes, extension);
            }
        }
    };

    PdfCanvasProcessor processor = new PdfCanvasProcessor(renderListener, Collections.emptyMap());
    processor.processContent(xObject.getBytes(), new PdfResources(xObject.getAsDictionary(PdfName.Resources)));

    return result;
}
地图提取注释图像(PdfStream xObject){
最终映射结果=新HashMap();
IEventListener renderListener=新IEventListener(){
@凌驾
公共集getSupportedEvents(){
返回集合。单例(渲染图像);
}
@凌驾
发生公共void事件(IEventData,EventType){
if(ImageRenderInfo的数据实例){
ImageRenderInfo ImageRenderInfo=(ImageRenderInfo)数据;
字节[]字节=imageRenderInfo.getImage().getImageBytes();
字符串扩展名=imageRenderInfo.getImage().IdentificationImageFileExtension();
result.put(字节,扩展名);
}
}
};
PdfCanvasProcessor=新的PdfCanvasProcessor(renderListener,Collections.emptyMap());
processor.processContent(xObject.getBytes(),新的PdfResources(xObject.getAsDictionary(PdfName.Resources));
返回结果;
}
(方法)

它返回从图像字节数组到要使用的文件扩展名的映射

我在这个助手方法中使用了它:

void saveAnnotationImages(PdfDocument pdfDocument, String prefix) throws IOException {
    for (int pageNumber = 1; pageNumber <= pdfDocument.getNumberOfPages(); pageNumber++) {
        PdfPage page = pdfDocument.getPage(pageNumber);
        int index = 0;
        for (PdfAnnotation annotation : page.getAnnotations()) {
            PdfDictionary normal = annotation.getAppearanceObject(PdfName.N);
            if (normal instanceof PdfStream) {
                Map<byte[], String> images = extractAnnotationImages((PdfStream)normal);
                for (Map.Entry<byte[], String> entry : images.entrySet()) {
                    Files.write(new File(String.format("%s-%s-%s.%s", prefix, pageNumber, index++, entry.getValue())).toPath(), entry.getKey());
                }
            }
        }
    }
}
void saveAnnotationImage(PdfDocument PdfDocument,字符串前缀)引发IOException{
对于(int pageNumber=1;pageNumber)
void saveAnnotationImages(PdfDocument pdfDocument, String prefix) throws IOException {
    for (int pageNumber = 1; pageNumber <= pdfDocument.getNumberOfPages(); pageNumber++) {
        PdfPage page = pdfDocument.getPage(pageNumber);
        int index = 0;
        for (PdfAnnotation annotation : page.getAnnotations()) {
            PdfDictionary normal = annotation.getAppearanceObject(PdfName.N);
            if (normal instanceof PdfStream) {
                Map<byte[], String> images = extractAnnotationImages((PdfStream)normal);
                for (Map.Entry<byte[], String> entry : images.entrySet()) {
                    Files.write(new File(String.format("%s-%s-%s.%s", prefix, pageNumber, index++, entry.getValue())).toPath(), entry.getKey());
                }
            }
        }
    }
}