使用 PDFBox 在 PDF 文件中绘制自动调整大小的图像
Draw auto-resized image in PDF file with PDFBox
我的目标是在一个空白页 (DIN A4) 的 PDF 文件上绘制一张我不知道其尺寸的上传图像。对于水平图像,我有一个包含水平空白页的 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:
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° 并从上到下调整(缩放工作但不是我希望的方式):
我的愿望是将上传的水平或垂直图片正确插入到预期的 PDF 页面而不旋转。
我知道找到了解决方案...当然它不是最优雅的解决方案,但它确实有效。我得到的结果是我的垂直或水平图像(如有必要)按比例缩小到 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:
// 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();
如有不妥请指正
我的目标是在一个空白页 (DIN A4) 的 PDF 文件上绘制一张我不知道其尺寸的上传图像。对于水平图像,我有一个包含水平空白页的 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:
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° 并从上到下调整(缩放工作但不是我希望的方式):
我的愿望是将上传的水平或垂直图片正确插入到预期的 PDF 页面而不旋转。
我知道找到了解决方案...当然它不是最优雅的解决方案,但它确实有效。我得到的结果是我的垂直或水平图像(如有必要)按比例缩小到 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:
// 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();
如有不妥请指正