一、關於Webp
WebP(發音:weppy)是一種同時提供了有損壓縮與無損壓縮(可逆壓縮)的圖片文件格式,派生自影像編碼格式VP8,被認為是WebM多媒體格式的姊妹項目,是由Google在購買On2 Technologies后發展出來,以BSD授權條款發布。
WebP最初在2010年發布,目標是減少文件大小,但達到和JPEG格式相同的圖片質量,希望能夠減少圖片檔在網絡上的發送時間。2011年11月8日,Google開始讓WebP支持無損壓縮和透明色(alpha通道)的功能,而在2012年8月16日的參考實做libwebp 0.2.0中正式支持。根據Google較早的測試,WebP的無損壓縮比網絡上找到的PNG檔少了45%的文件大小,即使這些PNG檔在使用pngcrush和PNGOUT處理過,WebP還是可以減少28%的文件大小。
WebP支持的像素最大數量是16383x16383。有損壓縮的WebP僅支持8-bit的YUV 4:2:0格式。而無損壓縮(可逆壓縮)的WebP支持VP8L編碼與8-bit之ARGB色彩空間。又無論是有損或無損壓縮皆支持Alpha透明通道、ICC色彩配置、XMP詮釋數據。
WebP有靜態與動態兩種模式。動態WebP(Animated WebP)支持有損與無損壓縮、ICC色彩配置、XMP詮釋數據、Alpha透明通道。
二、開始轉換
參考https://blog.csdn.net/lx542657544/article/details/77871524,從https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html下載所需libwebp-0.4.1-rc1-windows-x64腳本包。
轉換器bin目錄中包括以下工具
- cwebp:將圖片轉換為webp格式
- dwebp:解碼webp
- gif2webp:gif動圖轉換為webp格式
一般這要這樣就可以轉換好了cwebp [options] input_file -o output_file.webp.
如果是gif就將工具換為gif2webp 其他都不用改.常用option為-q 設置壓縮質量 如75質量等.
編寫一個工具類
package example; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; public class ImageFormatConverter { private static Logger log = Logger.getLogger(String.valueOf(ImageFormatConverter.class)); public static boolean convertFromUrlToWebp(String fileUrl,String outPutFile,Integer quality) { //首先從url獲得源文件 File file = saveUrlAs(fileUrl,outPutFile,""); String filePath = file.getPath()+File.separator+"xxx.png"; return convertToWebp(filePath); } public static boolean convertToWebp(String inputFile, String outputFile) { return convertToWebp(inputFile, outputFile, 75); } public static boolean convertToWebp(String inputFile, String outputFile, Integer quality) { if (!new File(inputFile).exists()) { return false; } /*if (!new File(outputFile).exists()) { new File(outputFile).mkdirs(); }*/ return executeCWebp(inputFile, outputFile, quality); } /** * execute cwebp command:cwebp [options] input_file -o output_file.webp */ /** * * @param inputFile * 原圖片路徑 * @param outputFile * webp路徑 * @param quality * 圖片質量1-100 * @return */ private static boolean executeCWebp(String inputFile, String outputFile, Integer quality) { boolean result = false; Class cl = ImageFormatConverter.class; // 換成相應的路徑 String cwebpPath = cl.getResource("/META-INF/libwebp-0.4.1-rc1-windows-x64/bin/cwebp.exe").getPath(); System.out.println("cwebpPath=" + cwebpPath); try { StringBuilder command = new StringBuilder(cwebpPath); command.append(" -q " + (quality == 0 ? 75 : quality)); command.append(" " + inputFile); command.append(" -o " + outputFile); Runtime.getRuntime().exec(command.toString()); result = true; } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); } return result; } public static boolean convertToWebp(String inputFile) { String outputFile = inputFile.split("\\.")[0] + ".webp"; return convertToWebp(inputFile, outputFile, 75); } public static void main(String[] args) { String inputFile = "https://desk-fd.zol-img.com.cn/t_s1920x1200c5/g2/M00/0B/0C/ChMlWV5g8MuIEW7tAAW1SrkHhDsAANkcALNw6MABbVi878.jpg"; String outputFile = "J:/文件暫存/jpg"; if (convertFromUrlToWebp(inputFile, outputFile, 75)) { System.out.println("convert ok~"); } else { System.out.println("sth wrong happened"); } } public static File saveUrlAs(String url,String filePath,String method){ //System.out.println("fileName---->"+filePath); //創建不同的文件夾目錄 File file=new File(filePath); //判斷文件夾是否存在 if (!file.exists()) { //如果文件夾不存在,則創建新的的文件夾 file.mkdirs(); } FileOutputStream fileOut = null; HttpURLConnection conn = null; InputStream inputStream = null; try { // 建立鏈接 URL httpUrl=new URL(url); conn=(HttpURLConnection) httpUrl.openConnection(); //以Post方式提交表單,默認get方式 if (method!=null&&!"".equals(method)){ switch (method.toUpperCase()){ case "GET": conn.setRequestMethod("GET"); break; case "POST": conn.setRequestMethod("POST"); break; } } conn.setDoInput(true); conn.setDoOutput(true); // post方式不能使用緩存 conn.setUseCaches(false); //連接指定的資源 conn.connect(); //獲取網絡輸入流 inputStream=conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(inputStream); //判斷文件的保存路徑后面是否以/結尾 if (!filePath.endsWith("/")) { filePath += "/"; } //寫入到文件(注意文件保存路徑的后面一定要加上文件的名稱) fileOut = new FileOutputStream(filePath+"xxx.png"); BufferedOutputStream bos = new BufferedOutputStream(fileOut); byte[] buf = new byte[4096]; int length = bis.read(buf); //保存文件 while(length != -1) { bos.write(buf, 0, length); length = bis.read(buf); } bos.close(); bis.close(); conn.disconnect(); } catch (Exception e) { e.printStackTrace(); System.out.println("拋出異常!!"); } return file; } }
將轉換質量設置為75,生成轉換后的的webp格式圖片。原圖為:

轉換后圖片為:

轉換后文件大小為181 KB (185,670 字節)文件大小明顯縮小,實際對比效果如下:在壓縮質量75時我發現兩者差距極小,幾乎看不出區別,壓縮質量很高。

String cwebpPath = cl.getResource("/META-INF/libwebp-0.4.1-rc1-windows-x64/bin/cwebp.exe").getPath();
項目路徑不要帶有中文 否則會出現無法找到exe的錯誤。
實驗過程中,我發現當選擇的圖片質量為4K分辨率時然后在進行轉化,然后將原圖和轉化后圖片方法500倍才能較為清楚地看到兩者的區別,轉化后圖片確實進行了像素的減少和虛化。如下圖:左側是轉化后圖片,右側是原圖。

