β

通过 Nginx-Lua 自动转换图片为 WEBP 格式

铜芯科技技术博客 647 阅读

有的时候图片实在是费流量, 而且我的 Blog 之前还是用的无损 PNG(之前写的代码和文章各种黑历史,不过有点不舍得删) ,访客一多,就导致流量很大,我们可以将其自动转换为 Google 的 WebP 格式,减小很大一部分的图片空间占用。

安装 libwebp (带 webp 命令行工具包)

通过包管理安装 libwebp

pacman -S libwebp

手动安装

wget " http://downloads.webmproject.org/releases/webp/libwebp-0.5.0-linux-x86-64.tar.gz "

tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local

这样我们就会有了 libwebp 和 "cwebp" 命令来方便的编码图片

自动转换

Lua 代码

因为图片转换只是一次性的,转换完成之后就会直接存储在磁盘上,不会有太大的性能损耗,所以我们可以直接调用命令行工具。

function file_exists(name)
   local f=io.open(name,"r")
   if f~=nil then io.close(f) return true else return false end
end

local newFile = ngx.var.request_filename;
local originalFile = newFile:sub(1, #newFile - 5); -- 去掉 .webp 的后缀

if not file_exists(originalFile) then -- 原文件不存在
  ngx.exit(404);
  return;
end

os.execute("cwebp -q 75 " .. originalFile  .. " -o " .. newFile);   -- 转换原图片到 webp 格式,这里的质量是 75 ,你也可以改成别的

if file_exists(newFile) then -- 如果新文件存在(转换成功)
    ngx.exec(ngx.var.uri) -- Internal Redirect
else
    ngx.exit(404)
end

Nginx 配置

在 http 块中加入

lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;"; # 指向存放 lua 代码的路径

server 块中加入一个 location

location /images {
  expires 365d;
  try_files $uri $uri/ @webp; # 如果文件不存在尝试生成 webp 图片
}

location @webp{
  if ($uri ~ "/([a-zA-Z0-9-_]+)\.(png|jpg|gif)\.webp") { # 这里可以改成你自己的路径匹配,很重要,否则可能会导致别的文件被恶意覆盖等
    content_by_lua_file "/usr/local/nginx/conf/waf/webp.lua";
  }
}

测试效果

重启 Nginx 后,访问原图片路径并在后面加 .webp 扩展名,即可看到图片被正常的转换成了 webp 格式,对前端做一些修改即可完成图片格式的自动选择。

转换 WEBP 之前的 PNG 有 266KB

转换之后的 webp 只有 90KB

http://img0.tycdn.net/images/1428559415329.png

可以看到尺寸改善了很多,画质几乎看不出变化

附一个 SO 看到的 JS 检测浏览器是否支持 webp 的代码 https://jsfiddle.net/JMzj2/29/

讲真其实我现在很讨厌 jquery 这类东西,但是这博客是好久之前写的了已经用了,实在懒得改,就直接用好了(

作者:铜芯科技技术博客
原文地址:通过 Nginx-Lua 自动转换图片为 WEBP 格式, 感谢原作者分享。

发表评论