Java圖片轉換Webp格式


一、關於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格式圖片。原圖為:

原圖 大小479 KB (491,075 字節)

轉換后圖片為:

 轉換后文件大小為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倍才能較為清楚地看到兩者的區別,轉化后圖片確實進行了像素的減少和虛化。如下圖:左側是轉化后圖片,右側是原圖。

 

 


免責聲明!

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



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