Node.js使用spawn调用pngquant压缩图片与终端执行结果不一致问题
问题原理说明
核心原因:二进制数据的错误编码转换
你最初的代码出错的根本原因确实和字符串编码逻辑相关:
- Node.js 中
child_process输出的data事件默认返回的是Buffer类型的原始二进制数据,当你执行output += data时,Node.js 会隐式调用Buffer.toString('utf-8')把二进制内容转成UTF-8字符串再拼接。 - PNG 是二进制格式文件,内部存在大量不符合UTF-8编码规则的字节序列,这些非法字节在转换时会被统一替换为U+FFFD替换字符(显示为�),每个替换字符占3个字节,这就直接导致两个问题:原始二进制数据被篡改、文件体积异常变大。你看到的输出还符合PNG格式特征是因为PNG的文件头几个字节刚好是合法的UTF-8序列,没有被替换,所以头部识别正常,但后续的实际像素数据已经全部损坏了。
- 你在终端直接执行命令时,shell 是直接传递二进制流,没有做编码转换,所以输出的文件是正常的。
修改后代码生效的原因
你调整后的逻辑全程没有做二进制到字符串的转换:
- 把每一段输出的
Buffer直接存入数组,最后调用Buffer.concat()合并为完整的二进制 Buffer,完全保留了 pngquant 输出的原始PNG数据,写入文件后自然是正常的。
通用注意事项:处理图片、压缩包、音视频等非文本类二进制内容时,全程都应该用
Buffer或者流来传递/存储数据,避免任何隐式或显式的字符串编码转换操作,否则都会导致文件损坏。
内容的提问来源于stack exchange,提问作者Efog
相关产品推荐
相关产品推荐

