PDFBox:根据输入的PDF,在不同位置和大小上绘制图像。

3

我使用在这里另一个问题的答案中由Nick Russler提供的代码,向文档添加了图片https://dev59.com/a2ox5IYBdhLWcg3w3X5S#20618152

/**
 * 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是扫描的A4 TIF图像放在PDF页面上 - 该图像约为1700x2300px - 这与正在发生的缩小比率相吻合),最后,在PDF页面上的另一个TIF图像中,我的添加的图像还会旋转90度。

对我来说,显然需要添加或修改一种变换 - 页面具有默认值 - 或者记住上次使用的变换,我只想要1:1的比例和0度的旋转,但我不知道如何做到这一点?

我已经阅读了有关Matrix和AffineTransformations的内容,但对我来说没有太多意义。

是否有一种方法可以将文档或drawXObject设置为非常1:1的比例和0度旋转?


使用PDPageContentStream构造函数,带有三个布尔参数,最后一个参数也要使用true。 - mkl
谢谢你,我在寻找中错过了这个构造函数。 - CJK
太好了。所以我将其作为一个独立的答案回复。 - mkl
1个回答

2
我的猜测是可能存在某些缩放或变换,但我无法确定在哪里找到或更正它。
是的,你的代码
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);

在页面内容流列表的末尾添加一个新的内容流,就像它本来就存在一样。这意味着它从图形状态开始,前一个流最后结束时的状态。
有些工具创建的内容流以与开始状态相同的状态结束,但这不是PDF规范所要求的。
为确保您的添加从默认图形状态开始,请使用一对运算符q...Q包含现有内容以保存和恢复图形状态。
幸运的是,如果您使用具有三个布尔参数的不同PDPageContentStream构造函数,并将true用作附加参数的值,则PDFBox已经为您执行此操作。
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true, true);

这个构造函数已经过时了,你应该使用PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true); - Mike
"这个构造函数已经被弃用很久了,你应该使用" - 的确,在我的回答之后仅仅过了10个月,就引入了使用 AppendMode 常量的构造函数(不仅允许添加,还允许在前面添加)。" - mkl
好的,这是一个旧但仍然有用的答案,所以我想指出新的构造函数 :) - Mike
没错,很有道理。 - mkl

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