JAVA中pdf轉圖片的幾種方法(二)


JAVA基於PDF box將PDF轉為圖片(轉自阿里雲社區)

1.引用:fontbox-2.0.16.jar、pdfbox-app-2.0.16.jar 版本一定要正確,否則代碼會有問題。

main函數:

package kevin.cn;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.PDFBox;

import kevin.cn.PdfUtil;
@SuppressWarnings("unused")
public class Test {

//經過測試,dpi為96,100,105,120,150,200中,105顯示效果較為清晰,體積穩定,dpi越高圖片體積越大,一般電腦顯示分辨率為96 public static final float DEFAULT_DPI = 105; //默認轉換的圖片格式為jpg public static final String DEFAULT_FORMAT = "jpg"; public static void main(String[] args) throws Exception { pdfToImage("/media/kevin/FileData/JavaCode/pdfboxTest/企業信息化建設論文.pdf","/media/kevin/FileData/JavaCode/pdfboxTest/img/7.jpg",5); }

  實現函數:

/**

 * pdf轉圖片 * * @param pdfPath PDF路徑 * @imgPath img路徑 * @page_end 要轉換的頁碼,也可以定義開始頁碼和結束頁碼,我這里只需要一頁,根據需求自行添加 */ public static void pdfToImage(String pdfPath, String imgPath,int page_end) { try { //圖像合並使用參數 // 總寬度 int width = 0; // 保存一張圖片中的RGB數據 int[] singleImgRGB; int shiftHeight = 0; //保存每張圖片的像素值 BufferedImage imageResult = null; //利用PdfBox生成圖像 PDDocument pdDocument = PDDocument.load(new File(pdfPath)); PDFRenderer renderer = new PDFRenderer(pdDocument); //循環每個頁碼 for (int i = 0, len = pdDocument.getNumberOfPages(); i < len; i++) { if (i==page_end) { BufferedImage image = renderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB); int imageHeight = image.getHeight(); int imageWidth = image.getWidth(); //計算高度和偏移量 //使用第一張圖片寬度; width = imageWidth; //保存每頁圖片的像素值 imageResult = new BufferedImage(width, imageHeight, BufferedImage.TYPE_INT_RGB); //這里有高度,可以將imageHeight*len,我這里值提取一頁所以不需要 singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width); // 寫入流中 imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width);
        //合並pdf
          if(i==23){
          imageResult1 = imageResult;
        }else {
         imageResult = merge(imageResult1, imageResult);
        }
}else if(i>page_end) { continue; } } pdDocument.close();
// 寫圖片
ImageIO.write(imageResult, DEFAULT_FORMAT, new File(imgPath));
} catch (Exception e) { e.printStackTrace(); } //OVER }
相關的(版本必須一致)jar:
<!--pdf轉圖片-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.0-alpha2</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>3.0.0-alpha2</version>
</dependency>
注意:

  根據3.0遷移指南,PDDocument.load方法已替換為Loader方法:

對於加載PDF,PDDocument.load已被Loader方法替換。加載FDF文檔也是如此。

當保存一個PDF文件時,這將在默認的壓縮模式下完成。使用CompressParameters.NO_COMPRESSION覆蓋PDDocument.save。

PDFBox現在以增量方式加載PDF文檔,以減少初始內存占用。如果只訪問PDF的某些部分,這也將減少消耗PDF所需的內存。請注意,由於PDF的性質,諸如遍歷所有頁面、訪問注釋、簽署PDF等用途可能仍然會超時加載PDF的所有部分,從而導致與PDFBox 2.0類似的內存消耗。

輸入文件不能用作保存操作的輸出。它將損壞文件並引發異常,因為在第一次保存文件時會讀取部分文件。

因此,您可以切換到PDFBox的早期2.x版本,或者需要使用新的Loader方法。我認為這應該奏效:

File file = new File("C:\\Meeting IDs.pdf");
PDDocument doc1 = Loader.loadPDF(file));

合並圖片的工具方法

復制代碼
 
//經過測試,dpi為96,100,105,120,150,200中,105顯示效果較為清晰,體積穩定,dpi越高圖片體積越大,一般電腦顯示分辨率為96
public static final float DEFAULT_DPI = 105;
//默認轉換的圖片格式為png
public static final String DEFAULT_FORMAT = "png";
/**
* @description: pdf轉成一張圖片
* @author xiyun.zhao
* @param: pdfFile
* @param: outpath
* @return:
* @date: 2021/10/21 11:36
*/
public static void pdfToImage(String pdfFile, String outpath,Integer page) {
try {
InputStream is = new FileInputStream(pdfFile);
//利用PdfBox生成圖像
PDDocument pdf = Loader.loadPDF(is);
PDFRenderer renderer = new PDFRenderer(pdf);
int actSize = pdf.getNumberOfPages();
List<BufferedImage> piclist = new ArrayList<>();
for (int i = 0; i < actSize; i++) {
if(i<page) {
BufferedImage image = renderer.renderImageWithDPI(i, DEFAULT_DPI, ImageType.RGB);
piclist.add(image);
}
}
yPic(piclist, outpath);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 將寬度相同的圖片,豎向追加在一起 ##注意:寬度必須相同
* @param piclist 文件流數組
* @param outPath 輸出路徑
*/
public static void yPic(java.util.List<BufferedImage> piclist, String outPath) {// 縱向處理圖片
if (piclist == null || piclist.size() <= 0) {
System.out.println("圖片數組為空!");
return;
}
try {
int height = 0, // 總高度
width = 0, // 總寬度
_height = 0, // 臨時的高度 , 或保存偏移高度
__height = 0, // 臨時的高度,主要保存每個高度
picNum = piclist.size();// 圖片的數量
int[] heightArray = new int[picNum]; // 保存每個文件的高度
BufferedImage buffer = null; // 保存圖片流
List<int[]> imgRGB = new ArrayList<int[]>(); // 保存所有的圖片的RGB
int[] _imgRGB; // 保存一張圖片中的RGB數據
for (int i = 0; i < picNum; i++) {
buffer = piclist.get(i);
heightArray[i] = _height = buffer.getHeight();// 圖片高度
if (i == 0) {
width = buffer.getWidth();// 圖片寬度
}
height += _height; // 獲取總高度
_imgRGB = new int[width * _height];// 從圖片中讀取RGB
_imgRGB = buffer.getRGB(0, 0, width, _height, _imgRGB, 0, width);
imgRGB.add(_imgRGB);
}
_height = 0; // 設置偏移高度為0
// 生成新圖片
BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < picNum; i++) {
__height = heightArray[i];
        //這樣寫有問題(有些pdf轉不成功)
//if (i != 0) _height += __height; // 計算偏移高度
       //改為:
       if (i != 0) _height += heightArray[i-1]; // 計算偏移高度
            imageResult.setRGB(0, _height, width, __height, imgRGB.get(i), 0, width); // 寫入流中
}
File outFile = new File(outPath);
ImageIO.write(imageResult, DEFAULT_FORMAT, outFile);// 寫圖片
} catch (Exception e) {
e.printStackTrace();
}
}





免責聲明!

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



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