java PDF轉圖片


1.所需jar包

<!--PDF轉圖片-->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.20</version>
</dependency>

  如果需要改變字體的話,還需要加上這個:

<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>fontbox</artifactId>
    <version>2.0.9</version>
</dependency>

2.代碼實現

  通過Apache的pdfbox實現

/*
 * PDF轉圖片
 * @attention: 將整個PDF文件轉圖片(所有頁)
 * @date: 2021-05-12 10:46
 * @param: imgPath
 * 圖片全路徑
 * @param: imgNamePrefix
 * 圖片名稱前綴
 * @param: pdfBytes
 * PDF二進制流
 * @return: boolean
 */
public static boolean toImageFromBytes(String imgPath, String imgNamePrefix, byte[] pdfBytes) {
    return toImageFromBytes(imgPath, imgNamePrefix,"png", pdfBytes);
}

/*
 * PDF轉圖片
 * @attention:
 * @date: 2021-06-21 14:46
 * @param: imgPath
 * @param: imgNamePrefix
 * @param: pdfBytes
 * @param: imgType
 * @return: boolean
 */
public static boolean toImageFromBytes(String imgPath, String imgNamePrefix, String imgType, byte[] pdfBytes) {
    return toImageFromBytes(imgPath, imgNamePrefix, imgType, pdfBytes, 0, -1);
} 
/*
 * PDF轉圖片
 * @attention: 支持自主選擇起始頁和結束頁
 * @date: 2021-05-12 10:41
 * @param: imgPath
 * 圖片全路徑
 * @param: imgNamePrefix
 * 圖片名稱前綴
 * @param: imgType
 * 圖片類型
 * @param: pdfBytes
 * PDF二進制流
 * @param: pageStartIndex
 * 開始頁:開始轉換的頁碼(第1頁,頁碼為0)
 * @param: pageEndIndex
 * 結束頁:結束轉換的頁碼(最后1頁,頁碼為-1)
 * @return: boolean
 * 只有PDF文件所有頁數轉換成功才返回true
 */
public static boolean toImageFromBytes(String imgPath, String imgNamePrefix, String imgType, byte[] pdfBytes, int pageStartIndex, int pageEndIndex) {

    if (StringUtils.isEmpty(imgPath)) {
        log.info("圖片保存路徑不能為空");
        return false;
    }
    if (StringUtils.isEmpty(imgNamePrefix)) {
        log.info("圖片名稱不能為空");
        return false;
    }
    if (pdfBytes == null) {
        log.info("pdf字節數組不能為空");
        return false;
    }
    if (StringUtils.isEmpty(imgType)) {
        log.info("圖片格式不能為空");
        return false;
    }
    if (pageStartIndex < -1 || pageEndIndex < -1) {
        log.info("PDF轉圖片的起始頁或結束頁必須>=-1");
        return false;
    }

    if (pageEndIndex != -1 && pageStartIndex > pageEndIndex) {
        log.info("PDF轉圖片的起始頁不能>結束頁");
        return false;
    }

    // 圖片類型處理
    if (!imgType.startsWith(".")) imgType = "." + imgType;

    // 圖片名稱處理(注意文件名里不要有點,否則一律視為后綴名被抹掉)
    if (imgNamePrefix.indexOf(".") > 0) imgNamePrefix = imgNamePrefix.substring(0, imgNamePrefix.indexOf(".") );

    // 添加路徑分隔符
    if (!imgPath.endsWith("/") && !imgPath.endsWith("\\")) imgPath += File.separator;

    try {
        // Date:2021-05-24
        // 創建圖片目錄(確保圖片的上級目錄存在)
        File directory = new File(imgPath);
        // 目錄不存在就創建
        directory.mkdirs();

        // 加載PDF
        PDDocument doc = PDDocument.load(pdfBytes);
        PDFRenderer renderer = new PDFRenderer(doc);
        // pdf總頁數
        int pageCount = doc.getNumberOfPages();
        log.info("該pdf文件共有" + pageCount + "頁");

        // 如果是起始頁是末頁的話,設置首頁的下標索引(末頁頁碼-1)
        if (pageStartIndex == -1) {
            pageStartIndex = pageCount - 1;
        }
        // 如果是結束頁是末頁的話,設置末頁的下標索引(末頁頁碼-1)
        if (pageEndIndex == -1) {
            pageEndIndex = pageCount - 1;
        }

        for (int i = pageStartIndex; i <= pageEndIndex; i++) {
            // dpi越大轉換后越清晰,相對轉換速度越慢
            BufferedImage image = renderer.renderImageWithDPI(i, 250); // Windows native DPI
            // BufferedImage srcImage = resize(image, 240, 240);//產生縮略圖

            // 生成圖片
            // Date:2021-06-21
            // ImageIO.write()第二個參數代表圖片的類型,不能帶".",否則圖片生成失敗
            if (pageCount == 1)
                ImageIO.write(image, imgType.substring(1), new File(imgPath + imgNamePrefix + imgType));
            else
                ImageIO.write(image, imgType.substring(1), new File(imgPath + imgNamePrefix + "_" + (i + 1) + imgType));

            log.info("pdf第" + (i + 1) + "頁轉圖片成功");
        }

        log.info("pdf-->圖片成功(起始頁:" + (pageStartIndex + 1) + ",結束頁:" + (pageEndIndex + 1) + ")");
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        log.error("pdf-->圖片失敗:" + e.getMessage());
        return false;
    }

}  

3.調用

toImageFromBytes("C:\\Users\\Marydon\\Desktop", "圖片", Base64Utils.decodeToBytes(sb.toString()));  

  注意:

  我曾嘗試直接將PDF數據強制輸出到圖片文件中,結果發現這樣是行不通的(生成的圖片文件無法打開)

  這,也就證明了PDF的數據流和圖片的數據流,雖然都可以通過java轉換成流,但兩個本質還是不一樣的。

2021-06-21

4.補充

  增加PDF文件直接轉圖片的方法,其核心點在於:文件轉bytes[]

/*
 * pdf文件轉img
 * @attention:
 * @date: 2021-06-21 16:38
 * @param: pdfCompletePath
 * @param: saveImgPath
 * @param: imgName
 * @return: boolean
 */
public static boolean toImageFromFile(String pdfCompletePath, String saveImgPath, String imgName) {

    if (StringUtils.isEmpty(pdfCompletePath)) {
        log.info("PDF文件所在完整路徑不能為空");
        return false;
    }
    // 設置圖片路徑
    if (StringUtils.isEmpty(saveImgPath)) {
        saveImgPath = "D:" + File.separator;
    }
    // 設置圖片名稱
    if (StringUtils.isEmpty(imgName)) imgName = DateUtils.getSysdateStr("yyyyMMddHHmmssSSS");

    return toImageFromFile(pdfCompletePath, saveImgPath, imgName, ".png");
}


/*
 * pdf文件轉img
 * @attention:
 * @date: 2021-06-21 16:38
 * @param: pdfCompletePath
 * @param: saveImgPath
 * @param: imgName
 * @param: imgType
 * @return: boolean
 */
public static boolean toImageFromFile(String pdfCompletePath, String saveImgPath, String imgName, String imgType) {
    return toImageFromFile(pdfCompletePath, saveImgPath, imgName, imgType,0, -1);
}
/*
 * pdf文件轉img
 * @attention:
 * @date: 2021-06-21 16:25
 * @param: pdfCompletePath pdf完整路徑
 * @param: imgPath 圖片路徑
 * @param: imgName 圖片名稱
 * @param: imgType 圖片類型
 * @param: pageStartIndex PDF的起始頁
 * 開始轉換的頁碼(第1頁,頁碼為0)
 * @param: pageEndIndex PDF的結束頁
 * 結束頁:結束轉換的頁碼(最后1頁,頁碼為-1)
 * @return: boolean
 */
public static boolean toImageFromFile(String pdfCompletePath, String imgPath, String imgName, String imgType, int pageStartIndex, int pageEndIndex) {

    if (StringUtils.isEmpty(pdfCompletePath)) {
        log.info("PDF文件所在完整路徑不能為空");
        return false;
    }

    if (StringUtils.isEmpty(imgPath)) {
        log.info("圖片保存路徑不能為空");
        return false;
    }
    if (StringUtils.isEmpty(imgName)) {
        log.info("圖片名稱不能為空");
        return false;
    }
    if (StringUtils.isEmpty(imgType)) {
        log.info("圖片類型不能為空");
        return false;
    }

    byte[] pdfBytes = null;
    try {
        // 文件轉文件流
        pdfBytes = Files.readAllBytes(Paths.get(pdfCompletePath));
    } catch (IOException e) {
        log.error("PDF文件-->Bytes[]失敗:" + e.getMessage());
        e.printStackTrace();
        return false;
    }

    return toImageFromBytes(imgPath, imgName, imgType, pdfBytes, pageStartIndex, pageEndIndex);
}

  調用:

toImageFromFile("C:\\Users\\Marydon\\Desktop\\個人信用報告.pdf","C:\\Users\\Marydon\\Desktop","cc", "png", -1, -1);

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM