如何检索PdfStampAnnotation的图像(How to retrieve the imag

2019-11-04 22:09发布

我用下面的例子中创建的PDF: https://developers.itextpdf.com/examples/actions-and-annotations/clone-creating-and-adding-annotations#2260-addstamp.java

@Category(SampleTest.class)
public class AddStamp extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/annotations/add_stamp.pdf";
    public static final String IMG = "./src/test/resources/img/itext.png";
    public static final String SRC = "./src/test/resources/pdfs/hello.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new AddStamp().manipulatePdf(DEST);
    }

    @Override
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));

        ImageData img = ImageDataFactory.create(IMG);
        float w = img.getWidth();
        float h = img.getHeight();
        Rectangle location = new Rectangle(36, 770 - h, w, h);
        PdfStampAnnotation stamp = new PdfStampAnnotation(location)
            .setStampName(new PdfName("ITEXT"));
        PdfFormXObject xObj = new PdfFormXObject(new Rectangle(w, h));
        PdfCanvas canvas = new PdfCanvas(xObj, pdfDoc);
        canvas.addImage(img, 0, 0, false);
        stamp.setNormalAppearance(xObj.getPdfObject());
        stamp.setFlags(PdfAnnotation.PRINT);

        pdfDoc.getFirstPage().addAnnotation(stamp);
        pdfDoc.close();
    }
}

PDF格式正确创建,并包含邮票注解

我可以用得到的注释:

...
PdfStampAnnotation s = (PdfStampAnnotation) pdfDoc.getFirstPage().getAnnotations().get(0);
s.?????

我怎样才能找回邮票的图像(itext.png)(例如:字节[])? 我真的很新的iText和研究小时后我被困在这一点上...

Answer 1:

首先,你不会得到原始图像回来。 PDF支持只有极少数的位图图像格式,它们分别是:JPEG,JPEG2000,某些传真的格式,但没有明确PNG。 PNG格式被转换成PDF内部位图格式,并在提取后可以最好地转换回PNG。

此外,为什么没有简单的原因getImage的方法PdfStampAnnotation类是邮票的外观可以像一个普通页面的内容构成,它可以包含文本,它可以包含矢量图形,它可能包含位图图像,它可以含有这些元素的任意混合物。 因此,你可以从注释中检索是它的外观。

如果您确定一个注释中只包含一个图像(或者至少是不感兴趣的东西,但图像),你可以使用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;
}

( ExtractAnnotationImage方法)

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

我用它在这个helper方法:

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());
                }
            }
        }
    }
}

( ExtractAnnotationImage辅助方法)

来提取注释的所有图像从iText的例子的输出AddStamp您参考,并得到了一个形象:

顺便说一句,你会意识到这里的透明度缺失。 透明度在PDF经由第二图像,掩模图像,从而有效地表示类似的α信道建模。 一个可以检索从这个面具ImageRenderInfo.getImage()对象。



文章来源: How to retrieve the image of a PdfStampAnnotation