Как получить изображение PdfStampAnnotation - PullRequest
0 голосов
/ 28 июня 2018

Я создал 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) штампа (например, byte [])? Я действительно новичок в itext, и после нескольких часов исследований я застрял в этой точке ...

1 Ответ

0 голосов
/ 01 июля 2018

Прежде всего, вы не получите исходное изображение обратно. 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;
}

( ExtractAnnotationImage метод)

, который возвращает отображение из байтовых массивов изображений в расширение файла для использования.

Я использовал его в этом вспомогательном методе:

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, на которые вы ссылаетесь, и получите одно изображение:

add_stamp-1-0.png

Кстати, вы поймете, что прозрачность отсутствует. Прозрачность в PDF моделируется с помощью второго изображения, маскирующего изображения, которое фактически представляет собой нечто вроде альфа-канала. Эту маску можно извлечь из объекта ImageRenderInfo.getImage().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...