使用PDFBox在PDF文件中绘制自动调整大小的图像。

6
我的目标是在一个空白的PDF文件(DIN A4)上绘制一张上传的图片,但我不知道它的尺寸。对于横向图片,我有一个带有一个水平空白页面的PDF文件;对于纵向图片,我有一个带有一个垂直页面的PDF文件。
以下是我的代码:
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://dev59.com/F2Ag5IYBdhLWcg3wwdPA

PDPageContentStream contentStream = new PDPageContentStream(doc, page);

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

对于竖直的图片,一切正常(我更希望图片居中显示,但这是下一步)。问题出在水平的图片上:我的上传的水平图片没有填满整个水平pdf页面,而是得到了一个水平的pdf页面,我的图片在左边被旋转了90度向右,并从上到下适合(缩放可以工作,但不是我所希望的方式): enter image description here 我的愿望是正确地插入上传的水平或垂直图片,而不需要旋转到预定的PDF页面。

关于识别Exif元数据,您可以像这个答案中的操作一样进行(它是在iText上下文中的一个答案,但对于Exif元数据识别使用了单独的库)。 - mkl
我现在有另一个问题...我会编辑帖子...但是谢谢。 - Lea
@mkl,你现在可以看一下这篇文章吗?我看到你之前评论了一个类似的问题,但是那个PDFBox版本有点不同:https://dev59.com/PXLYa4cB1Zd3GeqPd_0Y - Lea
1
getScaledDimension 是做什么用的? - TuGordoBello
1个回答

8

我知道找到了一个解决方法……虽然不是最优雅的方法,但它有效。我得到的结果是我的垂直或水平图像(如果需要)缩小到A4格式并居中在页面上。

我的代码:

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://dev59.com/F2Ag5IYBdhLWcg3wwdPA

// 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();

如果有错误,请纠正我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接