You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用PdfBox将多页PDF转换为单张JPG图片?

将多页PDF合并为单张图片(基于Apache PDFBox)

你现在的代码会为PDF的每一页单独生成图片,要改成合并成单张图片,核心思路是先把所有页面渲染成独立图片,再创建一个足够容纳所有页面的大画布,最后把每页图片按顺序绘制到这个画布上并保存。

原代码的问题点

你的原代码仅循环渲染并保存单页图片,缺少合并逻辑:

@Test 
public void testImage() throws IOException { 
    try { 
        PDDocument pdDocument = PDDocument.load(new File("download.pdf")); 
        PDFRenderer pdfRenderer = new PDFRenderer(pdDocument); 
        for (int x = 0; x < pdDocument.getNumberOfPages(); x++) { 
            BufferedImage bImage = pdfRenderer.renderImageWithDPI(x, 300, ImageType.RGB); 
            ImageIOUtil.writeImage(bImage, String.format(x +"__template_image.%s", "jpg"), 300); 
            File imageFile = new File(x +"_template_image.jpg"); 
        } 
        pdDocument.close(); 
    } catch (IOException e) { 
        e.printStackTrace(); 
    } 
}

修改后的完整实现

下面是调整后的代码,每一步都加了注释说明逻辑:

@Test 
public void testMergePdfToSingleImage() throws IOException { 
    PDDocument pdDocument = null;
    List<BufferedImage> pageImages = new ArrayList<>();
    try { 
        pdDocument = PDDocument.load(new File("download.pdf")); 
        PDFRenderer pdfRenderer = new PDFRenderer(pdDocument); 
        int pageCount = pdDocument.getNumberOfPages();

        // 1. 先把所有页面渲染成BufferedImage,存到列表中
        for (int x = 0; x < pageCount; x++) { 
            BufferedImage pageImage = pdfRenderer.renderImageWithDPI(x, 300, ImageType.RGB); 
            pageImages.add(pageImage);
        }

        // 处理空PDF的情况
        if (pageImages.isEmpty()) {
            System.out.println("该PDF没有可处理的页面");
            return;
        }

        // 2. 计算合并后大图的尺寸:取第一页的宽度,总高度为所有页面高度之和
        int singlePageWidth = pageImages.get(0).getWidth();
        int totalHeight = pageImages.stream().mapToInt(BufferedImage::getHeight).sum();

        // 3. 创建能容纳所有页面的空白大图
        BufferedImage mergedImage = new BufferedImage(singlePageWidth, totalHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = mergedImage.createGraphics();

        // 4. 逐页将图片绘制到大图上,从上到下排列
        int currentY = 0;
        for (BufferedImage img : pageImages) {
            g2d.drawImage(img, 0, currentY, null);
            currentY += img.getHeight();
        }
        g2d.dispose(); // 释放绘图资源,避免内存泄漏

        // 5. 保存最终的合并图片
        ImageIOUtil.writeImage(mergedImage, "merged_template_image.jpg", 300);
        System.out.println("单张合并图片已生成!");

    } catch (IOException e) { 
        e.printStackTrace(); 
    } finally {
        // 确保资源被正确关闭
        if (pdDocument != null) {
            pdDocument.close();
        }
        pageImages.forEach(img -> img.flush());
    } 
}

额外说明

  • 如果你的PDF存在页面宽度不一致的情况,可以将大图宽度改为所有页面中的最大值,绘制时可选择居中对齐或保持原宽度(根据需求调整即可)。
  • 代码中保持了原有的300DPI设置,确保图片清晰度和原逻辑一致。

内容的提问来源于stack exchange,提问作者Mohamed Taboubi

火山引擎 最新活动