图片压缩工具把135字节的图标压成了560字节,而画质拉满反倒更小

图片压缩工具把135字节的图标压成了560字节,而画质拉满反倒更小
张文保 30 分钟阅读 4,721 阅读
本文目录
  1. 把一张32×32的图标丢进去,它会还给你多大?
  2. 它有没有骗人?没有
  3. PNG进出一字不差,这不是巧合
  4. 先说结论,省得你往下翻
  5. 那根画质滑块,最右边一格到底做了什么?
  6. 逐像素比对,不看观感看数字
  7. 把产物的二进制拆开看
  8. 带透明的图,无损那一格还少了一个数据块
  9. 这条得加个前提
  10. 为什么线条图和照片,对同一个数值的反应完全相反?
  11. 四类素材的实测体积(单位:字节)
  12. 把这张表读三遍
  13. 中间那一档:logo为什么两边差不多
  14. 背后的道理其实很朴素
  15. 每张图里那456个字节,是谁塞进去的?
  16. 三种格式的固定开销不一样
  17. 那这笔费用什么时候不算钱?
  18. 选JPEG之前,得先知道透明会变成什么颜色
  19. 实测:透明区变成纯黑
  20. 同一张图转WebP,作为对照
  21. 什么时候会踩到
  22. 为什么在缩略图上看不出来
  23. "最大宽度"这个框,管不了你的长图
  24. 一张600×4000的长图,填1200
  25. 而文案里写的是"宽高"
  26. 那个输入框还接受一些它不该接受的值
  27. 300×150是从哪来的
  28. 有哪些东西它会照单全收,但结果不是你要的?
  29. SVG会被静默栅格化
  30. 解码失败的图会一声不吭地消失
  31. 丢一张图,代价不只是少一张图
  32. 竖着拍的照片进去,会不会躺下来?
  33. 手工造一张带方向标记的照片
  34. 结果
  35. 一个说明书没提的好处
  36. 这几类图,分别该怎么设?
  37. 照片:按说明书来就对了
  38. 线条图、图表、纯色插画:把画质拉到1.00
  39. 图标、logo、任何小于5 KB的图:别用这个工具
  40. 透明图:先决定要不要透明
  41. 长图:这个框帮不了你
  42. 先尺寸还是先画质?这个顺序也得看图
  43. 批量作业:多看一眼那个数字
  44. 常见问题解答
  45. 为什么我的图标转成WebP反而变大了?
  46. 画质滑块拉到1.00是不是就无损了?
  47. 线条图和图表到底该用什么设置?
  48. 带透明背景的图转JPEG会怎么样?
  49. 为什么填了最大宽度,我的长图还是没缩小?
  50. 我选了5张图,为什么只出来4张?
  51. 竖着拍的手机照片进去会不会变横的?
  52. 能把SVG丢进去压吗?
  53. 权威参考资料

摘要:把一张135字节的纯色图标丢进去,选它推荐的WebP,出来是560字节,红字标着"大了315%"。这不是bug,是那456个字节的色彩配置文件在起作用——它对每张WebP和JPEG都收这笔固定费用,图越小越致命。

更值得知道的是画质滑块:0.95和1.00之间隔的不是一点点画质,是有损和无损两种编码器。拉到1.00那一格,48万个通道值一个都没变;退回0.95,9万个被改写。对线条图,无损那一格反而让体积腰斩。

这款工具的界面简单到几乎没有学习成本:拖图进去,选格式,拉滑块,点开始。三个控件,一个按钮。正因为简单,很多人默认它就是"把图变小"的黑盒子,选推荐项、拉到甜点区、下载走人。

我把它翻来覆去测了一下午,结论是:它没骗人,每一个数字都如实显示。但它给的三条建议——推荐WebP、画质0.75到0.85、先限尺寸再调画质——是照着一类图写的,那类图叫照片。你手上另外三类图,得反着来。

把一张32×32的图标丢进去,它会还给你多大?

先做一件最没有想象力的事:造一张32×32的纯色方块,颜色是靛蓝,存成PNG,135字节。然后把它喂给这款工具,四种设置各跑一遍。

结果是这样的:

  • 输出PNG:135字节 → 135字节,省0%
  • 输出WebP画质0.8:135字节 → 560字节,大了315%
  • 输出WebP画质1.0:135字节 → 520字节,大了285%
  • 输出JPEG画质0.8:135字节 → 767字节,大了468%

而在格式下拉框里,WebP那一项后面跟着五个字:推荐,体积最小。

它有没有骗人?没有

工具把"大了315%"用红色标了出来,一个字都没藏。它的使用说明里也确实写过"浏览器重新编码PNG体积很可能不降反增"。这两点它做得比很多同类工具都诚实。

问题不在诚实,在推荐。下拉框里那句"推荐,体积最小"是一句无条件的话,它不知道你正要压的是一张图标还是一张风景照。用户看见"推荐"两个字,选它,得到一个反向结果,然后大概率会怀疑是自己哪里设错了。

PNG进出一字不差,这不是巧合

上面那行"PNG 135字节 → 135字节"值得单独说一句。我又拿另外两张图试了同样的事:2651字节的双色logo,出来2651;3648字节的细条纹插画,出来3648。三张图,进出的字节数一个不差。

这不是工具偷懒没处理,它确实老老实实解码、画到画布、再重新编码了一遍。只是浏览器内置的PNG编码器和当初生成这些文件的编码器参数一致,压出来的结果就完全一样。

更值得记住的是它的另一面:浏览器的PNG编码器不做调色板量化。专业工具能把一张256色的插画从32位真彩色降到8位索引色,体积直接砍掉七成,这一步浏览器不做,也没接口让你要求它做。所以对PNG来说,这个工具的能力上限就是"不改变"。想真正压PNG,得换工具。

先说结论,省得你往下翻

32×32这个例子不是极端案例,它是一整类素材的代表:图标、logo、UI截图里的小元素、邮件签名里的小图。这类图有两个共同点——尺寸小、颜色少。对它们来说,PNG才是体积最小的那个,而且往往是原地不动最小。

至于原因,得从那张图里多出来的456个字节说起,那是本文第四节的事。在那之前,先看一个更颠覆的东西:那根画质滑块。

那根画质滑块,最右边一格到底做了什么?

工具的说明里对画质给了一段很有经验感的建议:0.9以上体积下降有限而画质提升几乎看不出,性价比低;0.75到0.85是大多数照片的甜点区;0.6以下开始出现块状伪影。

前两句在照片上是对的。但"0.9以上性价比低"这句话,把一件更重要的事盖住了。

逐像素比对,不看观感看数字

我画了一张400×300的图,故意做得对压缩最不友好:白底上每4像素一根2像素宽的黑竖条,中间压一块玫红色矩形。锐利边缘、纯色大块、高频细节,全齐了。

然后把工具的输出读回来,跟源图逐个通道比对。这张图一共480000个通道值(400×300×4),比对结果:

  • 画质1.00:0个通道值不同,最大偏差0,体积2.5 KB
  • 画质0.95:90489个通道值不同,最大偏差58,体积1.6 KB
  • 画质0.80:182196个通道值不同,最大偏差63,体积1.5 KB

0.95到1.00这一格,跨过去的不是"一点点画质",是有损和无损的分界线。

把产物的二进制拆开看

光看像素还不够硬,我把输出的WebP文件按容器格式逐个数据块解析了一遍。WebP是RIFF容器,图像数据装在不同名字的块里:

  • 画质0.80:VP8X(10) ICCP(456) VP8(1004)
  • 画质0.90:VP8X(10) ICCP(456) VP8(1002)
  • 画质0.95:VP8X(10) ICCP(456) VP8(1122)
  • 画质1.00:VP8X(10) ICCP(456) VP8L(2044)

按Google的WebP容器规范,VP8块装的是有损码流,VP8L块装的是无损码流。前三档全是VP8,最后一档变成了VP8L。滑块在最右边那一格换掉了整个编码器。

带透明的图,无损那一格还少了一个数据块

再看一组更有意思的。同样一张200×200的图,左半透明右半绿,两档画质各跑一次,把产物拆开:

  • 画质0.80:VP8X(10) ICCP(456) ALPH(28) VP8(194),共732字节
  • 画质1.00:VP8X(10) ICCP(456) VP8L(38),共540字节

注意0.80那行多出来的ALPH块。有损模式下WebP的颜色和透明度是分开存的:颜色走VP8,透明通道单独编码成一个ALPH块。无损模式的VP8L则自带透明通道,不需要额外的块。

结果就是这张带透明的图,画质拉满反而比0.80小了26%。少了一个数据块,少了一次分开编码的开销,图像数据本身也从194字节降到38字节。

这跟上一节线条图的结论是同一个方向,但成因多了一层——透明图不只受益于无损编码的规律性,还省掉了ALPH块这份额外开销。所以带透明的图标、UI元素、贴纸这几类素材,画质滑块的正确位置基本就是最右边。

这条得加个前提

这是浏览器的实现选择,不是规范规定的。MDN对toBlob的原话是,质量参数用于"支持有损压缩的文件格式(例如image/jpeg或image/webp)",至于给1.0会发生什么,规范一个字没说。我测的是Chrome,换个浏览器内核得重新验一遍。

顺带一提,同一张图输出JPEG、质量也给1.0,48万个通道值里只有6000个差了1——几乎无损,但体积从3.8 KB涨到14.1 KB,大了266%。JPEG没有无损模式可切,它只能在有损的路上把量化表调到最细,代价是体积失控。这就是为什么同一格滑块,两种格式的行为完全不同。

为什么线条图和照片,对同一个数值的反应完全相反?

知道了最右一格是无损,接下来的问题就有意思了:什么时候该用它。

我准备了四类素材,走同一条编码路径,把每种设置的字节数列成一张表。

四类素材的实测体积(单位:字节)

素材原始PNGPNG重编码WebP 0.8WebP 1.0JPEG 0.8
32×32纯色图标135135560520767
128×128两色logo26512651142213742344
400×300细条纹插画3648364811925229786
800×600噪点照片11436311143631125914825034128198

把这张表读三遍

第一遍看最后两列的对比。细条纹插画在画质1.0下是522字节,在0.8下是1192字节——无损比有损小了56%。这不是四舍五入的差别,是体积腰斩。

第二遍看最后一行。同样是这两档,噪点照片在1.0下是825 KB,在0.8下是126 KB——无损比有损大了6.5倍。方向完全掉了个个儿。

第三遍看这两行的关系。同一根滑块,同一个数值,在线条图上是"拉满最省",在照片上是"拉满最亏"。而工具的说明只写了一句"0.9以上体积下降有限",那句话只对最后一行成立。

中间那一档:logo为什么两边差不多

表格第二行容易被忽略:128×128的双色logo,画质0.8是1422字节,画质1.0是1374字节,两者只差3%。

这一档代表的是"介于两者之间"的素材——有平滑边缘(圆形的抗锯齿)、又有大片纯色。有损编码器在这类图上既发挥不出优势,也吃不了大亏。

遇到这种两档接近的情况,判断标准就该换一个:既然体积上没差别,那就选无损,因为它零损失。花一样的钱买没有损伤的版本,没有理由不选。反过来说,如果实测下来有损版本明显更小(比如小三成以上),那这张图大概率偏向照片属性,按照片的规矩办。

这也是我建议的通用做法:拿不准的图,同一张跑两遍,看数字说话。这个工具处理一张几百KB的图只要几十毫秒,跑两遍的成本可以忽略,比背任何经验法则都可靠。

背后的道理其实很朴素

有损编码的本事是丢掉人眼不敏感的高频信息,照片里这类信息多得是——渐变、噪点、毛发、树叶,丢掉一点看不出来。线条图恰恰相反,它整张图几乎全是高频(那些锐利的边),而且颜色种类极少。有损编码器一边费劲地在边缘附近编码它其实处理不好的高频,一边还在边缘留下色晕;无损编码器则可以靠"这一整片都是同一个颜色"的规律把它压得极扁。

web.dev那篇讲图片格式选择的文章给的判断句就是这个意思:需要保留最高精度的细节,就用PNG或者无损WebP;优化的是照片、截图这类素材,就用JPEG、有损WebP或者AVIF。这款工具把"无损WebP"这个选项藏在了滑块最右边,而且旁边的文案还劝你别去。

每张图里那456个字节,是谁塞进去的?

回到开头那个图标。520字节的WebP里,真正装图像的VP8L块只有17个字节,而ICCP块占了456个。

ICCP装的是ICC色彩配置文件,用来告诉解码方"这些RGB数值该按哪套色彩空间理解"。浏览器在canvas导出WebP和JPEG的时候会自动把当前的sRGB配置文件写进去,你没得选。

三种格式的固定开销不一样

我把32×32那张图的三种输出都按格式逐段解析了一遍:

  • WebP:VP8X(10) ICCP(456) VP8L(17),共520字节
  • JPEG:段里有个FFE2(APP2)长472字节,那也是ICC,全文件767字节
  • PNG:IHDR(13) IDAT(60) IDAT(6) IEND(0),共135字节,一个字节的ICC都没有

这就解释了开头那组反直觉的数字。不是WebP的压缩能力不行,是它先交了456字节的入场费,而这张图本身只值17个字节。入场费是它的27倍。

那这笔费用什么时候不算钱?

456字节是固定的,图越大越不值一提。128×128的logo一到WebP就从2651压到1422,赚了;800×600的照片从1.1 MB压到126 KB,456字节连零头都算不上。

所以判据很好记:产物预计小于5 KB的图,先算一下这456字节占多大比例;大于50 KB的图,当它不存在。中间那段自己跑一次对比,反正这工具跑一张图只要几十毫秒。

顺带说一句,这个坑跟站内那篇讲Favicon生成器给你10个图标文件的文章是同一类问题:小图上的固定开销,比例上会被放大到你意想不到的程度。做图标那一档资产的时候,几百字节真的要数着花。

选JPEG之前,得先知道透明会变成什么颜色

这一条是四类坑里唯一会把图彻底做废的。

实测:透明区变成纯黑

我做了一张200×200的图,左半边完全透明(alpha为0),右半边是绿色。选JPEG,画质0.92,跑一遍,再把产物的像素读回来:

  • 左上角:(0, 0, 0, 255)
  • 左边中间:(0, 0, 0, 255)
  • 左下角:(0, 0, 0, 255)
  • 右边中间:(34, 163, 73, 255)

透明的那半边整个变成了纯黑。而面板上显示的是"1.6 KB → 1.4 KB省13%",绿色的进度条,没有任何警告。

同一张图转WebP,作为对照

把格式换成WebP,其余不动:左边中间读回来是(0, 0, 0, 0),透明度完整保留,面板显示"省57%"。

一张图,两种格式,一个把它做废了还说省了13%,一个既保住了透明又省了57%。工具的说明里对这件事只有一句话:"它的短板是不支持透明通道。"这句话技术上没错,但它没说不支持的具体表现是把透明填成黑色。

什么时候会踩到

典型场景是这样的:你有一张带透明背景的产品图或者logo,因为要发给某个只收JPG的第三方平台,于是打开这个工具选了JPEG。导出的图在缩略图里看着还行(缩略图默认object-fit: cover,可能只显示中间那块),传上去才发现logo背在一块黑板上。

正确做法是:透明图要转JPEG,先自己在下面垫一层白底(或者你想要的背景色),再来压。这个工具不提供垫底功能,所以这一步得在别处做。如果目标平台其实收PNG或WebP,那就根本别转JPEG。

为什么在缩略图上看不出来

结果列表里每张图左边有个78像素见方的缩略图,用的是压缩后的产物,样式写的是等比裁切填满。也就是说,一张200×200的图在这个格子里只会显示中间那一块。

如果你的透明区域集中在四周(logo周围的留白、图标的圆角外侧),那么缩略图里显示的恰好是主体最完整、最不容易看出问题的那部分。真正变黑的边缘全在裁切掉的范围里。

这不是设计缺陷,缩略图本来就该这么做。但它意味着你不能靠列表里那个小方块验收结果,尤其是透明图、四周有重要内容的图、以及做了缩放的图。下载下来打开看,这一步省不掉。

"最大宽度"这个框,管不了你的长图

工具对这个控件的定位很高:使用说明里专门有一节叫"最大宽度为什么比画质更重要",讲得也很在理——体积和像素数大致成正比,把宽度从4000缩到1200,像素数少了将近九成。

问题是这个框只管宽。

一张600×4000的长图,填1200

信息长图、竖版海报、聊天记录截图,这类素材的共同点是窄而高。我造了一张600×4000的,填上最大宽度1200,跑:

输出原样是600×4000,一个像素没缩,面板报"省92%"。因为600本来就小于1200,缩放条件不成立。

作为对照,同一张图填300,输出300×2000,缩放逻辑本身完全正常。

所以对这类长图,"限制尺寸"这个最有效的手段直接失效了。它在移动端仍然是一个4000像素高的解码任务,占的解码内存跟宽度无关——解码内存按宽乘高乘每像素4字节算,600乘4000就是9.6 MB,缩不缩宽度都得先在内存里摊开这么一片。这件事在低端机和弱网环境下打开独立站时会被放大得很明显,内存紧张的机器上直接表现为白屏或者滚动卡顿。

而文案里写的是"宽高"

控件标签写的是"最大宽度(像素)",这是准确的。但页面的meta描述和结构化数据里,这项能力被描述成"可调质量、限制最大宽高"。

这不是抠字眼。搜索结果和AI摘要抓的往往就是meta描述那句话,用户带着"能限制高度"的预期点进来,会在界面上找一个不存在的输入框。这类文案与实现的错位,在JS压缩工具那几个被夸大的开关里也出现过,属于工具类页面的高发病。

那个输入框还接受一些它不该接受的值

输入框写着min="50" max="8000",看起来是有防护的。但这两个属性属于HTML的表单约束校验,只在表单提交或者显式调用校验接口时才生效。这个工具的按钮不是提交按钮,它直接读输入框的值往下算,于是这两个属性从头到尾只是给数字输入框的上下箭头限了个范围,你手打进去的值它一个都不拦。实测:

填的值面板显示实际产物
-3800×600 → -3×-2,省94%300×150的全透明空图
1.9800×600 → 1×1,省95%1×1
5800×600 → 5×4,省95%5×4
0不缩放800×600
abc不缩放800×600
99999不缩放800×600

最有意思的是第一行。面板上白纸黑字写着"-3×-2",产物却是300×150的一张全透明空图,中心像素读回来是(0,0,0,0),而它给这张空图的评价是"省94%",配绿色进度条。

300×150是从哪来的

这个数字不是随机的。WHATWG的HTML标准里写着:canvas的width属性默认是300,height属性默认是150。给canvas赋一个无效值(比如负数),它就回落到默认值。

所以整条链是这样的:代码算出宽-3高-2 → 面板照着这两个数显示 → canvas拒绝这个无效值、回落到300×150 → 空画布导出成一张全透明的图 → 体积确实小了94%。它告诉你的尺寸、它实际给你的尺寸、它对结果的评价,三件事互不相干。

填1.9那行也值得注意:parseInt把1.9截成1,于是你得到一张1×1的图,工具报"省95%"。手滑多打一个小数点,一张商品图就变成一个像素,而界面上还是绿色的。

有哪些东西它会照单全收,但结果不是你要的?

这一节讲两件事:一件是它不该收却收了,一件是它收了却悄悄弄丢了。

SVG会被静默栅格化

工具的提示写着"支持JPEG、PNG、WebP、GIF、BMP",没提SVG。但文件选择框的过滤条件是image/*,代码里的判断也是"MIME类型以image/开头",而SVG的MIME类型正是image/svg+xml。它进得来。

实测两种SVG:

  • 带width和height属性的300×200 SVG:177字节 → 1.7 KB,大了890%,输出300×200的位图
  • 只有viewBox、没有宽高属性的SVG:115字节 → 630字节,输出225×150

第二行那个225×150是哪来的?还是那个默认高度150在起作用:浏览器给没有内在尺寸的替换元素一个默认高度150,再按viewBox的3比2算出宽度225。一张本来可以任意缩放的矢量图,被固定成了一个跟你的设计稿毫无关系的位图尺寸。

而且这一步是净亏损。Google的图片文档里明确列出了它支持索引的格式:BMP、GIF、JPEG、PNG、WebP、SVG和AVIF——SVG本来就在名单里。把它栅格化,等于主动把一个更小、更清晰、搜索引擎也认的格式降级成位图。

解码失败的图会一声不吭地消失

我一次投了3个文件,第1个是伪造的、无法解码的PNG。压缩完,列表里只剩2行,统计卡显示"已处理2、原始总体积4.1 KB、整体节省67%"。

界面上没有任何地方告诉你有一张失败了,更没说是哪一张。你选3张出2张,如果不回头数一遍,根本不会发现。

批量处理时这一条更要命。拖50张进去,出来47张,界面上照样一片绿。用这个工具做批量的时候,处理完先看统计卡上的"已处理"数字对不对得上,这是唯一能发现丢图的地方。

顺便说,"整体节省67%"这个百分比只统计成功的那些,失败的图既不进分子也不进分母。所以这个数字永远好看。

丢一张图,代价不只是少一张图

批量压完直接上传的工作流里,丢图这件事的后果会往后传。文章里的图少了一张,页面上留下一个破图标记;商品详情页少了一张,主图轮播就短一格;更麻烦的是你已经在HTML里写好了引用路径,文件却不存在,服务器返回404。

而图片404对搜索引擎来说不是小事——抓取预算被浪费在拿不到的资源上,图片搜索里这张图直接消失。站内那篇讲图片SEO怎么落地的文章里提过,图片要进图片搜索,前提是它得能被抓到、有alt、文件名有意义,第一条就是能被抓到。

所以批量场景下,压完之后核对数量这一步别省。更稳妥的做法是分批处理,一次十来张,肉眼扫一遍列表比数字更快。

竖着拍的照片进去,会不会躺下来?

这是我原本最担心的一条,测完发现它做对了,而且做得挺干净。值得单独说,因为这个坑在服务端处理图片时几乎是必踩的。

手工造一张带方向标记的照片

手机竖着拍照时,传感器其实是横着记录的,然后在文件里写一个EXIF方向标记说"显示的时候请顺时针转90度"。不读这个标记的程序,就会把照片显示成躺倒的。

我造了一张400×200的JPEG(左半红、右半蓝、顶部一条白带),手工在文件头后面插了一段APP1的EXIF段,方向值设为6(顺时针90度),然后连同一张没有这个标记的对照版一起丢进工具。

结果

带标记的那张,输出200×400,把产物读回来:上部是红(227,29,73),下部是蓝(36,99,233),右侧一条竖白带(255,255,255)。完全符合顺时针转90度之后应有的样子。对照组输出400×200,横的。

原因在浏览器那一层:MDN对image-orientation属性的说明写着,它的初始值就是from-image,也就是"用图片里的EXIF信息把图片转到正确方向"。工具用img元素加载图片,拿到的宽高和画到画布上的像素都已经是转好的了。

一个说明书没提的好处

方向转好之后被烧进了像素,而EXIF元数据在重新编码时被清掉了。这意味着处理过的图在任何不读EXIF的环境里都是正的——老一点的图片查看器、某些后端缩略图脚本、一部分邮件客户端,全都不会再把它显示成躺倒的。

工具的说明里把"元数据会被清掉"列在"做不到什么"那一节,当成缺点写的。对归档原片来说确实是缺点,对发到网上的图来说,这一条加上方向烧录,其实是两个实打实的好处(顺便还把照片里的GPS位置一起清了)。

这几类图,分别该怎么设?

把前面所有实测收敛成能直接照做的设置。

照片:按说明书来就对了

风景、人像、产品实拍、任何有噪点和渐变的图,工具的默认建议完全适用:格式WebP,画质0.75到0.85,最大宽度按容器实际宽度填(正文图1200,封面1600,全屏背景1920)。这是唯一一类"照抄说明书"就能拿到最优解的素材。

线条图、图表、纯色插画:把画质拉到1.00

这类图的正确设置和说明书写的正好相反。实测那张细条纹插画,画质1.00是522字节,0.80是1192字节。拉满不但没变大,还小了一半,而且是零像素损失的一半。

判断标准很简单:这张图放大四倍看,边缘是干脆的还是糊的?干脆的就拉满。带文字的截图也归这一类——有损压缩会在文字边缘留色晕,那正是最影响可读性的地方。

图标、logo、任何小于5 KB的图:别用这个工具

直接留着原来的PNG。456字节的ICC开销在这个体量下是压倒性的,转任何格式都是亏。如果原图是没优化过的PNG,用做调色板量化的专业工具去压,那才是这一档该走的路——浏览器的PNG编码器不做量化,所以这个工具对PNG的输出永远是"省0%"(实测三张PNG进出体积一字不差)。

透明图:先决定要不要透明

要保留透明,格式只能选WebP或PNG。必须转JPEG的,先在别处垫一层背景色。别指望工具会提醒你——它只会平静地给你一张黑底图,并告诉你省了13%。

长图:这个框帮不了你

窄而高的图,最大宽度填多少都不生效。要控制高度只能在别的地方改尺寸,或者反过来利用这个特性:填一个比图片实际宽度更小的值,让它按比例整体缩,高度自然跟着降。600×4000填300,就能拿到300×2000。

先尺寸还是先画质?这个顺序也得看图

工具的说明给了一条很硬的顺序:先把尺寸限制到实际需要的大小,再调画质。理由是体积和像素数大致成正比,尺寸的降幅是任何画质参数都做不到的。

这条对照片成立,而且成立得很彻底。但对前面那两类图,顺序要调整。

图标和小logo本来就已经是它该有的尺寸了,没有可缩的空间,这一步直接跳过——真正的决策只有一个:要不要转格式(答案通常是不要)。线条图和图表则要反过来想:这类图缩小的代价比照片大得多,因为细线条一缩就会糊成灰色。一张原本1像素宽的分隔线,缩到六成就变成一条半透明的灰边,而这恰恰是这类图里承载信息的部分。

所以我的顺序是:先判断图的类型,再决定要不要缩、缩多少。照片按容器宽度缩到底;线条图宁可保留原尺寸靠无损编码省体积;图标一动不动。做电商站的话,商品主图和尺码表图往往正好分属这两类,别用一套参数一起跑,这一点在Shopify图片SEO从命名到压缩的清单里也是同一个道理。

批量作业:多看一眼那个数字

处理完先核对统计卡上的"已处理"和你投进去的张数是否一致。不一致就说明有图解码失败被静默丢掉了,而工具不会告诉你是哪几张。

动手试试:图片压缩与格式转换

拖图进去就能压,WebP、JPEG、PNG三种格式互转,画质滑块和最大宽度实时生效,每张图的体积变化和压缩率逐条列出来,变大的会用红色标出。全部在你自己的浏览器里跑,图片一个字节都不上传。

保哥自研免费在线工具,浏览器打开就能用。

→ 打开图片压缩与格式转换

常见问题解答

为什么我的图标转成WebP反而变大了?

因为浏览器在导出WebP和JPEG时会自动写入一个456字节左右的ICC色彩配置文件,这是固定开销。一张32×32纯色图标的实测数据是:PNG 135字节,WebP 520字节,其中真正的图像数据只有17个字节,剩下的全是配置文件和容器头。PNG输出不带ICC,所以小图上PNG才是体积最小的那个。产物预计小于5 KB的图,都要先算一下这笔开销占多大比例。

画质滑块拉到1.00是不是就无损了?

在Chrome上实测是的,但要分格式看。WebP在1.00时会切到无损编码器,把产物按容器格式拆开能看到数据块从VP8变成了VP8L,48万个通道值逐个比对零差异。JPEG没有无损模式,1.00只是把量化调到最细,实测仍有6000个通道值差1,而体积会暴涨266%。另外这是浏览器的实现选择,规范并没有规定质量参数给1必须无损,换浏览器内核要重新验。

线条图和图表到底该用什么设置?

格式选WebP,画质直接拉到1.00。实测一张400×300的细条纹插画,画质1.00是522字节,0.80是1192字节,无损版本比有损版本小了56%,而且零像素损失。原因是这类图颜色少、边缘锐利,无损编码器能靠大片同色的规律压得很扁,有损编码器反而要在边缘费劲还留色晕。带文字的截图同理。

带透明背景的图转JPEG会怎么样?

透明区域会变成纯黑,而且没有任何警告。实测一张左半透明右半绿的图转JPEG,透明那半边的像素读回来全是(0,0,0,255)纯黑,面板还显示"省13%"。同一张图转WebP则完整保留透明。要转JPEG必须先在图片下面垫一层背景色再压,这个工具不提供垫底功能。

为什么填了最大宽度,我的长图还是没缩小?

这个框只管宽度,不管高度。一张600×4000的长图填最大宽度1200,因为600本来就小于1200,缩放条件不成立,输出原样是600×4000。要让它缩,得填一个比图片实际宽度更小的值——同一张图填300就会输出300×2000。页面meta描述里写的"限制最大宽高"是文案与实现不符。

我选了5张图,为什么只出来4张?

有一张解码失败了,被静默跳过。工具在处理失败时只是跳到下一张,界面上不显示任何错误,也不告诉你是哪一张出的问题。唯一能发现的地方是统计卡上的"已处理"数字,跟你投进去的张数一对就知道。另外"整体节省"这个百分比只统计成功的那些,失败的图不进分子也不进分母。

竖着拍的手机照片进去会不会变横的?

不会。实测构造了一张带EXIF方向标记(值为6,顺时针90度)的JPEG,工具输出的尺寸和像素朝向都是转正之后的。原因是浏览器的image-orientation属性初始值就是from-image,img元素加载时已经按EXIF转好了。而且方向被烧进像素之后EXIF被清掉,处理过的图在任何不读EXIF的老程序里也是正的。

能把SVG丢进去压吗?

能丢进去,但不该丢。文件类型判断只看MIME是否以image/开头,SVG能通过。结果是矢量图被栅格化成位图:带宽高属性的300×200 SVG会从177字节涨到1.7 KB,只有viewBox没有宽高的SVG会输出成225×150这个跟设计稿无关的尺寸。而Google的图片文档里明确把SVG列在支持索引的格式清单中,栅格化是净亏损。

权威参考资料

分享到
标签
版权声明

本文标题:《图片压缩工具把135字节的图标压成了560字节,而画质拉满反倒更小》

本文链接:https://zhangwenbao.com/image-compressor-webp-lossless-icc-icon-size-guide.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交