全球主机交流论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

CeraNetworks网络延迟测速工具IP归属甄别会员请立即修改密码
查看: 574|回复: 9

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

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式
收费的CDN用不起。

免费的也不会有。


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


有没有其他的方案?
发表于 前天 18:15 来自手机 | 显示全部楼层
安装 image_filter 模块
 楼主| 发表于 昨天 00:13 | 显示全部楼层
Slimyang 发表于 2025-6-8 18:15
安装 image_filter 模块

这个模块似乎没看到重写webp的功能,大佬有没有这个模块的官网?我谷歌了下没找到。
发表于 昨天 01:01 | 显示全部楼层
webp有啥优势
发表于 昨天 01:26 | 显示全部楼层

一般情况下,webp图片文件大小会变的很小,也就加快了图片加载速度,节省了带宽。
发表于 昨天 01:34 | 显示全部楼层
根据您的需求,您希望找到一个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很难吗
发表于 昨天 06:23 | 显示全部楼层
我采用的方法是nginx转发处理,如果请求包含了特定参数,并且是image图片类型,则通过本地脚本读取对应图片缓存,然后进行输出。如果读取不到则调用SDK根据传递的参数进行图片裁剪、转换。并返回对应的内容,同时缓存到本地,以便下次使用
发表于 昨天 07:42 | 显示全部楼层
要是WP 程序的话 有插件啊 全自动 不需要额外搞
发表于 昨天 07:57 来自手机 | 显示全部楼层
我是老王 发表于 2025-6-9 07:42
要是WP 程序的话 有插件啊 全自动 不需要额外搞

我要是你,就会审计下代码。
不然你想站被跳?
发表于 昨天 12:25 | 显示全部楼层
https://github.com/weserv/images

官方是直接打包好的nginx+图片处理,我单独抽离了这个模块出来编译到了openresty上
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|全球主机交流论坛

GMT+8, 2025-6-10 17:12 , Processed in 0.062467 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表