Example usage for org.apache.pdfbox.pdmodel PDDocument load

List of usage examples for org.apache.pdfbox.pdmodel PDDocument load

Introduction

In this page you can find the example usage for org.apache.pdfbox.pdmodel PDDocument load.

Prototype

public static PDDocument load(byte[] input) throws IOException 

Source Link

Document

Parses a PDF.

Usage

From source file:org.nuxeo.pdf.PDFInfo.java

License:Open Source License

/**
 * After building the object with the correct constructor, and after
 * possibly having set some parsing property (<code>setParseWithXMP()</code>
 * for example), this method will extract the information from the PDF.
 * <p>// www.j  ava2  s .co  m
 * After extraction, caller get the info: Either all of them (
 * <code>toHashMap()</code> or <code>toString()</code>) or individual info
 * (see all getters)
 *
 * @throws ClientException
 *
 * @since 5.9.5
 */
public void run() throws ClientException {

    // In case the caller calls several time the run() method
    if (!alreadyParsed) {

        fileName = pdfBlob.getFilename();
        // Getting the file size os ok only if the blob is already backed by
        // a
        // File. If it is pure Stream, we give up
        File pdfFile = BlobHelper.getFileFromBlob(pdfBlob);
        if (pdfFile == null) {
            fileSize = -1;
        } else {
            fileSize = pdfFile.length();
        }

        try {
            pdfDoc = PDDocument.load(pdfBlob.getStream());

            isEncrypted = pdfDoc.isEncrypted();
            if (isEncrypted) {
                pdfDoc.openProtection(new StandardDecryptionMaterial(password));
            }

            numberOfPages = pdfDoc.getNumberOfPages();
            PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
            pageLayout = checkNotNull(docCatalog.getPageLayout());
            pdfVersion = "" + pdfDoc.getDocument().getVersion();

            PDDocumentInformation docInfo = pdfDoc.getDocumentInformation();
            author = checkNotNull(docInfo.getAuthor());
            contentCreator = checkNotNull(docInfo.getCreator());
            keywords = checkNotNull(docInfo.getKeywords());
            creationDate = docInfo.getCreationDate();
            modificationDate = docInfo.getModificationDate();
            producer = checkNotNull(docInfo.getProducer());
            subject = checkNotNull(docInfo.getSubject());
            title = checkNotNull(docInfo.getTitle());

            // Getting dimension is a bit tricky
            mediaBoxWidthInPoints = -1;
            mediaBoxHeightInPoints = -1;
            cropBoxWidthInPoints = -1;
            cropBoxHeightInPoints = -1;
            List<PDPage> allPages = docCatalog.getAllPages();
            boolean gotMediaBox = false;
            boolean gotCropBox = false;
            for (PDPage page : allPages) {

                if (page != null) {
                    PDRectangle r = page.findMediaBox();
                    if (r != null) {
                        mediaBoxWidthInPoints = r.getWidth();
                        mediaBoxHeightInPoints = r.getHeight();
                        gotMediaBox = true;
                    }
                    r = page.findCropBox();
                    if (r != null) {
                        cropBoxWidthInPoints = r.getWidth();
                        cropBoxHeightInPoints = r.getHeight();
                        gotCropBox = true;
                    }
                }
                if (gotMediaBox && gotCropBox) {
                    break;
                }
            }

            if (doXMP) {
                xmp = null;
                PDMetadata metadata = docCatalog.getMetadata();
                if (metadata != null) {
                    xmp = "";
                    InputStream xmlInputStream = metadata.createInputStream();

                    InputStreamReader isr = new InputStreamReader(xmlInputStream);
                    BufferedReader reader = new BufferedReader(isr);
                    String line;
                    do {
                        line = reader.readLine();
                        if (line != null) {
                            xmp += line + "\n";
                        }
                    } while (line != null);
                    reader.close();
                }
            }

        } catch (IOException | BadSecurityHandlerException | CryptographyException e) {
            throw new ClientException(/*
                                       * "Cannot get PDF info: " +
                                       * e.getMessage(),
                                       */e);
        } finally {
            if (pdfDoc != null) {
                try {
                    pdfDoc.close();
                } catch (IOException e) {
                    // Ignore
                }
                pdfDoc = null;
            }
            alreadyParsed = true;
        }
    }
}

From source file:org.nuxeo.pdf.PDFMerge.java

License:Open Source License

/**
 * Merge the PDFs. optionnaly, can set the title, subject and author of the
 * resulting PDF.//from ww w . j a  v a2  s  .c om
 * <p>
 * <b>Notice</b> for title, author and subject: If the value is null or "",
 * it is just ignored
 *
 * @param inFileName
 * @param inTitle
 * @param inSubject
 * @param inAuthor
 * @return
 * @throws IOException
 * @throws COSVisitorException
 *
 * @since 5.9.5
 */
public Blob merge(String inFileName, String inTitle, String inSubject, String inAuthor)
        throws IOException, COSVisitorException {

    Blob finalBlob = null;

    switch (blobs.size()) {
    case 0:
        finalBlob = null;
        break;

    case 1:
        finalBlob = blobs.get(0);
        break;

    default:
        PDFMergerUtility ut = new PDFMergerUtility();
        for (Blob b : blobs) {
            ut.addSource(b.getStream());
        }

        File tempFile = File.createTempFile("mergepdf", ".pdf");
        ut.setDestinationFileName(tempFile.getAbsolutePath());

        ut.mergeDocuments();

        if (inTitle != null || inAuthor != null || inSubject != null) {
            PDDocument finalDoc = PDDocument.load(tempFile);
            PDFUtils.setInfos(finalDoc, inTitle, inSubject, inAuthor);
            finalDoc.save(tempFile);
            finalDoc.close();
        }

        finalBlob = new FileBlob(tempFile);
        Framework.trackFile(tempFile, finalBlob);

        if (inFileName != null && !inFileName.isEmpty()) {
            finalBlob.setFilename(inFileName);
        } else {
            finalBlob.setFilename(blobs.get(0).getFilename());
        }
        finalBlob.setMimeType("application/pdf");
        break;

    }

    return finalBlob;
}

From source file:org.nuxeo.pdf.PDFPageExtractor.java

License:Open Source License

/**
 * Return a Blob built from page <code>inStartPage</code> to
 * <code>inEndPage</code> (inclusive).
 * <p>/*from  w  w w.  j  ava  2 s  .  c  om*/
 * If <code>inEndPage</code> is greater than the number of pages in the
 * source document, it will go to the end of the document. If
 * <code>inStartPage</code> is less than 1, it'll start with page 1. If
 * <code>inStartPage</code> is greater than <code>inEndPage</code> or
 * greater than the number of pages in the source document, a blank document
 * will be returned.
 * <p>
 * If fileName is null or "", if is set to the original name + the page
 * range: mydoc.pdf and pages 10-75 +> mydoc-10-75.pdf
 * <p>
 * The mimetype is always set to "application/pdf"
 * <p>
 * Can set the title, subject and author of the resulting PDF.
 * <b>Notice</b>: If the value is null or "", it is just ignored
 *
 * @param inStartPage
 * @param inEndPage
 * @param inFileName
 * @param inTitle
 * @param inSubject
 * @param inAuthor
 * @return FileBlob
 *
 */
public Blob extract(int inStartPage, int inEndPage, String inFileName, String inTitle, String inSubject,
        String inAuthor) {

    Blob result = null;
    PDDocument pdfDoc = null;
    PDDocument extracted = null;

    try {
        pdfDoc = PDDocument.load(pdfBlob.getStream());

        PageExtractor pe = new PageExtractor(pdfDoc, inStartPage, inEndPage);
        extracted = pe.extract();

        PDFUtils.setInfos(extracted, inTitle, inSubject, inAuthor);

        result = PDFUtils.saveInTempFile(extracted);

        result.setMimeType("application/pdf");

        if (inFileName == null || inFileName.isEmpty()) {
            String originalName = pdfBlob.getFilename();
            if (originalName == null || originalName.isEmpty()) {
                originalName = "extracted";
            } else {
                int pos = originalName.toLowerCase().lastIndexOf(".pdf");
                if (pos > 0) {
                    originalName = originalName.substring(0, pos);
                }

            }
            inFileName = originalName + "-" + inStartPage + "-" + inEndPage + ".pdf";
        }
        result.setFilename(inFileName);
        extracted.close();

    } catch (IOException | COSVisitorException e) {
        throw new ClientException(e);
    } finally {
        if (pdfDoc != null) {
            try {
                pdfDoc.close();
            } catch (IOException e) {
                log.error("Error closing the PDDocument", e);
            }
        }
        if (extracted != null) {
            try {
                extracted.close();
            } catch (IOException e) {
                // Nothing
            }
        }
    }

    return result;
}

From source file:org.nuxeo.pdf.PDFPageNumbering.java

License:Open Source License

/**
 * Add page numbers and returns a <i>new</i> Blob. Original blob is not
 * modified. This code assumes://  www. j  a v a 2s .c  o m
 * <ul>
 * <li>There is no page numbers already (it always draw the numbers)</li>
 * <li>The pdf is not rotated</li>
 * <li>Default values apply:
 * <ul>
 * <li><code>inStartAtPage</code> and <code>inStartAtNumber</code> are set
 * to 1 if they are passed < 1.</li>
 * <li>If <code>inStartAtPage</code> is > number of pages it also is reset
 * to 1</li>
 * <li><code>inFontName</code> is set to "Helvetica" if "" or null</li>
 * <li><code>inFontSize</code> is <= 0, it is set to 16</li>
 * <li><code>inHex255Color</code> is set to black if "", null or if its
 * length < 6. Expected format is 0xrrggbb, #rrggbb or just rrggbb</li>
 * <li><code>inPosition</code> is set to <code>BOTTOM_RIGHT</code> if null</li>
 * </ul>
 * </li>
 * <li></li>
 * </ul>
 *
 * @param inBlob
 * @param inStartAtPage
 * @param inStartAtNumber
 * @param inFontName
 * @param inFontSize
 * @param inHex255Color
 * @param inPosition
 * @return Blob
 * @throws IOException
 * @throws COSVisitorException
 *
 * @since 5.9.5
 */
public Blob addPageNumbers(int inStartAtPage, int inStartAtNumber, String inFontName, float inFontSize,
        String inHex255Color, PAGE_NUMBER_POSITION inPosition) throws IOException, COSVisitorException {

    Blob result = null;
    PDDocument doc = null;

    inStartAtPage = inStartAtPage < 1 ? 1 : inStartAtPage;
    int pageNumber = inStartAtNumber < 1 ? 1 : inStartAtNumber;
    inFontSize = inFontSize <= 0 ? DEFAULT_FONT_SIZE : inFontSize;

    int[] rgb = PDFUtils.hex255ToRGB(inHex255Color);

    try {
        doc = PDDocument.load(blob.getStream());
        List<?> allPages;
        PDFont font;
        int max;

        if (inFontName == null || inFontName.isEmpty()) {
            font = PDType1Font.HELVETICA;
        } else {
            font = PDType1Font.getStandardFont(inFontName);
            if (font == null) {
                font = new PDType1Font(inFontName);
            }
        }

        allPages = doc.getDocumentCatalog().getAllPages();
        max = allPages.size();
        inStartAtPage = inStartAtPage > max ? 1 : inStartAtPage;
        for (int i = inStartAtPage; i <= max; i++) {
            String pageNumAsStr = "" + pageNumber;
            pageNumber += 1;

            PDPage page = (PDPage) allPages.get(i - 1);
            PDPageContentStream footercontentStream = new PDPageContentStream(doc, page, true, true);

            float stringWidth = font.getStringWidth(pageNumAsStr) * inFontSize / 1000f;
            float stringHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() * inFontSize / 1000;
            PDRectangle pageRect = page.findMediaBox();

            float xMoveAmount, yMoveAmount;

            if (inPosition == null) {
                inPosition = PAGE_NUMBER_POSITION.BOTTOM_RIGHT;
            }
            switch (inPosition) {
            case BOTTOM_LEFT:
                xMoveAmount = 10;
                yMoveAmount = pageRect.getLowerLeftY() + 10;
                break;

            case BOTTOM_CENTER:
                xMoveAmount = (pageRect.getUpperRightX() / 2) - (stringWidth / 2);
                yMoveAmount = pageRect.getLowerLeftY() + 10;
                break;

            case TOP_LEFT:
                xMoveAmount = 10;
                yMoveAmount = pageRect.getHeight() - stringHeight - 10;
                break;

            case TOP_CENTER:
                xMoveAmount = (pageRect.getUpperRightX() / 2) - (stringWidth / 2);
                yMoveAmount = pageRect.getHeight() - stringHeight - 10;
                break;

            case TOP_RIGHT:
                xMoveAmount = pageRect.getUpperRightX() - 10 - stringWidth;
                yMoveAmount = pageRect.getHeight() - stringHeight - 10;
                break;

            // Bottom-right is the default
            default:
                xMoveAmount = pageRect.getUpperRightX() - 10 - stringWidth;
                yMoveAmount = pageRect.getLowerLeftY() + 10;
                break;
            }

            footercontentStream.beginText();
            footercontentStream.setFont(font, inFontSize);
            footercontentStream.moveTextPositionByAmount(xMoveAmount, yMoveAmount);
            footercontentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]);
            footercontentStream.drawString(pageNumAsStr);
            footercontentStream.endText();
            footercontentStream.close();
        }

        File tempFile = File.createTempFile("pdfutils-", ".pdf");
        doc.save(tempFile);
        result = new FileBlob(tempFile);
        Framework.trackFile(tempFile, result);

    } finally {
        if (doc != null) {
            doc.close();
        }
    }

    return result;
}

From source file:org.nuxeo.pdf.PDFTextExtractor.java

License:Open Source License

public String getAllExtractedLines() throws IOException {

    PDDocument pdfDoc = null;//from  ww  w . j ava  2s . c om
    PDFTextStripper stripper = new PDFTextStripper();

    if (extractedAllAsString == null) {
        try {
            pdfDoc = PDDocument.load(pdfBlob.getStream());
            extractedAllAsString = stripper.getText(pdfDoc);

        } catch (IOException e) {
            throw new ClientException(e);
        } finally {
            if (pdfDoc != null) {
                try {
                    pdfDoc.close();
                } catch (IOException e) {
                    log.error("Error closing the PDDocument", e);
                }
            }

        }
    }
    return extractedAllAsString;
}

From source file:org.nuxeo.pdf.PDFWatermarking.java

License:Open Source License

/**
 * Adds the watermark to the Blob passed to the constructor.
 * <p>//  www  .  ja  v a 2s . c  om
 * If no setter has been used, the DEFAULT_nnn values apply
 * <p>
 * If
 * <code>text</text> is empty or null, a simple copy of the original Blob is returned
 * <p>
 * With thanks to the sample code found at https://issues.apache.org/jira/browse/PDFBOX-1176
 * and to Jack (https://jackson-brain.com/a-better-simple-pdf-stamper-in-java/)
 *
 * @return a new Blob with the watermark on each page
 *
 * @throws ClientException
 *
 * @since 6.0
 */
public Blob watermark() throws ClientException {

    Blob result = null;
    PDDocument pdfDoc = null;
    PDPageContentStream contentStream = null;

    if (text == null || text.isEmpty()) {
        try {

            File tempFile = File.createTempFile("nuxeo-pdfwatermarking-", ".pdf");
            blob.transferTo(tempFile);
            result = new FileBlob(tempFile);
            // Just duplicate the info
            result.setFilename(blob.getFilename());
            result.setMimeType(blob.getMimeType());
            result.setEncoding(blob.getEncoding());
            Framework.trackFile(tempFile, result);

            return result;

        } catch (IOException e) {
            throw new ClientException(e);
        }
    }

    // Set up the graphic state to handle transparency
    // Define a new extended graphic state
    PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
    // Set the transparency/opacity
    extendedGraphicsState.setNonStrokingAlphaConstant(alphaColor);

    try {

        pdfDoc = PDDocument.load(blob.getStream());
        PDFont font = PDType1Font.getStandardFont(fontFamily);
        int[] rgb = PDFUtils.hex255ToRGB(hex255Color);

        List<?> allPages = pdfDoc.getDocumentCatalog().getAllPages();
        int max = allPages.size();
        for (int i = 0; i < max; i++) {
            contentStream = null;

            PDPage page = (PDPage) allPages.get(i);
            PDRectangle pageSize = page.findMediaBox();

            PDResources resources = page.findResources();
            // Get the defined graphic states.
            HashMap<String, PDExtendedGraphicsState> graphicsStateDictionary = (HashMap<String, PDExtendedGraphicsState>) resources
                    .getGraphicsStates();
            if (graphicsStateDictionary != null) {
                graphicsStateDictionary.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(graphicsStateDictionary);
            } else {
                Map<String, PDExtendedGraphicsState> m = new HashMap<>();
                m.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(m);
            }

            if (invertY) {
                yPosition = pageSize.getHeight() - yPosition;
            }

            float stringWidth = font.getStringWidth(text) * fontSize / 1000f;

            int pageRot = page.findRotation();
            boolean pageRotated = pageRot == 90 || pageRot == 270;
            boolean textRotated = textRotation != 0 && textRotation != 360;

            int totalRot = pageRot - textRotation;

            float pageWidth = pageRotated ? pageSize.getHeight() : pageSize.getWidth();
            float pageHeight = pageRotated ? pageSize.getWidth() : pageSize.getHeight();

            double centeredXPosition = pageRotated ? pageHeight / 2f : (pageWidth - stringWidth) / 2f;
            double centeredYPosition = pageRotated ? (pageWidth - stringWidth) / 2f : pageHeight / 2f;

            contentStream = new PDPageContentStream(pdfDoc, page, true, true, true);
            contentStream.beginText();

            contentStream.setFont(font, fontSize);
            contentStream.appendRawCommands("/TransparentState gs\n");
            contentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]);

            if (pageRotated) {
                contentStream.setTextRotation(Math.toRadians(totalRot), centeredXPosition, centeredYPosition);
            } else if (textRotated) {
                contentStream.setTextRotation(Math.toRadians(textRotation), xPosition, yPosition);
            } else {
                contentStream.setTextTranslation(xPosition, yPosition);
            }

            contentStream.drawString(text);

            contentStream.endText();
            contentStream.close();
            contentStream = null;
        }

        result = PDFUtils.saveInTempFile(pdfDoc);

    } catch (IOException | COSVisitorException e) {
        throw new ClientException(e);
    } finally {
        if (contentStream != null) {
            try {
                contentStream.close();
            } catch (IOException e) {
                // Ignore
            }
        }
        PDFUtils.closeSilently(pdfDoc);
    }
    return result;
}

From source file:org.nuxeo.pdf.PDFWatermarking.java

License:Open Source License

public Blob watermarkWithPdf(Blob inBlob) throws ClientException {

    Blob result = null;//from w ww .  j  a v a 2 s  .c  o  m
    PDDocument pdfDoc = null;
    PDDocument pdfOverlayDoc = null;

    try {
        pdfDoc = PDDocument.load(blob.getStream());
        pdfOverlayDoc = PDDocument.load(inBlob.getStream());

        Overlay overlay = new Overlay();
        overlay.overlay(pdfOverlayDoc, pdfDoc);

        result = PDFUtils.saveInTempFile(pdfDoc);

    } catch (IOException | COSVisitorException e) {
        throw new ClientException(e);
    } finally {
        PDFUtils.closeSilently(pdfDoc, pdfOverlayDoc);
    }

    return result;
}

From source file:org.nuxeo.pdf.PDFWatermarking.java

License:Open Source License

public Blob watermarkWithImage(Blob inBlob, int x, int y, float scale) throws ClientException {

    Blob result = null;/*from  ww w.j  a  v  a  2 s.c  o  m*/
    PDDocument pdfDoc = null;
    PDPageContentStream contentStream = null;

    scale = (scale <= 0f) ? 1.0f : scale;

    try {

        BufferedImage tmp_image = ImageIO.read(inBlob.getStream());

        pdfDoc = PDDocument.load(blob.getStream());
        PDXObjectImage ximage = new PDPixelMap(pdfDoc, tmp_image);

        List<?> allPages = pdfDoc.getDocumentCatalog().getAllPages();
        int max = allPages.size();
        for (int i = 0; i < max; i++) {
            PDPage page = (PDPage) allPages.get(i);

            contentStream = new PDPageContentStream(pdfDoc, page, true, true);
            contentStream.endMarkedContentSequence();
            contentStream.drawXObject(ximage, x, y, ximage.getWidth() * scale, ximage.getHeight() * scale);
            /*
             * AffineTransform at = new AffineTransform(ximage.getWidth() *
             * scale, 200, 200, ximage.getHeight() * scale, x, y);
             * at.rotate(Math.toRadians(90));
             * contentStream.drawXObject(ximage, at);
             */

            contentStream.close();
            contentStream = null;
        }

        result = PDFUtils.saveInTempFile(pdfDoc);

    } catch (IOException | COSVisitorException e) {
        throw new ClientException(e);
    } finally {
        if (contentStream != null) {
            try {
                contentStream.close();
            } catch (IOException e) {
                // Ignore
            }
        }

        PDFUtils.closeSilently(pdfDoc);
    }

    return result;
}

From source file:org.nuxeo.pdf.service.PDFTransformationServiceImpl.java

License:Apache License

@Override
public Blob applyTextWatermark(Blob input, String text, WatermarkProperties properties) {

    // Set up the graphic state to handle transparency
    // Define a new extended graphic state
    PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
    // Set the transparency/opacity
    extendedGraphicsState.setNonStrokingAlphaConstant((float) properties.getAlphaColor());

    try (PDDocument pdfDoc = PDDocument.load(input.getStream())) {

        PDFont font = PDType1Font.getStandardFont(properties.getFontFamily());
        float watermarkWidth = (float) (font.getStringWidth(text) * properties.getFontSize() / 1000f);
        int[] rgb = PDFUtils.hex255ToRGB(properties.getHex255Color());

        for (Object o : pdfDoc.getDocumentCatalog().getAllPages()) {
            PDPage page = (PDPage) o;//from   w w  w  .j a  v a  2 s  . c o  m
            PDRectangle pageSize = page.findMediaBox();
            PDResources resources = page.findResources();

            // Get the defined graphic states.
            HashMap<String, PDExtendedGraphicsState> graphicsStateDictionary = (HashMap<String, PDExtendedGraphicsState>) resources
                    .getGraphicsStates();
            if (graphicsStateDictionary != null) {
                graphicsStateDictionary.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(graphicsStateDictionary);
            } else {
                Map<String, PDExtendedGraphicsState> m = new HashMap<>();
                m.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(m);
            }

            try (PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page, true, true, true)) {
                contentStream.beginText();
                contentStream.setFont(font, (float) properties.getFontSize());
                contentStream.appendRawCommands("/TransparentState gs\n");
                contentStream.setNonStrokingColor(rgb[0], rgb[1], rgb[2]);
                Point2D position = computeTranslationVector(pageSize.getWidth(), watermarkWidth,
                        pageSize.getHeight(), properties.getFontSize(), properties);
                contentStream.setTextRotation(Math.toRadians(properties.getTextRotation()), position.getX(),
                        position.getY());
                contentStream.drawString(text);
                contentStream.endText();
            }
        }
        return saveInTempFile(pdfDoc);

    } catch (Exception e) {
        throw new NuxeoException(e);
    }
}

From source file:org.nuxeo.pdf.service.PDFTransformationServiceImpl.java

License:Apache License

@Override
public Blob applyImageWatermark(Blob input, Blob watermark, WatermarkProperties properties) {

    // Set up the graphic state to handle transparency
    // Define a new extended graphic state
    PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
    // Set the transparency/opacity
    extendedGraphicsState.setNonStrokingAlphaConstant((float) properties.getAlphaColor());

    try (PDDocument pdfDoc = PDDocument.load(input.getStream())) {
        BufferedImage image = ImageIO.read(watermark.getStream());
        PDXObjectImage ximage = new PDPixelMap(pdfDoc, image);

        for (Object o : pdfDoc.getDocumentCatalog().getAllPages()) {
            PDPage page = (PDPage) o;/*from   w w w .ja va2  s .  co  m*/
            PDRectangle pageSize = page.findMediaBox();
            PDResources resources = page.findResources();

            // Get the defined graphic states.
            HashMap<String, PDExtendedGraphicsState> graphicsStateDictionary = (HashMap<String, PDExtendedGraphicsState>) resources
                    .getGraphicsStates();
            if (graphicsStateDictionary != null) {
                graphicsStateDictionary.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(graphicsStateDictionary);
            } else {
                Map<String, PDExtendedGraphicsState> m = new HashMap<>();
                m.put("TransparentState", extendedGraphicsState);
                resources.setGraphicsStates(m);
            }

            try (PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page, true, true)) {
                contentStream.appendRawCommands("/TransparentState gs\n");
                contentStream.endMarkedContentSequence();

                double watermarkWidth = ximage.getWidth() * properties.getScale();
                double watermarkHeight = ximage.getHeight() * properties.getScale();

                Point2D position = computeTranslationVector(pageSize.getWidth(), watermarkWidth,
                        pageSize.getHeight(), watermarkHeight, properties);

                contentStream.drawXObject(ximage, (float) position.getX(), (float) position.getY(),
                        (float) watermarkWidth, (float) watermarkHeight);
            }
        }
        return saveInTempFile(pdfDoc);
    } catch (COSVisitorException | IOException e) {
        throw new NuxeoException(e);
    }
}