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