一、关于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倍才能较为清楚地看到两者的区别,转化后图片确实进行了像素的减少和虚化。如下图:左侧是转化后图片,右侧是原图。