java圖片處理以及pdf轉圖片
1.需求
之前項目裡面有用到顯示pdf的模組,需要將pdf顯示處理,也結合了一些外掛程式,pdf.js是firefox瀏覽器推出的一套h5渲染pdf的前端外掛程式,支援移動端pc端,但是顯示效果不太好,有時候需要嵌套到移動的webview裡面,顯示時候會有問題,pc端,由於直接採用iframe就支援,但是個別瀏覽器還是不支援,所以為了一次性解決相容,把所有的pdf轉換成圖片就行,這樣就不會出現相容問題了
但是在實際操作時,發現還是有點問題,有的pdf中字型較多,linux伺服器上字型庫沒有時,當時採用的時icetext的類庫,發現當pdf字型icetext無法識別時就會出現亂碼,而且產生圖片時,是按照pdf一頁一張圖片產生的,顯示不太友好. 需求進一步明確 1.一個pdf檔案對應一張圖片 2.不能出現亂碼
最終發現Apache的,pdfbox支援轉出的圖片效果比較好,而且也不會亂碼,但是pdf對應多個圖片
需求2解決了,如何解決一個pdf檔案對應一張圖片的問題尼?
要是能在記憶體中把多張圖片合并成一張圖片就行了,那麼怎麼才能合并圖片尼?
這個其實也不難,之前上學的時候,書本上曾經說個,圖片檔案就是一個一個的像素點組成的,只能我們能擷取並儲存每張圖片的所有像素點,就可以隨時還原這張圖片,當然為了保證圖片不失真,還需要儲存原始寬高. pdfbox代碼實現
代碼中採用的時最新的pdfbox2.0版本,大家可以去官網自行下載
package com.taoyuanx.utils;import java.awt.image.BufferedImage;import java.io.File;import javax.imageio.ImageIO;import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.rendering.ImageType;import org.apache.pdfbox.rendering.PDFRenderer;public class PdfToImage { public static void main(String[] args) { pdfToImage("d://test.pdf"); } //經過測試,dpi為96,100,105,120,150,200中,105顯示效果較為清晰,體積穩定,dpi越高圖片體積越大 //一般電腦顯示解析度為96 public static final float DEFAULT_DPI=105; /**pdf轉圖片 * @param pdfPath */ public static void pdfToImage(String pdfPath){ try{ if(pdfPath==null||"".equals(pdfPath)||!pdfPath.endsWith(".pdf")) return; //映像合并使用參數 int width = 0; // 總寬度 int[] singleImgRGB; // 儲存一張圖片中的RGB資料 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++){ BufferedImage image=renderer.renderImageWithDPI(i, DEFAULT_DPI,ImageType.RGB); int imageHeight=image.getHeight(); int imageWidth=image.getWidth(); if(i==0){//計算高度和位移量 width=imageWidth;//使用第一張圖片寬度; //儲存每頁圖片的像素值 imageResult= new BufferedImage(width, imageHeight*len, BufferedImage.TYPE_INT_RGB); }else{ shiftHeight += imageHeight; // 計算位移高度 } singleImgRGB= image.getRGB(0, 0, width, imageHeight, null, 0, width); imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width); // 寫入流中 } pdDocument.close(); File outFile = new File(pdfPath.replace(".pdf", "_"+DEFAULT_DPI+".jpg")); ImageIO.write(imageResult, "jpg", outFile);// 寫圖片 }catch (Exception e) { e.printStackTrace(); } }}
這裡唯寫了pdf轉圖片的代碼,其實pdfbox還有很多操作,比如浮水印,繪圖之類,如果我們想對產生的圖片做些裁剪,繪製文字之類,可以是bufferimage這個java內建的類實現,可能圖片會有些失真. 後記
因為可能業務後續還涉及到對圖片的操作,所以就瞭解了下,圖片類庫,發現阿里巴巴的simpleimage比較好用,圖片的裁剪,翻轉也不會失真,但是就是有些bug,使用simpleimage時發現,繪製自訂字型時,必須使用全量參數類執行個體化DrawTextItem 的子類.
simpleimage還依賴了oracle的jai圖片類庫,大家使用時可能還需要去掛網下載,簡單的操作圖片還可以的.