上传照片总是报错“无效文件”,但明明尺寸、格式全对
问题就在这:市面上几乎所有的图片压缩工具(不管是网页版的还是 App)逻辑都是“减法”。你设置个目标大小,它只会拼命往下压,试图让文件变小。结果就是,你按照尺寸要求裁好了图,文件本身才 15 KB,你压完之后更小了,系统直接判定你文件太小,拒绝上传,而且报错信息往往极其模糊,甚至干脆直接清空表单,让你一脸懵逼。
这种时候,你需要的不是压缩,而是“扩容”。
如果遇到这种死循环,我的工程思路是:先尝试通过调整 JPEG 质量参数来“反向逼近”目标区间。不要想着压到最小,而是要寻找那个能满足最小体积限制(比如 20 KB)且质量最高的临界点。
如果常规工具搞不定,甚至可以写个简单的脚本,通过在 JPEG 的数据段里注入一些无意义的冗余信息(比如自定义的 Metadata 或填充字节)来强行撑大体积,只要不破坏文件结构就行。
这里有个处理 JPEG 结构逻辑的参考思路,主要是为了在不破坏 SOF(Start of Frame)标记的情况下,通过注入数据来凑大小:
// 核心思路:在不破坏图像数据的情况下,通过在段中插入填充字节来增加文件体积
// 这种方法比单纯拉高质量更可控,尤其是在文件本身已经很小的情况下
const MAX_PAYLOAD = 0xffff - 2;
const segments = [];
let remaining = shortfall;while (remaining > 0) {
const payload = Math.min(remaining > 4 ? remaining - 4 : 1, MAX_PAYLOAD);
const length = payload + 2;
segments.push(0xff, 0xfe, (length >> 8) & 0xff, length & 0xff);
// ... 注入逻辑
}
另外还得提个防坑指南:别光看后缀名。现在 iPhone 默认都是 HEIC 格式,很多时候你通过某些转换工具导出的文件,看着叫 photo.jpg,其实底层字节流还是 HEIC 编码。如果系统后台校验的是文件头(Magic Number),那这种“伪装”的 JPEG 必挂无疑。
遇到这种诡异的上传失败,先别急着怀疑网络,去查查文件头字节和实际体积是不是落在了那个该死的“区间”里。