一、導入PDF處理的包
阿里雲倉庫搜索icepdf-core依賴,找到合適的版本,導入pom.xml文件。
<dependency> <groupId>org.icepdf.os</groupId> <artifactId>icepdf-core</artifactId> <version>6.1.2</version> </dependency>
二、PDF轉圖片存儲
1、讀取目標PDF文件;
2、創建Document對象,通過getNumberOfPages方法獲取PDF頁數;
3、循環創建BufferedImage對象,讀取每頁PDF,並以圖片流的方式輸出,將圖片寫入指定路徑。
import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.Page; import org.icepdf.core.util.GraphicsRenderingHints; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; public class PDFToImageUtil { /*獲取pdf文件名*/ public String getPDFName(String filePath){ File fileOrigin = new File(filePath); String fileName = fileOrigin.getName(); fileName = fileName.substring(0,fileName.lastIndexOf(".")); return fileName; } /*pdf轉圖片*/ public List<String> Pdf2Img(String filePath,String imagePath) throws Exception { String fileName = getPDFName(filePath); File dir = new File(imagePath); if(!dir.exists()){ boolean b = dir.mkdir(); if(!b){ return null; } } Document document = new Document(); document.setFile(filePath); float scale = 2.5f;//縮放比例 float rotation = 0f;//旋轉角度 List<String> filePaths = new ArrayList<String>(); for(int i = 0; i<document.getNumberOfPages();i++){ BufferedImage bufferedImage = (BufferedImage) document.getPageImage(i, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX,rotation,scale); try { File file = new File(imagePath+"/"+fileName+new Date().getTime() +".png"); filePaths.add(file.getPath()); ImageIO.write(bufferedImage,"png",file); }catch (IOException e){ e.printStackTrace(); } bufferedImage.flush(); } document.dispose(); return filePaths; } }
4、生成圖片后,方法會將圖片的全路徑存入List並返回。
三、拼接圖片
1、獲取所有圖片路徑,循環遍歷圖片,用BufferedImage對象存儲;
2、獲取每張圖片的RGB,用數組存儲;
3、以每張圖片的左上角為起始坐標,根據縱向坐標不斷累加的原理,將RGB拼接;
4、循環完成后,對最終拼接完成的BufferedImage對象寫入指定位置生成拼接后的圖片。
import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.List; import javax.imageio.ImageIO; public class PDFToMergeImageUtil { public String Pdf2MergeImg(String filePath,String imagePath) throws Exception { PDFToImageUtil pdfToImageUtil = new PDFToImageUtil(); List<String> filePaths = pdfToImageUtil.Pdf2Img(filePath, imagePath); String fileName = pdfToImageUtil.getPDFName(filePath); BufferedImage destImage = null; for(int i =0 ; i < filePaths.size() - 1;i++){ BufferedImage img1 = null; BufferedImage img2 = null; if(i == 0){ img1 = getBufferedImage(filePaths.get(i)); img2 = getBufferedImage(filePaths.get(i+1)); }else{ img1 = destImage; img2 = getBufferedImage(filePaths.get(i+1)); } // 從圖片中讀取RGB int[] imageArrayOne = new int[img1.getWidth() * img1.getHeight()]; imageArrayOne = img1.getRGB(0, 0, img1.getWidth(), img1.getHeight(), imageArrayOne, 0, img1.getWidth()); // 逐行掃描圖像中各個像素的RGB到數組中 int[] imageArrayTwo = new int[img2.getWidth() * img2.getHeight()]; imageArrayTwo = img2.getRGB(0, 0, img2.getWidth(), img2.getHeight(), imageArrayTwo, 0, img2.getWidth()); destImage = new BufferedImage(img1.getWidth(), img1.getHeight()+img2.getHeight(), BufferedImage.TYPE_INT_RGB); destImage.setRGB(0, 0, img1.getWidth(), img1.getHeight(), imageArrayOne, 0, img1.getWidth()); // 設置上半部分或左半部分的RGB destImage.setRGB(0, img1.getHeight(), img2.getWidth(), img2.getHeight(), imageArrayTwo, 0, img2.getWidth()); // 設置下半部分的RGB } File fileAll = new File(imagePath+"/"+fileName+".jpg"); ImageIO.write(destImage,"png",fileAll); destImage.flush(); return fileAll.getPath(); } /** * @param fileUrl * 文件絕對路徑或相對路徑 * @return 讀取到的緩存圖像 * @throws IOException * 路徑錯誤或者不存在該文件時拋出IO異常 */ private BufferedImage getBufferedImage(String fileUrl) throws IOException { File f = new File(fileUrl); return ImageIO.read(f); } }
四、測試
import org.jeecg.business.utils.PDFToMergeImageUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.io.IOException; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class Pdf2Image { @Value(value = "${path.imagePath}") private String imagePath; @Test public void test1() throws Exception { PDFToMergeImageUtil pdf = new PDFToMergeImageUtil(); String listImg = pdf.Pdf2MergeImg("D://java//maven.pdf",imagePath); System.out.println(listImg); } }
五、總結
總的來說就是通過BufferedImage的讀寫及RGB渲染實現,如果PDF文件的頁數較多時,可能會出現堆內存不夠的情況。