小萝卜 发表于 前天 21:11

有没有什么Nginx模块可以全站图片自动重写成webp?不要CDN

收费的CDN用不起。

免费的也不会有。


但是我觉得应该有什么模块或者插件可以实现。谷歌的Ngx_Pagespeed就算了,已经是7年前的产品,跟nginx1.17后的版本都不兼容。


有没有其他的方案?

Slimyang 发表于 昨天 18:15

安装 image_filter 模块

小萝卜 发表于 10 小时前

Slimyang 发表于 2025-6-8 18:15
安装 image_filter 模块

这个模块似乎没看到重写webp的功能,大佬有没有这个模块的官网?我谷歌了下没找到。

masir 发表于 9 小时前

webp有啥优势

盖茨 发表于 9 小时前

masir 发表于 2025-6-9 01:01
webp有啥优势

yc018t 一般情况下,webp图片文件大小会变的很小,也就加快了图片加载速度,节省了带宽。

jsdv 发表于 9 小时前

根据您的需求,您希望找到一个Nginx模块来实现全站图片的自动WebP重写,并且不依赖CDN。以下是一些可行的方案:

**1. 使用 `ngx_http_image_filter_module` 模块结合 `map` 指令**

*   **`ngx_http_image_filter_module`**: 这是Nginx官方提供的一个模块,可以用来动态转换JPEG、GIF、PNG和WebP格式的图片。 不过,它默认可能没有编译进Nginx,您可能需要重新编译Nginx并在编译时通过 `--with-http_image_filter_module` 参数来启用它。
*   **`map` 指令**: 您可以使用Nginx的 `map` 指令来检查浏览器发送的 `Accept` 请求头。如果浏览器支持WebP格式,则将请求重写到WebP版本的图片。

**工作流程大致如下:**

1.**判断浏览器支持**: Nginx通过`map`指令检测HTTP请求头中的`Accept`字段,判断浏览器是否声明支持`image/webp`。
2.**尝试提供WebP**: 如果浏览器支持WebP,并且服务器上存在对应图片的`.webp`版本(例如,`example.jpg.webp`),则Nginx会返回WebP格式的图片。
3.**实时转换 (可选)**: 如果服务器上不存在预转换的WebP图片,`ngx_http_image_filter_module` 可以配置为实时将JPEG/PNG等格式转换为WebP。但请注意,实时转换会增加服务器的CPU负载。
4.**回退到原图**: 如果浏览器不支持WebP,或者WebP版本的图片不存在(且未配置实时转换),Nginx会返回原始格式的图片(如JPEG或PNG)。

**Nginx配置示例思路 (具体配置需根据您的环境调整):**

```nginx
http {
    # Map to check if browser accepts webp
    # 映射,检查浏览器是否接受webp
    map $http_accept $webp_suffix {
      default "";
      "~*webp" ".webp";
    }

    # Ensure Nginx knows the .webp mime type
    # 确保Nginx识别.webp的mime类型
    # (Newer Nginx versions should already have this in mime.types)
    # (较新版本的Nginx应该已经在mime.types中包含了)
    # types {
    #   image/webp webp;
    # }

    server {
      listen 80;
      server_name yourdomain.com;

      location ~* ^/path/to/images/.+\.(png|jpe?g)$ {
            add_header Vary Accept; # Important for caching proxies # 对缓存代理很重要
            try_files $uri$webp_suffix $uri =404; # Try to serve .webp, then original # 尝试提供.webp,然后是原图

            # Optional: On-the-fly conversion if webp doesn't exist
            # 可选:如果webp不存在则进行实时转换
            # This requires ngx_http_image_filter_module and libgd or libvips
            # 这需要ngx_http_image_filter_module以及libgd或libvips
            # error_page 404 = @generate_webp;
      }

      # Optional: Location for on-the-fly WebP generation
      # 可选:用于实时生成WebP的location
      # location @generate_webp {
      #   set $webp_uri $uri$webp_suffix;
      #   image_filter resize 400 400; # Example: resize, not strictly for webp conversion
                                          # 示例:调整大小,并非严格用于webp转换
      #   image_filter_jpeg_quality 75;
      #   image_filter_webp_quality 80;
      #   image_filter_buffer 10M;
      #   # Logic to convert original to webp and serve it
      #   # 转换原图为webp并提供的逻辑
      #   # This part is complex and might need additional scripting or modules
      #   # 这部分比较复杂,可能需要额外的脚本或模块
      # }
    }
}
```

**2. 使用 Nginx + Lua 脚本 (例如 OpenResty)**

*   **Lua 模块**: 通过Nginx的Lua模块(如 `lua-nginx-module`),您可以编写Lua脚本来处理图片请求。
*   **`libwebp`**: 您需要在服务器上安装 `libwebp` 这个库,它提供了将图片转换为WebP格式的命令行工具 (如 `cwebp`)。

**工作流程大致如下:**

1.**Nginx接收请求**: 当Nginx接收到图片请求时。
2.**Lua脚本处理**: Lua脚本会检查浏览器是否支持WebP。
3.**检查WebP是否存在**: 如果支持,脚本会检查本地是否已经存在该图片的WebP版本。
4.**按需转换**: 如果WebP图片不存在,Lua脚本会调用服务器上的`cwebp`工具将原图转换为WebP格式,并保存下来供后续请求使用。
5.**返回图片**: 根据浏览器支持情况和WebP文件是否存在,返回合适的图片格式。

**Nginx配置示例思路 (来自搜索结果)**:

```nginx
# 在 http 段添加:
# In http block add:
lua_package_path "/path/to/your/lua/scripts/?.lua;;"; # 根据实际路径修改 # Modify according to your actual path

server {
    # ... 其他配置 ... other configurations ...

    location ~* /path/to/images/.+\.(png|jpe?g)$ {
      set $original_uri $uri;
      set $webp_uri $uri.webp;

      # 检查浏览器是否接受webp
      # Check if browser accepts webp
      if ($http_accept ~* "image/webp") {
            # 尝试直接提供webp文件,如果存在
            # Try to serve webp file directly if it exists
            try_files $webp_uri @generate_webp_lua;
      }

      # 如果浏览器不支持webp或者webp文件不存在,则提供原图
      # If browser does not support webp or webp file does not exist, serve original image
      try_files $original_uri =404;
    }

    location @generate_webp_lua {
      # 调用Lua脚本处理
      # Call Lua script for processing
      content_by_lua_file /path/to/your/lua/scripts/webp_converter.lua; # 根据实际路径修改 # Modify according to your actual path
    }
}
```

**Lua 脚本示例 (`webp_converter.lua`) 思路 (来自搜索结果)**:

```lua
-- webp_converter.lua
local 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 original_image_path = ngx.var.document_root .. ngx.var.original_uri -- 假设original_uri是相对于文档根目录的路径
                                                                        -- Assuming original_uri is relative to document root
local webp_image_path = ngx.var.document_root .. ngx.var.webp_uri   -- 假设webp_uri是相对于文档根目录的路径
                                                                        -- Assuming webp_uri is relative to document root

if not file_exists(original_image_path) then
    ngx.exit(ngx.HTTP_NOT_FOUND)
    return
end

if not file_exists(webp_image_path) then
    -- 调用 cwebp 进行转换,质量参数可以调整
    -- Call cwebp for conversion, quality parameter can be adjusted
    local command = string.format("cwebp -q 75 %s -o %s", original_image_path, webp_image_path)
    local handle = io.popen(command)
    handle:close() -- Ensure process finishes Ensure process finishes
end

if file_exists(webp_image_path) then
    ngx.exec(ngx.var.webp_uri) -- 内部重定向到 WebP 图片 Internal redirect to WebP image
else
    -- 如果转换失败,可以考虑返回原图或错误
    -- If conversion fails, consider returning the original image or an error
    ngx.exec(ngx.var.original_uri) -- 或者 ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) or ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
```

**重要注意事项:**

*   **性能**: 实时图片转换会消耗服务器CPU资源。对于高流量网站,建议预先批量转换所有图片,或者结合缓存策略。
*   **存储**: 如果您选择转换并存储WebP图片,会占用额外的磁盘空间。
*   **编译Nginx**: `ngx_http_image_filter_module` 和 `lua-nginx-module` 通常需要您在编译Nginx时手动加入。
*   **`libwebp` 安装**: 使用Lua方案时,确保服务器上已安装 `libwebp` 工具。
*   **WordPress插件**: 如果您使用的是WordPress,有一些插件如WebP Express或Smush Pro(部分功能)可以与Nginx配合,或者独立完成本地WebP转换和提供,而无需CDN。 这些插件通常会提供相应的Nginx配置规则。
*   **测试**: 在生产环境部署前,务必在测试环境中充分测试配置,确保其按预期工作且不会引入性能问题。

您可以根据您的服务器环境、技术栈以及对性能和复杂性的权衡来选择最适合您的方案。对于不想重新编译Nginx的用户,基于Lua的方案或者利用已有的图片处理工具脚本可能是更便捷的选择,但可能在性能上不如原生Nginx模块。



问AI很难吗https://cdn.jsdelivr.net/gh/master-of-forums/master-of-forums/public/images/patch.gif

心乐 发表于 4 小时前

我采用的方法是nginx转发处理,如果请求包含了特定参数,并且是image图片类型,则通过本地脚本读取对应图片缓存,然后进行输出。如果读取不到则调用SDK根据传递的参数进行图片裁剪、转换。并返回对应的内容,同时缓存到本地,以便下次使用

我是老王 发表于 2 小时前

要是WP 程序的话 有插件啊 全自动 不需要额外搞

jsdv 发表于 2 小时前

我是老王 发表于 2025-6-9 07:42
要是WP 程序的话 有插件啊 全自动 不需要额外搞

我要是你,就会审计下代码。
不然你想站被跳?
页: [1]
查看完整版本: 有没有什么Nginx模块可以全站图片自动重写成webp?不要CDN