PDFbox 1.7.0 - Как сохранить существующее изображение при добавлении нового с PDFBox? - PullRequest
1 голос
/ 02 апреля 2019

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


// Use for convert mm to dots
// ... 72 dots per inch
static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
// ... mm -> inch -> dots
static final float MM_TO_UNITS = 1 / (10 * 2.54f) * DEFAULT_USER_SPACE_UNIT_DPI;

/**
 * Add a given image to a specific page of a PDF
 * @param document PDF document to manipulate
 * @param input image inputStream
 * @param pdfpage page number to target
 * @param x image position (en mm)
 * @param y image position (en mm)
 * @param width max width of the image (mm)
 * @param height max height of the image (en mm)
 * @param opacity opacity level of the image (fraction)
 */
void addImageToPage (PDDocument document, InputStream input, int pdfpage, int x, int y, int width, int height, float opacity) throws IOException {
    if (input != null) {
        // Convert inputstream to usable BufferedImage
        BufferedImage tmp_image = ImageIO.read (input);
        // User TYPE_4BYTE_ABGR to fix PDFBox issue with transparent PNG
        BufferedImage image = new BufferedImage (tmp_image.getWidth(), tmp_image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        // Prepare the image
        image.createGraphics().drawRenderedImage (tmp_image, null);
        PDXObjectImage ximage = new PDPixelMap (document, image);
        // Resize the image
        int iWidth = ximage.getWidth();
        int iHeight = ximage.getHeight();
        if (width / height > iWidth / iHeight) {
            ximage.setWidth (Math.round (width * MM_TO_UNITS));
            ximage.setHeight (Math.round ((iHeight * width / iWidth) * MM_TO_UNITS));
        } else {
            ximage.setWidth (Math.round ((iWidth * height / iHeight) * MM_TO_UNITS));
            ximage.setHeight (Math.round (height * MM_TO_UNITS));
        }
        // Retrieve the page to update
        PDPage page = (PDPage)document.getDocumentCatalog().getAllPages().get (pdfpage);
        PDResources resources = page.findResources();
        // Get graphics states
        Map graphicsStates = resources.getGraphicsStates();
        if (graphicsStates == null) {
            graphicsStates = new HashMap();
        }
        // Set graphics states configurations
        PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
        // Set the opacity of the image
        extendedGraphicsState.setNonStrokingAlphaConstant (opacity);
        graphicsStates.put ("TransparentState", extendedGraphicsState);
        // Restore graphics states
        resources.setGraphicsStates (graphicsStates);
        // Retrieve the content stream
        PDPageContentStream contentStream = new PDPageContentStream (document, page, true, true);
        // Activate transparency options
        contentStream.appendRawCommands ("/TransparentState gs\n");
        contentStream.endMarkedContentSequence();
        // Insert image
        contentStream.drawImage (
            ximage,
            (float) x * MM_TO_UNITS,
            (float) y * MM_TO_UNITS
        );
        // close the stream
        contentStream.close();
    }
}

Я ожидал, что на странице появится новое изображение, но вместо нового исчезло существующее изображение на странице.

Пример используемого PDF: http://www.mediafire.com/folder/g6p7c2b5ob1c7/PDFBox_issue

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Хорошо.Я отказался от попыток использовать PDFbox 1.7 для этой части разработки.Это требование ко многим исправлениям реализует несколько вещей.Это не совсем ремонтопригодно для будущих работ.Спасибо всем за советы и подсказки.

0 голосов
/ 03 апреля 2019

В 1.7 есть несколько ошибок ... одна, о которой я упоминал в комментарии (оказывается, это не влияет на вас), другая - то, что ресурсы выполняют некоторое кеширование, но не управляются должным образом… Короче говоря,вам нужно сохранять и восстанавливать ресурсы xobject следующим образом:

Map<String, PDXObject> xObjectsMap = page.getResources().getXObjects(); // save xobjects
…
PDXObjectImage ximage = new PDPixelMap (document, image);
String imgName = page.getResources().addXObject(ximage, "Im");
cs.drawImage(ximage, 0, 0); // bug happens here, old xobjects gets lost
xObjectsMap.put(imgName, ximage);
page.getResources().setXObjects(xObjectsMap); // restore xobjects

Это действительно просто обходной путь ... может случиться больше неприятных сюрпризов.Вы не должны использовать старые версии.Они больше не вызывают радости.Вы должны поблагодарить их за службу и затем отпустить их без вины.

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