kn007的个人博客
♥ You are here: > > > 为Nginx添加将图片转换成WebP支持

为Nginx添加将图片转换成WebP支持

by | 16 Comments


Nginx对图片的处理,可以利用其对Lua支持(需要lua nginx module)来实现。

今天介绍有关将图片压缩为webp的方法。webp的好处可以自行搜索。

首先,需要准备带有lua nginx module的Nginx,以及libwebp库。

Nginx添加lua nginx module的方法不再表,具体可以参考之前文章《我的Nginx编译之旅》。

关于libwebp,可以通过包管理或其官网安装,官网传送门。注意需要Glibc版本不小于2.14。

接着,创建Lua脚本文件,比如名字为cwebp.lua(Lua脚本名),放在你知道的位置上(我喜欢放在Nginx的配置目录下),内容如下:

---------------------------  Function  ---------------------------------

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

------------------------------------------------------------------------

if ngx ~= nil then
    local reqpath = ngx.var.request_filename;
    local requri = ngx.var.uri;
    local originalFile = reqpath:sub(1, #reqpath - 13);
    local originalFile_uri = requri:sub(1, #requri - 13);

    if not file_exists(originalFile) then
        ngx.exit(404);
        return;
    end

    local newFile_md5 = ngx.md5(originalFile_uri);
    local newFile = ngx.var.document_root .. "/wp-content/webp/" .. newFile_md5 ..".webp";
    local newFile_uri = "/wp-content/webp/" .. newFile_md5 .. ".webp";

    if file_exists(newFile) then
        ngx.req.set_uri(newFile_uri);
        ngx.exec(ngx.var.uri);
        return;
    end

    os.execute("cwebp -quiet " .. originalFile  .. " -o " .. newFile);

    if file_exists(newFile) then
        ngx.req.set_uri(newFile_uri);
    else
        ngx.req.set_uri(originalFile_uri);
    end

    ngx.exec(ngx.var.uri);
end

以上为我按照自己需求做的一个lua脚本,这个脚本的流程是这样的:

1.首先去除!/format/webp的后缀,共计13个字符。
2.如果源文件不存在,返回404并结束。
3.对请求的URI进行md5处理并作为webp文件名,新文件位于根目录下的/wp-content/webp目录下(请按自己需求更改)。
4.如果新文件存在,那么返回该文件内容并结束。不存在的话,调用libwebp库的cwebp程序对图片进行处理。
5.检查webp文件是否被创建,如果存在返回webp文件内容,不存在则返回源文件内容。

如果你是第一次使用Lua,需要在Nginx的http段,添加Lua脚本位置注册:

lua_package_path '/usr/local/nginx/conf/lua/?.lua;;';

其中/usr/local/nginx/conf/lua/为你未来lua脚本文件归置的目录。如果你存放于Nginx默认索引的Lua目录下,可以忽略此步。

你可以根据实际情况,选择是否启用lua_code_cache

最后,在Nginx的server段,添加对!/format/webp请求进行回应,指定由cwebp.lua来处理。

location ~ \!/format/webp$ {
    expires max;
    content_by_lua_file "/usr/local/nginx/conf/lua/cwebp.lua";
}

其中/usr/local/nginx/conf/lua/cwebp.lua为上面创建的cwebp.lua绝对路径,注意它位于注册的Lua归置目录下。

如果你像我一样,也有使用headers more nginx module,那么你可以添加多一句:

more_clear_headers "Set-Cookie*";

来去除图片请求中不必要的cookie传输。

保存后,reload或restart Nginx即可。

php上理论可以通过以下判断浏览器是否支持webp,以此来决定是否为图片添上webp转换后缀。

function browser_is_support_webp(){
    return isset($_SERVER['HTTP_ACCEPT']) ? strstr($_SERVER['HTTP_ACCEPT'],'image/webp') : FALSE;
}

像Wordpress的话,可以利用Wordpress的原生filter:the_content,以及正则函数来达到hook目的。

转载请注明转自:kn007的个人博客的《为Nginx添加将图片转换成WebP支持

donate
有所帮助?

Comments

16 Comments立即评论
Loading...
  1. 更新至 Nginx 级 WebP 生成 :lol:

    1. MOD回复

      @lwl12: :grin: 语文学得不错

  2. 回复

    先占坑 让我看看这次更新了啥 :|

    1. MOD回复

      @一曲长歌辞烟雨: 没有更新,很久很久以前的配置。 :sad:

  3. 啊,终于知道了 libwebp 的用法(摊 :cry:

    1. MOD回复

      @metowolf: 额 ;-) 其实还蛮好用

  4. 回复

    Webp还是有必要的, 不晓得apache是否也有相似的处理方法, 话说google不是有pagespeed么.

    1. MOD回复

      @Sam.Z: apache忘得一干二净。
      我不用pagespeed。

  5. LV1回复

    伺服器:該加工資了

    1. MOD回复

      @Kreen: 早給足了金錢 :arrow:

  6. 回复

    ho to translate this page :oops:

    1. MOD回复

      @karen: Maybe you could try google translation

  7. 你的nginx真牛!有空了跟着你的整一整

    1. MOD回复

      @ayawaw: 没什么牛不牛的,以前就是这样,没进步一直

  8. 回复

    试了一下好像不行诶,Nginx返回404,不清楚是什么情况,Nginx日志也没错误啊,真是纳闷。路径已经改了,也不是权限问题,Lua文件的权限是777啊,也不应该不能执行啊.....emmmm :sad: 大佬可以帮忙看看吗?
    https://t.me/haimaAS1

    1. MOD回复

      @海马: 404无非两种原因啊,第一种源文件不存在,第二种,压根nginx没对后缀hook调用lua。
      把nginx日志等级调一下就能看到原因了。或者把代码中唯一的404改成其他状态码,也能确认。

icon_wink.gificon_neutral.gificon_mad.gificon_twisted.gificon_smile.gificon_eek.gificon_sad.gificon_rolleyes.gificon_razz.gificon_redface.gificon_surprised.gificon_mrgreen.gificon_lol.gificon_idea.gificon_biggrin.gificon_evil.gificon_cry.gificon_cool.gificon_arrow.gificon_confused.gificon_question.gificon_exclaim.gif