Search code examples
javaimagepdfpdfboximage-resizing

Draw auto-resized image in PDF file with PDFBox


My aim is it to draw an uploaded image of which I do not know the dimensions on a PDF file with one empty page (DIN A4). For horizontal images I have a PDF file with one horizontal empty page and for vertical images I have a PDF file with one vertical page.

This is my code so far:

File image = convertMultipartFileToFile(file); //I get a MultipartFile from my RequestParam (Spring) - converting works fine
BufferedImage awtImage = ImageIO.read(image);

String path = "";

if (awtImage.getWidth() > awtImage.getHeight()) {
    path = MyController.class.getResource("/pdf4ImageUploadHorizontal.pdf").getPath();
} else {
    path = MyController.class.getResource("/pdf4ImageUploadVertical.pdf").getPath();
}

pdf = new File(path);
PDDocument doc = PDDocument.load(pdf);
PDPage page = doc.getPage(0);
int actualPDFWidth = 0;
int actualPDFHeight = 0;
if (awtImage.getWidth() > awtImage.getHeight()) {

    actualPDFWidth = (int) PDRectangle.A4.getHeight();
    actualPDFHeight = (int) PDRectangle.A4.getWidth();
} else {
    actualPDFWidth = (int) PDRectangle.A4.getWidth();
    actualPDFHeight = (int) PDRectangle.A4.getHeight();
}

// Add image to page
PDImageXObject pdImage = PDImageXObject.createFromFileByContent(image, doc);

Dimension scaledDim = getScaledDimension(new Dimension(pdImage.getWidth(), pdImage.getHeight()), new Dimension(actualPDFWidth, actualPDFHeight)); // I'm using this function: https://stackoverflow.com/questions/23223716/scaled-image-blurry-in-pdfbox

PDPageContentStream contentStream = new PDPageContentStream(doc, page);

contentStream.drawImage(pdImage, 0, 0, scaledDim.width, scaledDim.height);
contentStream.close();
doc.save("c:\\xyz\\pdf.pdf");

For vertical images everything works fine (I would prefer the images to be centered on the page but that'd be the next step).

Problem is with horizontal images: instead of my uploaded horizontal image filling the complete horizontal pdf page I get a horizontal pdf page with my image on the left being rotated 90° to the right and fitting from top to bottom (scaling worked but not the way I hoped for): enter image description here

My wish is to insert uploaded horizontal or vertical pictures correctly without rotation into to the intended PDF page.


Solution

  • I know found a solution...for sure it is not the most elegant one but it works. The result I get is my vertical or horizontal image if necessary scaled down to the A4 format and centered on the page. My code:

    File image = convertMultipartFileToFile(file);
    BufferedImage awtImage = ImageIO.read(image);
    
    // check if horizontal or vertical
    Boolean isHorizontal = false;
    if (awtImage.getWidth() > awtImage.getHeight()) {
        isHorizontal = true;
    }
    String path = "";
    
    // get actual height and width of pdf page 'cause pdfbox sees page always as vertical and only saves the rotation   
    // ....-------------------
    // ...|...................|
    // ...|.........A4........|...0.x
    // ...|......PDF.page.....|..0y-|----------------------------
    // ...|......vertical.....|.....|............A4..............|
    // ...|...._________......|.....|.........PDF.page...........|
    // ...|...(.........).....|.....|........horizontal..........|
    // ...|...(..image..).....|.....|...._______________.........|
    // ...|...(.........).....|.....|...(...............)........|
    // ...|...(.........).....|.....|...(....image......)........|
    // ...|...(.........).....|.....|...(_______________)........|
    // ...|...(_________).....|.....|----------------------------
    // 0x-|-------------------
    // ..0y
    int actualPDFWidth = 0;
    int actualPDFHeight = 0;
    if (isHorizontal) {
        actualPDFWidth = (int) PDRectangle.A4.getHeight();
        actualPDFHeight = (int) PDRectangle.A4.getWidth();
        path = MyController.class.getResource("/pdf4ImageUploadHorizontal.pdf").getPath();
    } else {
        actualPDFWidth = (int) PDRectangle.A4.getWidth();
        actualPDFHeight = (int) PDRectangle.A4.getHeight();
        path = MyController.class.getResource("/pdf4ImageUploadVertical.pdf").getPath();
    }
    
    pdf = new File(path);
    PDDocument doc = PDDocument.load(pdf);
    PDPage page = doc.getPage(0);
    
    PDImageXObject pdImage = PDImageXObject.createFromFileByContent(image, doc);
    PDPageContentStream contentStream = new PDPageContentStream(doc, page);
    
    // scale image
    Dimension scaledDim = getScaledDimension(new Dimension(pdImage.getWidth(), pdImage.getHeight()), new Dimension(actualPDFWidth, actualPDFHeight)); // I'm using this function: https://stackoverflow.com/questions/23223716/scaled-image-blurry-in-pdfbox
    
    // if horizontal rotate 90°, calculate position and draw on page
    if (isHorizontal) {
        int x = (int) PDRectangle.A4.getWidth() - (((int) PDRectangle.A4.getWidth() - scaledDim.height) /2);
        int y = ((int) PDRectangle.A4.getHeight() - scaledDim.width) / 2;
        AffineTransform at = new AffineTransform(scaledDim.getHeight(), 0, 0, scaledDim.getWidth(), x, y);
        at.rotate(Math.toRadians(90));
        Matrix m = new Matrix(at);
        contentStream.drawImage(pdImage, m);
    } else {
        int x = ((int) PDRectangle.A4.getWidth() - scaledDim.width) / 2;
        int y = ((int) PDRectangle.A4.getHeight() - scaledDim.height) / 2;
        contentStream.drawImage(pdImage, x, y, scaledDim.width, scaledDim.height);
    }
    
    contentStream.close();
    doc.save("c:\\xyz\\pdf.pdf");           
    doc.close();
    

    Please correct me if there's something wrong.