Java pdf 转 图片

maven 依赖:

<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>2.0.8</version>
</dependency>
<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox-tools</artifactId>
  <version>2.0.8</version>
</dependency>

代码示例:

private static final int HOME_PAGE_INDEX = 0;

/**
 * Pdf -> Image (首页)
 *
 * [@param](https://my.oschina.net/u/2303379) pdf    pdf流
 * [@param](https://my.oschina.net/u/2303379) format 图片格式
 * [@return](https://my.oschina.net/u/556800) pdf 图片流
 */
public static byte[] getImageFromPdf(byte[] pdf, String format) {
    return pdfHomePageToImage(getFromByteArray(pdf), format);
}

/**
 * Pdf -> Image (首页)
 *
 * [@param](https://my.oschina.net/u/2303379) pdf    pdf文件
 * [@param](https://my.oschina.net/u/2303379) format 图片格式
 * @return pdf 图片流
 */
public static byte[] getImageFromPdf(File pdf, String format) {
    return pdfHomePageToImage(getFromFile(pdf), format);
}

/**
 * Pdf -> Image (指定页)
 *
 * @param pdf       pdf文件
 * @param pageIndex 页号(页号从0开始)
 * @param format    图片格式
 * @return pdf 图片流
 */
public static byte[] getImageFromPdf(File pdf, int pageIndex, String format) {
    return pdfToImageWithIndex(getFromFile(pdf), pageIndex, pageIndex, format).get(0);
}

/**
 * Pdf -> Image (指定页)
 *
 * @param pdf       pdf流
 * @param pageIndex 起始页号(页号从0开始)
 * @param format    图片格式
 * @return pdf 图片流
 */
public static byte[] getImageFromPdf(byte[] pdf, int pageIndex, String format) {
    return pdfToImageWithIndex(getFromByteArray(pdf), pageIndex, pageIndex, format).get(0);
}

/**
 * Pdf -> Image (指定页)
 *
 * @param pdf        pdf文件
 * @param startIndex 起始页号(页号从0开始)
 * @param endIndex   终止页号
 * @param format     图片格式
 * @return pdf 图片流
 */
public static List<byte[]> getImageFromPdf(File pdf, int startIndex, int endIndex, String format) {
    return pdfToImageWithIndex(getFromFile(pdf), startIndex, endIndex, format);
}

/**
 * Pdf -> Image (指定页)
 *
 * @param pdf        pdf流
 * @param startIndex 起始页号(页号从0开始)
 * @param endIndex   终止页号
 * @param format     图片格式
 * @return pdf 图片流
 */
public static List<byte[]> getImageFromPdf(byte[] pdf, int startIndex, int endIndex, String format) {
    return pdfToImageWithIndex(getFromByteArray(pdf), startIndex, endIndex, format);
}

private static List<byte[]> pdfToImageWithIndex(PDDocument document, int startIndex, int endIndex, String format) {
    List<byte[]> pdfImages = new ArrayList<>();
    if (startIndex > endIndex) {
        throw new IllegalArgumentException("The param startIndex cannot be greater than endIndex");
    }
    if (endIndex > pdfTotalPages(document)) {
        throw new IllegalArgumentException(String.format("The pdf max page index is [%s], But the endIndex you input is [%s]", pdfTotalPages(document), endIndex));
    }
    for (int i = startIndex; i < endIndex; i++) {
        pdfImages.add(pdfToImage(document, i, endIndex, format));
    }
    return pdfImages;
}

/**
 * Pdf -> Image (所有页)
 *
 * @param pdf    pdf byte[]
 * @param format 图片格式
 * @return 图片 byte[]
 */
public static List<byte[]> getImageFromPdfAllPages(byte[] pdf, String format) {
    return pdfToImageForAllPages(getFromByteArray(pdf), format);
}

/**
 * Pdf -> Image (所有页)
 *
 * @param pdf    pdf文件
 * @param format 图片格式
 * @return 图片 byte[]
 */
public static List<byte[]> getImageFromPdfAllPages(File pdf, String format) {
    return pdfToImageForAllPages(getFromFile(pdf), format);
}

private static List<byte[]> pdfToImageForAllPages(PDDocument document, String format) {
    List<byte[]> pdfImages = new ArrayList<>();
    int totalPages = pdfTotalPages(document);
    for (int i = 0; i < totalPages; i++) {
        pdfImages.add(pdfToImage(document, i, totalPages, format));
    }
    return pdfImages;
}

/**
 * pdf首页 -> image
 *
 * @param document PDDocument
 * @param format   图片格式
 * @return 图片 byte[]
 */
private static byte[] pdfHomePageToImage(PDDocument document, String format) {
    return pdfToImage(document, HOME_PAGE_INDEX, HOME_PAGE_INDEX, format);
}


/**
 * pdf -> image
 *
 * @param document   PDDocument
 * @param startIndex 页号
 * @param endIndex   页数
 * @param format     图片格式
 * @return 图片 byte[]
 */
private static byte[] pdfToImage(PDDocument document, int startIndex, int endIndex, String format) {
    try {
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(startIndex, 100);
        return imageToBytes(bufferedImage, format);
    } catch (Exception e) {
        log.warn("Pdf Read Error:", e);
    } finally {
        // 开发者需要的页数读取完再关闭
        if (startIndex == endIndex) {
            try {
                document.close();
            } catch (IOException e) {
                log.warn("IO Exception", e);
            }
        }

    }
    return null;
}

/**
 * 获取pdf总页数
 *
 * @param document pdf
 * @return pdf总页数
 */
private static int pdfTotalPages(PDDocument document) {
    return document.getNumberOfPages();
}

/**
 * PDDocument
 *
 * @param pdf pdf文件
 * @return 图片 byte[]
 */
private static PDDocument getFromFile(File pdf) {
    try {
        return PDDocument.load(pdf);
    } catch (IOException e) {
        throw new RuntimeException(String.format("Load pdf %s, The File must be a pdf.", e.getMessage()));
    }
}

/**
 * PDDocument
 *
 * @param pdf pdf文件 byte[]
 * @return 图片 byte[]
 */
private static PDDocument getFromByteArray(byte[] pdf) {
    try {
        return PDDocument.load(pdf);
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("Load pdf error: The File must be a pdf.");
    }

}

/**
 * 转换BufferedImage 数据为byte数组
 *
 * @param bImage Image对象
 * @param format image格式字符串.如"gif","png"
 * @return byte数组
 */
private static byte[] imageToBytes(BufferedImage bImage, String format) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        ImageIO.write(bImage, format, out);
    } catch (IOException e) {
        log.warn("IO Exception", e);
    }
    return out.toByteArray();
}

转载于:https://my.oschina.net/u/3757402/blog/3026251

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
<p style="color:#666666;"> <span style="font-size:14px;">本门课程重实战,将基础知识拆解到项目里,让你在项目情境里学知识。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">这样的学习方式能让你保持兴趣、充满动力,时刻知道学的东西能用在哪、能怎么用。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">平时不明白的知识点,放在项目里去理解就恍然大悟了。</span> </p> <p style="color:#666666;"> <span></span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>一、融汇贯通</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本视频采用了前后端分离的开发模式,前端使用Vue.js+Element UI实现了Web页面的呈现,后端使用Python 的Django框架实现了数据访问的接口,前端通过Axios访问后端接口获得数据。在学习完本章节后,真正理解前后端的各自承担的工作。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>二、贴近实战</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本系列课程为练手项目实战:学生管理系统v4.0的开发,项目包含了如下几个内容:项目的总体介绍、基本功能的演示、Vuejs的初始化、Element UI的使用、在Django中实现针对数据的增删改查的接口、在Vuejs中实现前端增删改查的调用、实现文件的上传、实现表格的分页、实现导出数据到Excel、实现通过Excel导入数据、实现针对表格的批量化操作等等,所有的功能都通过演示完成、贴近了实战</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>三、课程亮点</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">在本案例中,最大的亮点在于前后端做了分离,真正理解前后端的各自承担的工作。前端如何和后端交互</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>适合人群:</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">1、有Python语言基础、web前端基础,想要深入学习Python Web框架的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">2、有Django基础,但是想学习企业级项目实战的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">3、有MySQL数据库基础的朋友</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><img alt="" src="https://img-bss.csdnimg.cn/202009070752197496.png" /><br /> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><br /> </span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值