Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 974
Lea Avatar asked Apr 19 '18 07:04

Lea


People also ask

What is PDFBox used for?

Apache PDFBox is an open source Java library that can be used to create, render, print, split, merge, alter, verify and extract text and meta-data of PDF files.

Is PDFBox free to use?

Bookmark this question. Show activity on this post. PDFbox is that PDFbox is the free version.


1 Answers

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.

like image 126
Lea Avatar answered Sep 28 '22 10:09

Lea