PDFBox:根据输入的 PDF 在不同的位置和大小绘制图像
PDFBox: Draws images in different locations and sizes depending on input PDF
我已使用 Nick Russler 提供的代码将图像添加到文档中以回答此处的另一个问题
/**
* Draw an image to the specified coordinates onto a single page. <br>
* Also scaled the image with the specified factor.
*
* @author Nick Russler
* @param document PDF document the image should be written to.
* @param pdfpage Page number of the page in which the image should be written to.
* @param x X coordinate on the page where the left bottom corner of the image should be located. Regard that 0 is the left bottom of the pdf page.
* @param y Y coordinate on the page where the left bottom corner of the image should be located.
* @param scale Factor used to resize the image.
* @param imageFilePath Filepath of the image that is written to the PDF.
* @throws IOException
*/
public static void addImageToPage(PDDocument document, int pdfpage, int x, int y, float scale, String imageFilePath) throws IOException {
// Convert the image to TYPE_4BYTE_ABGR so PDFBox won't throw exceptions (e.g. for transparent png's).
BufferedImage tmp_image = ImageIO.read(new File(imageFilePath));
BufferedImage image = new BufferedImage(tmp_image.getWidth(), tmp_image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
image.createGraphics().drawRenderedImage(tmp_image, null);
PDXObjectImage ximage = new PDPixelMap(document, image);
PDPage page = (PDPage)document.getDocumentCatalog().getAllPages().get(pdfpage);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.drawXObject(ximage, x, y, ximage.getWidth()*scale, ximage.getHeight()*scale);
contentStream.close();
}
基本上图像是通过 XObjectImage 添加到 PDF 页面的,但是我发现相同的代码会根据所使用的 PDF 得到不同的结果。我的猜测是似乎有一些比例或变换在起作用,但我不知道在哪里可以找到或更正它。
页面报告(来自 MediaBox PDRectangle)它(大约)为 600x800(页面单位)。但是当我放置我的 500px 图像时,它根据使用的 PDF 显示不同。在一个 PDF 中,它以页面的宽度出现(这是一个生成的 PDF - 即文本和对象等)。在另一个 PDF 中,图像大约是宽度的一半到三分之一(此 PDF 是 PDF 页面上扫描的 A4 TIF 图像 - 图像约为 1700x2300px - 这与我的图像发生的收缩率一致),并且PDF 页面上的最后一个 TIF 图像,我添加的图像也旋转了 90 度。
对我来说很明显我需要添加或修改一个转换 - 页面有一个默认值 - 或者正在记住上次使用的转换,我想要的只是 1:1 比率和 0 度旋转,但我不知道该怎么做?
我读过 Matrix 和 AffineTransformations - 但它对我来说意义不大。
有没有办法将文档或 drawXObject 设置为非常 1:1 且旋转 0 度的比例?
My guess is there seems to be some scale or transform in play but I cant work out where to find or correct this.
是的,你的代码
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
按原样在页面的内容流列表末尾添加一个新的内容流。这意味着它从以前最后一个流结束的图形状态开始。
有些工具创建的内容流的结束状态与开始状态相同,但这不是 PDF 规范强加的要求。
为确保您的添加以默认图形状态开始,您必须将现有内容包含在一对运算符中 q...Q 保存和恢复图形状态。
幸运的是,如果您使用不同的 PDPageContentStream
构造函数(具有三个布尔参数的构造函数)并使用 true
作为附加参数的值,PDFBox 已经为您完成了此操作:
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true, true);
我已使用 Nick Russler 提供的代码将图像添加到文档中以回答此处的另一个问题
/**
* Draw an image to the specified coordinates onto a single page. <br>
* Also scaled the image with the specified factor.
*
* @author Nick Russler
* @param document PDF document the image should be written to.
* @param pdfpage Page number of the page in which the image should be written to.
* @param x X coordinate on the page where the left bottom corner of the image should be located. Regard that 0 is the left bottom of the pdf page.
* @param y Y coordinate on the page where the left bottom corner of the image should be located.
* @param scale Factor used to resize the image.
* @param imageFilePath Filepath of the image that is written to the PDF.
* @throws IOException
*/
public static void addImageToPage(PDDocument document, int pdfpage, int x, int y, float scale, String imageFilePath) throws IOException {
// Convert the image to TYPE_4BYTE_ABGR so PDFBox won't throw exceptions (e.g. for transparent png's).
BufferedImage tmp_image = ImageIO.read(new File(imageFilePath));
BufferedImage image = new BufferedImage(tmp_image.getWidth(), tmp_image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
image.createGraphics().drawRenderedImage(tmp_image, null);
PDXObjectImage ximage = new PDPixelMap(document, image);
PDPage page = (PDPage)document.getDocumentCatalog().getAllPages().get(pdfpage);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.drawXObject(ximage, x, y, ximage.getWidth()*scale, ximage.getHeight()*scale);
contentStream.close();
}
基本上图像是通过 XObjectImage 添加到 PDF 页面的,但是我发现相同的代码会根据所使用的 PDF 得到不同的结果。我的猜测是似乎有一些比例或变换在起作用,但我不知道在哪里可以找到或更正它。
页面报告(来自 MediaBox PDRectangle)它(大约)为 600x800(页面单位)。但是当我放置我的 500px 图像时,它根据使用的 PDF 显示不同。在一个 PDF 中,它以页面的宽度出现(这是一个生成的 PDF - 即文本和对象等)。在另一个 PDF 中,图像大约是宽度的一半到三分之一(此 PDF 是 PDF 页面上扫描的 A4 TIF 图像 - 图像约为 1700x2300px - 这与我的图像发生的收缩率一致),并且PDF 页面上的最后一个 TIF 图像,我添加的图像也旋转了 90 度。
对我来说很明显我需要添加或修改一个转换 - 页面有一个默认值 - 或者正在记住上次使用的转换,我想要的只是 1:1 比率和 0 度旋转,但我不知道该怎么做?
我读过 Matrix 和 AffineTransformations - 但它对我来说意义不大。
有没有办法将文档或 drawXObject 设置为非常 1:1 且旋转 0 度的比例?
My guess is there seems to be some scale or transform in play but I cant work out where to find or correct this.
是的,你的代码
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
按原样在页面的内容流列表末尾添加一个新的内容流。这意味着它从以前最后一个流结束的图形状态开始。
有些工具创建的内容流的结束状态与开始状态相同,但这不是 PDF 规范强加的要求。
为确保您的添加以默认图形状态开始,您必须将现有内容包含在一对运算符中 q...Q 保存和恢复图形状态。
幸运的是,如果您使用不同的 PDPageContentStream
构造函数(具有三个布尔参数的构造函数)并使用 true
作为附加参数的值,PDFBox 已经为您完成了此操作:
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true, true);