1186 字
6 分钟
“幽灵表情包”
2025-10-18
统计加载中...

昨天在给 Twikoo 评论系统加小黑盒表情包时,遇到了一连串看似无关、实则环环相扣的问题。整个过程始于一次普通的批量上传,却意外揭开了 PNG 文件结构兼容性的冰山一角。

表情素材很轻松就得到了,是一张包含78个 60×60 表情的大图,而 OwO 需要提前分割成独立图片并写入 owo.json。我用 PIL 写了个基础分割脚本:

from PIL import Image
import os
# 打开图片
img = Image.open('cube1.png')
img_width, img_height = img.size
# 定义每个小素材图的尺寸
tile_width = 60
tile_height = 60
# 计算图片在横纵方向上分别能被分割成多少块
cols = img_width // tile_width
rows = img_height // tile_height
# 创建用于存放结果的文件夹
output_dir = 'split_images'
os.makedirs(output_dir, exist_ok=True)
# 循环进行切割
for row in range(rows):
for col in range(cols):
# 计算每个小图片的边界框 (左, 上, 右, 下)
left = col * tile_width
upper = row * tile_height
right = left + tile_width
lower = upper + tile_height
box = (left, upper, right, lower)
# 切割并保存图片
tile = img.crop(box)
tile.save(f'{output_dir}/tile_{row}_{col}.png')
print(f"分割完成!共 {rows * cols} 个。")

问题初现:从无极到去不#

我先将部分表情上传到“无极图床”,一切正常,表情显示无误。但由于无极限制上传频率,剩下几张图我转而使用“去不图床”。

就在这时,异常出现了:

  • 有两张表情在去不的图库管理界面缩略图显示错误,是旁边图片的缩略图;
  • 直链刚上传时能打开,但几小时后变成 404
  • 第二天早上手机端加载失败,电脑端却又能打开。

这让我非常困惑:同一张图,为何表现如此不稳定?


对照测试中的低级失误#

为了确认是否是图床问题,我做了个对照测试:把在去不出问题的图重新上传到无极图床

但在测试直链时,我犯了一个低级错误或者说被坑了——在 VSC 中ctrl单击链接打开,但是因为bug/特性导致链接带上了末尾的转义反斜杠(如 https...png\"),导致浏览器请求非法 URL,返回 404,关键我也没发现,后来排查时又被坑才反应过来……
至于无极到底正不正常没再测试,可能是正常的,如果没有这个疏忽可能就没这篇博客了(?

正是这个错误的对照测试,让我确信:问题不在图床本身,而在图片文件


误入歧途:压缩工具的干扰#

为“修复”图片,我用了 imagestool.com 的无损压缩工具处理那两张图,想着可能能输出规范的格式。结果更诡异:Windows 资源管理器里透明区域变成了深绿色,虽然用看图软件打开仍是透明。

这说明压缩工具非但没解决问题,反而引入了新问题——透明像素的 RGB 值未清零。


真相:PNG 元数据兼容性差异#

我写了新的脚本验证像素内容,发现原始脚本生成的图其实像素完全规范(Alpha=0 时 RGB=0)。那为何去不图床会拒绝?

最终通过对比文件结构发现:

PIL 默认保存的 PNG 会包含一些非必要元数据或编码特征(如色彩配置、辅助 chunks 等),而“去不图床”的 PNG 解析器极有可能无法正确处理这类结构。

这些细节对浏览器无害,但对兼容性较弱的服务却可能触发解析异常——在校验或缩略图生成阶段失败,导致文件被异步清理。


最终修复:optimize=True#

解决方案出奇简单:在保存时加上 optimize=True

tile.save(f'{output_dir}/tile_{row}_{col}.png', 'PNG', optimize=True)

这个参数会:

  • 移除所有非必要 PNG chunks;
  • 输出仅含 IHDRIDATIEND 的干净结构;
  • 极大提升兼容性。

修复后,所有表情在去不、无极等图床均稳定显示,幽灵图彻底消失。


总结#

  • 起点:无极图床正常,去不图床异常;
  • 干扰项:对照测试时的 JSON 转义错误 + 压缩工具引入深绿色透明;
  • 根源:PIL 默认保留的 PNG 元数据在部分图床中引发解析异常;
  • 解法optimize=True 生成干净 PNG。

这次经历让我明白:“能打开”不等于“能用”——结构干净,才是跨平台稳定的基石

另外,在写的时候才发现,imagestool.com就有图片批量分割功能,也不存在这些问题……
折腾半天还搞出一堆问题,还是用已有的成熟服务省心的多qwq

“幽灵表情包”
https://blog.lonzov.top/posts/ghost-png-fix/
作者
浪小舟
发布于
2025-10-18
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
加载中…
正在加载中……
封面
加载中…
正在加载中……
0:00 / 0:00