如何使用PDFBox将页面的一部分渲染为图像?

时间:2016-03-16 15:05:51

标签: java image pdf pdfbox

PDFBox提供渲染整个页面的功能,但无法仅渲染页面的特定矩形。

似乎实现这一目标的唯一方法是使用PDFRenderer.renderPageToGraphics并配置Graphics2D对象,以便只渲染感兴趣的区域,但我无法弄清楚如何做这一点。

另一种方法是渲染整个页面,然后提取子图像,但我想避免这种情况。

1 个答案:

答案 0 :(得分:1)

所以,它比我最初想的要容易一些。

这是Groovy代码。

import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.rendering.PDFRenderer

import javax.imageio.ImageIO
import java.awt.*
import java.awt.geom.AffineTransform
import java.awt.geom.Rectangle2D
import java.awt.image.BufferedImage
import java.awt.image.RenderedImage

class RegionPDFRenderer {

    private static final int POINTS_IN_INCH = 72

    private final PDDocument document
    private final PDFRenderer renderer
    private final int resolutionDotPerInch

    RegionPDFRenderer(PDDocument document, int resolutionDotPerInch) {
        this.document = document
        this.renderer = new PDFRenderer(document)
        this.resolutionDotPerInch = resolutionDotPerInch
    }

    RenderedImage renderRect(int pageIndex, Rectangle2D rect) {
        BufferedImage image = createImage(rect)
        Graphics2D graphics = createGraphics(image, rect)
        renderer.renderPageToGraphics(pageIndex, graphics)
        graphics.dispose()
        image
    }

    private BufferedImage createImage(Rectangle2D rect) {
        double scale = resolutionDotPerInch / POINTS_IN_INCH
        int bitmapWidth  = rect.width  * scale
        int bitmapHeight = rect.height * scale
        new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_RGB)
    }

    private Graphics2D createGraphics(BufferedImage image, Rectangle2D rect) {
        double scale = resolutionDotPerInch / POINTS_IN_INCH
        AffineTransform transform = AffineTransform.getScaleInstance(scale, scale)
        transform.concatenate(AffineTransform.getTranslateInstance(-rect.x, -rect.y))

        Graphics2D graphics = image.createGraphics()
        graphics.setBackground(Color.WHITE)
        graphics.setTransform(transform)
        graphics
    }

    static void main(String[] args) {
        String filePath = './input.pdf'
        def pageIndex = 0
        def region = new Rectangle(70, 472, 498, 289)
        def resolutionForHiDPIScreenRendering = 220 /* dpi */

        PDDocument doc = PDDocument.load(new File(filePath))
        try {
            def renderer = new RegionPDFRenderer(doc, resolutionForHiDPIScreenRendering)
            def image = renderer.renderRect(pageIndex, region)
            ImageIO.write(image, "png", new File("./output/image.png"))
        } finally {
            doc.close()
        }
    }

}