【XIUNOX插件】WebP 压缩 v1.0.0

管理员组

xnx_webp — WebP 压缩

> Xiuno X 插件:上传图片时自动转换为 WebP 格式,显著减小图片体积,提升页面加载速度。

功能特性

  • 自动转换:用户上传图片时自动转换为 WebP 格式,无需手动操作
  • 双引擎支持:优先使用 Imagick(质量更好),降级使用 PHP GD 扩展
  • 等比例缩放:超过最大宽高时按比例缩放,不拉伸变形
  • 透明通道保留:PNG / GIF / BMP 转换后保留透明背景
  • 智能跳过
- 服务器不支持 WebP 时跳过(使用原图)

- 文件小于阈值(默认 100KB)时跳过 - GIF 动图默认跳过(可配置开启) - 已是 WebP 格式跳过

  • 失败降级:转换失败时记录日志并使用原图,不中断上传流程
  • 全局覆盖:覆盖所有走 attach-create 路由的上传场景(发帖、回帖、编辑器插图、应用中心截图等)

环境要求

  • Xiuno X(BBS 1.0+)
  • PHP 7.0+(推荐 PHP 8.0+)
  • 至少安装以下任一扩展
- Imagick(推荐,质量更好)

- PHP GD 扩展(需编译时启用 WebP 支持,imagewebp() 函数可用)

检测命令:

php -m | grep -E "imagick|gd"
php -r "var_dump(function_exists('imagewebp'));"

安装

  1. xnx_webp 目录放入 plugin/
  2. 登录后台 → 插件管理 → 找到「WebP 压缩」→ 点击「安装」并「启用」
  3. (生产环境 DEBUG=0)清理编译缓存:
rm -f tmp/route_attach.php tmp/model.min.php tmp/lang_*_bbs.php
  1. 进入 admin/?plugin-setting-xnx_webp.htm 配置参数

后台配置项

| 配置项 | 说明 | 默认值 | |---|---|---| | 启用 WebP 转换 | 全局开关 | 开 | | 压缩质量 | 1-100,数值越大质量越好体积越大 | 80 | | 最大宽度 | 像素,超过则等比缩放,0 表示不限制 | 1920 | | 最大高度 | 像素,超过则等比缩放,0 表示不限制 | 1920 | | 转换 GIF 动图 | 是否将 GIF 动图转为 WebP(默认关闭,保留动图) | 关 | | 最小文件大小 | KB,小于此值的图片不转换 | 100 |

支持的源格式

| 格式 | MIME | Imagick | GD | |---|---|:---:|:---:| | JPEG | image/jpeg | ✅ | ✅ | | PNG | image/png | ✅ | ✅ | | GIF | image/gif | ✅ | ✅ | | BMP | image/bmp | ✅ | PHP 7.2+ | | WebP | image/webp | 跳过 | 跳过 |

工作原理

插件通过 attach_create_save_before hook 注入到 route/attach.php 的上传流程中:

用户上传图片
   ↓
route/attach.php 接收请求
   ↓
[hook] attach_create_save_before.php 拦截
   ↓
WebpService::convert() 转换为 WebP
   ↓
file_put_contents 写回 $_FILES['file']['tmp_name']
   ↓
同步更新 $name / $ext / $size / $tmpname / $tmpfile / $tmpurl
   ↓
move_uploaded_file 移动到最终位置

转换后的文件名后缀会自动改为 .webp(如 photo.jpgphoto.webp),确保用户下载后能用图片查看器正常打开。

覆盖场景

插件覆盖所有走 attach-create 路由(FormData 模式)的上传场景:

  • ✅ 发帖/回帖上传图片
  • ✅ 富文本编辑器(AIEditor / wangEditor)上传图片
  • ✅ xnx_attach 插件附件上传
  • ✅ xnx_appcenter 应用截图上传
  • ✅ 其他任何通过系统上传接口的图片

不覆盖的场景(保持原格式):

  • 头像上传(固定后缀,转换会导致 MIME 不匹配)
  • 勋章图标上传(固定后缀)

降级与容错

| 场景 | 行为 | |---|---| | 服务器未装 Imagick 和 GD | 后台设置页显示红色警告,上传流程使用原图 | | 单次转换失败 | 记录 xn_log 日志(php_error 通道),使用原图 | | 图片损坏无法读取 | getimagesize() 返回 false,跳过转换 | | GIF 动图(默认配置) | 保留原 GIF 格式不动 |

文件结构

plugin/xnx_webp/
├── conf.json                              # 插件配置
├── install.php                            # 安装脚本(初始化默认配置)
├── uninstall.php                          # 卸载脚本(清理 setting)
├── setting.php                            # 后台设置处理
├── icon.png                               # 插件图标
├── README.md                              # 本文档
├── model/
│   └── WebpService.php                    # 核心转换类
├── view/htm/
│   └── setting.htm                        # 后台设置页模板
└── hook/
    ├── attach_create_save_before.php      # 上传前拦截 hook
    ├── model_inc_file.php                 # 注册 Service 到核心
    ├── lang_zh_cn_bbs.php                 # 简体中文
    ├── lang_zh_tw_bbs.php                 # 繁体中文
    └── lang_en_us_bbs.php                 # 英文

验证转换效果

启用插件后上传一张 JPEG/PNG 图片,访问帖子详情页右键图片 → 「在新标签页打开图片」,URL 应以 .webp 结尾。

或在服务器查看:

ls -la upload/attach/<YYYY-MM>/<uid>/
# 应看到 .webp 后缀的文件

常见问题

Q: 后台设置页显示「不支持」?

A: 服务器未安装 Imagick 或 GD 扩展。安装方式:

  • Imagickapt install php-imagick(Debian/Ubuntu)或 pecl install imagick
  • GD with WebP:编译 PHP 时加 --with-webp 参数,或 apt install php-gd(确认版本支持 WebP)

Q: 上传后图片没有变成 WebP?

A: 排查顺序:

  1. 确认插件已启用且「启用 WebP 转换」开关打开
  2. 确认图片大小超过「最小文件大小」阈值(默认 100KB)
  3. 确认不是 GIF 动图(默认不转换)
  4. 清理 tmp/ 编译缓存后重试
  5. 查看 xiunobbs-master/log/php_error_*.php 日志中是否有 WebpService convert failed 记录

Q: 转换后图片体积反而变大了?

A: 通常发生在高质量参数 + 小尺寸图片上。建议:

  • 降低「压缩质量」(如 80 → 70)
  • 提高「最小文件大小」阈值(如 100KB → 200KB)

Q: 透明 PNG 转换后背景变黑了?

A: 已在插件中通过 imagealphablending(false) + imagesavealpha(true) 处理。若仍出现,检查 GD 扩展版本是否过旧。

Q: 会影响已有的旧图片吗?

A: 不会。插件仅在上传时对新图片进行转换,不会扫描和转换历史图片。

卸载

后台 → 插件管理 → 找到「WebP 压缩」→ 点击「卸载」

卸载会清理 setting 表中的 xnx_webp 配置项,已转换的 WebP 图片保留不动。

版本记录

  • v1.0.0 (2026-07-22):首发版本
- 上传图片自动转 WebP

- Imagick 优先 / GD 降级 - 后台可配置:质量、最大宽高、GIF 处理、最小尺寸阈值 - 三语言支持(简中 / 繁中 / 英文)

许可证

随 Xiuno X 主项目分发。

版本 1.0.0 | 兼容 Xiuno 1.1+



版本:v1.0.0
适用版本:1.1
开发者:Twelve

请登录后查看此内容
最新回复

请先登录后再回复 登录