格式问题很少出在像素上,出在标签上。只接受 JPG 的上传框会拒掉一张完全正常的 PNG;打印店打不开 WebP;主题需要透明背景,却拿到一张 JPEG;页面加载慢,很多时候只是因为图库里塞着一堆没缩过的原图。这些都是容器格式的选择,不是修图,所以放在浏览器里做正合适:文件被解码、按你想要的尺寸画到 canvas 上、再编码成目标格式,用的全是设备上本来就有的 API。相比装一个软件,在这里做转换的实际理由和所有本地工具一样——被转换的图片常常是私密的:体检报告、护照照片、合同截图、客户手机里的照片。本页没有上传接口,也就没有东西可以被截获;耗时只是你本机 CPU 的处理时间。
三种格式的性格完全不同
PNG 无损且支持完整透明通道,所以截图、logo、图表以及任何带文字或纯色的内容都应该保持 PNG,代价是体积:无损编码逐像素原样存储,一张照片存成 PNG,体积常常是同一张照片 JPEG 的好几倍,把已经高效的 PNG 再转一遍 PNG,除了消耗 CPU 没有任何收益。JPEG 是有损格式,通用性最好,但完全没有 alpha 通道——这是最常见的意外:带透明的 PNG 转成 JPEG 不是变成略微透明,而是透明区域变成不透明的黑块,因为编码器合成到了未定义的背景上。解决办法是先把 canvas 填成你想要的背景色再画图,文档用白色,卡片用品牌色。WebP 是现代的折中方案:像 JPEG 一样有损,但同画质下体积小 25% 到 35% 左右,同时支持真正的透明通道,画质参数也确实生效。
会静默降级的浏览器行为
有两种浏览器行为经常造成困惑,值得记住。第一,WebP 编码取决于浏览器:canvas 只能输出当前引擎支持的格式,当你要的类型不被支持时,编码器会退回 PNG 且不告诉你。如果你本该得到 WebP 却拿到一个更大的文件,先看看实际生成的文件后缀。第二,色彩描述文件会丢失。canvas 工作在单一色彩空间里,通常是 sRGB,所以在广色域屏幕上截的图或 P3 照片转出来会略微发闷,原来内嵌的 ICC 配置也没了。两者都不算缺陷,绝大多数网页用途也看不出来,但这正是严谨的设计师不该把浏览器转换当作印刷生产环节的原因。
转换就是重新编码,要注意代数损失
每一次转换都要重新解码和编码一次。PNG 源转 JPEG 或 WebP 只是一代有损损失,完全可以接受;JPEG 转 WebP 再转 JPEG 就是两代,而反复 JPEG 转 JPEG 正是画质变糊的典型路径。每次都从你的原始母版开始转换,母版留好,本页产出的每一个文件都当成派生副本。如果源文件是已经压过三轮的 JPEG,转换不会找回任何东西,只会把已有的伪影再编码深一代——这种情况下唯一的办法是回到最初的原始文件。
常见问题
原图会被上传吗?
不会。转换通过 canvas 和 Blob API 在这个标签页里完成,你选的文件由浏览器从本地读取,不会发往任何地方。本站有广告,广告服务商会看到页面层面的数据,比如你的 IP 地址,但看不到你的图片。
为什么我的 PNG 转成 JPEG 后反而大了?
可能有两种原因。如果是把照片从 PNG 转成 JPEG 变大了,那份 PNG 本来就存得很高效,而高画质档的 JPEG 并不是真的省事。如果是截图或 logo 转 JPEG 后明显变大,这也很正常——有损编码会花大量字节去记录你看不出差异的平滑渐变。这类内容请保持 PNG,只转换真正需要的部分。
转成 JPEG 之后透明背景变黑了,为什么?
因为 JPEG 不支持透明。浏览器把透明像素合成到了未定义的背景上,通常就是黑色。请从原始 PNG 转 JPEG;如果需要特定背景色,先在 canvas 上铺一层填色矩形再画图。需要透明的话,WebP 和 PNG 都支持。
可以一次转换很多张吗?
可以,选中多个文件后会逐个在浏览器里处理。实际限制来自设备内存:每张图都会被完整解码成位图,手机上一堆 5000 万像素的照片就可能耗尽移动浏览器可用的内存。在手机上分批处理更稳妥。