图片丢进压缩或转换工具,下载下来的文件却比原图还大。多数时候这不是 bug:编码器只是按你选的格式去描述它拿到的像素,而这份描述有时就是比原来那份长。
简短回答: 以下几种情况文件会变大:新设置保留的信息比原文件多(压得很狠的 JPEG 用更高质量重新保存);有损照片转成无损格式(JPG 转 PNG);编码器丢掉了原文件用的技巧(调色板 PNG 被重新存成 32 位);图片太小,格式本身的开销反而占了大头;或者像素数量变多了。我们的测试里,一张 135 kB 的 JPEG 转成 PNG 后变成 2.21 MB,一个 504 字节的图标转成 WebP 后变成 1,104 字节。解决办法通常是保留原图、换一种格式,或者把质量调低;下面每一节都写明了该用哪一种。
九种情况一览
这里的每个数字都来自我们机器上的一次运行。大小均为精确字节数;正文中 1 kB 指 1,000 字节。
| 情况 | 输入 | 输出 | 变化 |
|---|---|---|---|
| 已优化的 JPEG 以质量 80 重新保存(浏览器编码器) | 135,151 | 168,059 | +24% |
| 同一张 JPEG 转成 PNG | 135,151 | 2,213,889 | 16.4x |
| 同一张 JPEG 以质量 90 转成 WebP | 135,151 | 212,204 | +57% |
| 照片 PNG 经浏览器 canvas 重新存为 PNG | 637,432 | 846,413 | +33% |
| 调色板 PNG logo 经浏览器 canvas 重新保存 | 45,525 | 170,429 | 3.7x |
| 截图 PNG 以质量 90 转成 JPG | 100,728 | 106,602 | +6% |
| 32 x 32 图标 PNG 以质量 90 转成 WebP | 504 | 1,104 | 2.2x |
| 320 x 480 的 JPEG 放大到 640 x 960 | 28,034 | 62,114 | 2.2x |
| 12 帧纯色块 GIF 转成 APNG | 5,519 | 5,758 | +4% |
我们是怎么测试的
所有测试于 2026-10-16(UTC)在一台 Apple M4 Mac 上完成,系统为 macOS 26.6.2。
- 浏览器编码器: 无头模式的 Google Chrome 155.0.8059.85。我们把 browser-image-compression 2.0.2(也就是我们的图片压缩工具所用的库)加载到一个空白本地页面里,用压缩工具的默认设置调用:质量 0.8、目标大小 1 MB、长边上限 1920 px、保持原格式、移除 EXIF、最多重试 30 轮。转换类测试用的是和我们转换页面相同的 canvas 调用:绘制图片,转 JPG 时在背后填充白色,然后以转换工具默认的 90% 质量调用
canvas.toBlob。我们没有在网站上逐个点击操作;代码路径一致,只是外面套的是测试页面。 - 其他编码器: Node v26.12.0 中的 sharp 0.35.5(libvips 8.18.7、mozjpeg、libwebp 1.6.0、libaom 3.15.1、libimagequant 2.4.1、libpng 1.6.58),以及 upng-js 2.1.0,即我们 GIF 转 APNG 工具调用的 PNG/APNG 编码器。
- 测试图片: Bonnie Moreland 拍摄的一张 CC0 风景照(Wikimedia Commons),取自我们之前一次基准测试中压缩工具的输出(1920 x 1280,250,382 字节),以及它用 mozjpeg 质量 70 重新编码的版本(135,151 字节);Kodak 测试图 kodim04(512 x 768 PNG,Kodak 发布、可不受限制地使用);我们自己 /compress 页面的截图(1440 x 900 PNG);Enzy Cell 制作的 CC0 图片 "NEW LOGO R"(Wikimedia Commons)及其调色板版本;我们为这次测试画的一个 32 x 32 图标和一个 12 帧 GIF;还有从 kodim04 裁出的一张 320 px 宽的缩略图。
每个数字都只跑了一次。浏览器的 PNG 编码器在不同运行之间输出的字节并不完全一致,所以你自己重复测试时,结果可能略有出入。ImgCompress.app 由我们开发,关于页面写明了网站由谁运营。文字初稿有 AI 助手参与,每个数字我们都对照原始输出文件核对过。
为什么 JPEG 再压缩一次反而变大?
因为“质量 80”并不代表固定的压缩量。它只是某一个编码器的设置项,换一个编码器,或者换一个质量数值,保留下来的细节多少都不一样。
我们那张 135 kB 的测试 JPEG 是用 mozjpeg 以质量 70 生成的,这个设置本来就偏向小体积。Chrome 自带的编码器以质量 80 重新保存后,得到 168 kB,大了 24%。浏览器先把 JPEG 解码成普通像素,连同 mozjpeg 留下的块状压缩噪点一起,然后用比原文件更精细的量化去编码这些像素。第一次压缩丢掉的东西不会回来;新文件只是花了更多字节去存同一张画面,外加旧的压缩痕迹。
同一张照片压缩得较轻的版本(250,382 字节)表现就不一样。Chrome 以质量 80 保存后是 250,670 字节,只多了 288 字节。用生成这个文件时的同一编码器和同一设置重新保存,结果几乎正好落在原始大小上。
我们的压缩工具怎么处理这种情况
我们的压缩工具会检查第一次的结果。在 browser-image-compression 里,如果输出比源文件大(或者超过目标大小),它会以上一次质量的 0.95 倍重新编码(PNG 为 0.85 倍),一直重复,直到文件同时低于这两个上限,或者重试轮数用完为止。这个循环里只有文件超过目标大小时才会缩小尺寸,所以小照片的像素尺寸不会变。
那张 250 kB 的文件多跑一轮、质量降到 0.76,变成 240,546 字节,小了 3.9%。那张 135 kB 的 mozjpeg 文件跑了七轮,质量一路降到 0.56,才变成 134,643 字节。也就是说,为了一个本来就压缩过的文件,把质量设置压低了一大截,只换来 508 字节。如果结果卡片上显示的节省只有几个百分点甚至更少,就保留原图吧。
如果结果还是没有变小、格式也没变,压缩工具会把原文件还给你,所以在同一格式下,它永远不会给你一个更大的文件。
关于质量数值的更多解释,见我们的 JPEG 压缩指南。
JPG 转成 PNG 后为什么大了这么多?
PNG 是无损格式,每个像素都原样存储。而一张解码后的 JPEG 照片里,有大量像素和邻近像素略有差异:胶片颗粒、传感器噪点,还有 JPEG 压缩留下的淡淡的 8 x 8 方块纹理。无损格式必须把这些全部保留。
| 源 JPEG | 转成 PNG(canvas) | 增长 |
|---|---|---|
| 250,382 字节 | 2,691,460 字节 | 10.7x |
| 135,151 字节 | 2,213,889 字节 | 16.4x |
在我们的测试里,JPEG 压得越狠,转 PNG 后涨得越多:起点文件更小,而 PNG 要存的像素数量一样多。转成 PNG 也不会修复 JPEG 已经造成的损伤。模糊和块状感都还在,只是现在以无损方式存了下来。
只有确实需要 PNG 时才做 JPG 转 PNG:比如编辑软件只认 PNG、要做一份会反复修改的母版,或者某个表单不收 JPG。如果目的是让文件变小,就继续用 JPG,或者改用 WebP、AVIF。
PNG 重新保存一次,为什么变大了?
在浏览器里,有两件事会和你对着干。
第一,Chrome 的 canvas PNG 编码器打包数据远不如原文件紧凑。把 kodim04 这张照片通过 canvas.toBlob 重新保存,637,432 字节变成了 846,413 字节,像素完全相同,体积却大了 33%。就算是认真做的无损重存,也不一定能赢:sharp 用 libpng 压缩级别 9 输出了 638,304 字节,比原文件还多 872 字节。
第二,canvas 里所有图片都以 32 位 RGBA 保存,Chrome 输出的也正是这种格式。调色板 PNG 则把每个像素存成一个小颜色表里的索引,TinyPNG、pngquant 这类工具就是靠这个把文件做小的。我们那个 logo 的调色板版本是 45,525 字节。画到 canvas 上再存一次,变成了 170,429 字节,大了 3.7 倍,因为颜色表没了,每个像素都要完整存储。
我们的压缩工具处理 PNG 时不直接用 canvas.toBlob。browser-image-compression 会把像素交给 UPNG,颜色上限是 4096 乘以质量,默认质量 0.8 时就是 3,276 色。同一次运行的结果:
| 图片 | 原始 | 压缩工具默认设置 | 变化 |
|---|---|---|---|
| kodim04.png(照片) | 637,432 | 542,951 | -15% |
| 截图 | 100,728 | 80,419 | -20% |
| Logo(全彩,带透明) | 152,010 | 113,515 | -25% |
| Logo(调色板) | 45,525 | 45,032 | -1% |
这一步会减少颜色,所以不是无损的:照片从 31,716 种不同颜色减到 3,277 种,截图从 2,002 种减到 1,314 种。已经优化过的调色板 PNG 基本没有压缩空间了,不管用哪个工具(包括我们的)再压一遍,大多是白费功夫。
截图应该存成 JPG 吗?
通常不应该。JPEG 是为平滑的照片细节设计的,而截图大多是纯色块,文字边缘又很锐利。Chrome 保存 JPG 时用了 4:2:0 色度子采样,也就是在水平和垂直方向上,颜色都只按亮度一半的分辨率存储;彩色文字和细彩色线条最先露出问题。在我们以质量 90 输出、放大 2 倍的局部图里,和 PNG 的差别很难看出来,但文件依然更大。
| 截图输出 | 字节 | 相比 100,728 字节的 PNG |
|---|---|---|
| JPG,质量 90(转换工具默认) | 106,602 | +6% |
| JPG,质量 80 | 82,331 | -18% |
| 经我们压缩工具处理的 PNG | 80,419 | -20% |
| WebP,质量 90(有损,canvas) | 59,638 | -41% |
| 无损 WebP(sharp) | 38,590 | -62% |
| 调色板 PNG(libimagequant,质量 80) | 30,544 | -70% |
如果网站非要 JPG,在我们的测试里,PNG 转 JPG 用 80% 质量时能比 PNG 小,90% 则不行。能用 WebP 的地方,截图换成 PNG 转 WebP 更合适。调色板 PNG 的文件最小,而我们不提供 256 色调色板模式,所以想再省下最后那 50 kB,可以用 pngquant 或 Squoosh 这类工具。这两种格式各自的取舍,见 WebP 和 PNG 怎么选。
WebP 或 AVIF 为什么比原图还大?
原因有两个,分别出现在两组不同的测试里。
用高质量转换已经压缩过的 JPEG
在画质看起来相同的前提下,WebP 和 AVIF 往往比 JPEG 小。但这个比较的前提是源图干净。从 JPEG 出发时,新编码器得把 JPEG 的压缩痕迹当成细节一起还原出来。
| 从 135,151 字节的 JPEG 转换 | 字节 | 变化 |
|---|---|---|
| WebP,质量 90(canvas,转换工具默认) | 212,204 | +57% |
| WebP,质量 75(sharp) | 109,124 | -19% |
| AVIF,质量 50(sharp) | 93,940 | -30% |
那张 250 kB 的 JPEG 以质量 90 转成 WebP,从 250,382 字节变成 269,556 字节,大了 7.7%。质量数值比格式本身影响更大。用 JPG 转 WebP 时,把滑块从默认的 90% 往下调,再比较文件大小;也可以试试 JPG 转 AVIF。AVIF 对细腻纹理有什么影响,见我们的 AVIF 格式详解。
小图片和固定开销
每种格式都有固定成本,比如文件头;有损 WebP 如果带透明,还要单独存一份 Alpha 通道。整张图只有 504 字节时,这些开销就显得很重。
| 504 字节的调色板 PNG 图标转成 | 字节 |
|---|---|
| 无损 WebP(sharp) | 364 |
| WebP 质量 75(sharp) | 436 |
| AVIF 质量 50(sharp) | 667 |
| canvas 重新保存的 PNG | 833 |
| WebP 质量 90(canvas) | 1,104 |
| 无损 AVIF(sharp) | 1,089 |
| JPG 质量 90(canvas) | 1,367 |
无损 WebP 确实比 PNG 小了 140 字节,但大多数选项都让图标变大了,两种 AVIF 设置都是如此。图标和小型界面图形就保留 PNG;如果手上有矢量源文件,用 SVG。在我们的测试里,WebP 和 AVIF 在照片上省下了字节,在图标上没有。
放大尺寸或保留元数据会增加体积吗?
放大会增加字节,却不会增加细节。我们那张 320 x 480 的缩略图是 28,034 字节。按原尺寸以质量 80 重新保存是 28,513 字节;先放大到 640 x 960 再保存,就成了 62,114 字节,大了 2.2 倍,画面反而更糊。我们的压缩工具从不放大图片,因为 1920 px 那个设置是上限。调整尺寸工具则不一样,你填了更大的数字它就会放大,所以导出前先在图片尺寸调整工具里确认一下目标尺寸。为什么放大找不回细节,见调整图片尺寸而不损失画质。
在我们的测试里,元数据的影响不大。这张缩略图带了一个 480 字节的 Display P3 颜色配置文件和 258 字节的 EXIF 标签,约占 28,290 字节总大小的 2.6%。我们的压缩工具默认移除 EXIF,只有打开“保留 EXIF”时才会保留。相机拍出的文件可能带更大的数据块,比如内嵌的预览图,所以相机或手机导出的小图,移除 EXIF 的效果可能更明显。它还会顺带去掉 GPS 位置信息。
GIF 转换后会怎样?
GIF 是老格式,但对于颜色不多、色块平整的短动画,它很紧凑:它存的是调色板索引,而且每帧可以只存变化的那一部分。我们画了一个 12 帧、240 x 240 的动画,内容是一个圆点在纯色背景上移动:
| 输出 | 字节 | 相比 5,519 字节的 GIF |
|---|---|---|
| APNG,无损(UPNG,和我们的 GIF 转 APNG 工具相同) | 5,758 | +4% |
| 动画 WebP,无损(sharp) | 5,426 | -2% |
| 动画 WebP,质量 75(sharp) | 5,750 | +4% |
这几种格式的大小都没怎么变。这个结果只适用于小型纯色块动画;我们没有测试画面是照片的长 GIF,那种情况下 256 色限制和抖动会让 GIF 吃更多亏。对于纯色块短动画,保留 GIF 是合理的选择;如果需要再小一点,可以先用 GIF 压缩工具试试。
结果变大时,我们的工具会怎么做
上面所有处理都在你的浏览器里完成;在我们的网站上,图片不会被上传。输出变大时,各个工具的做法如下:
- 压缩工具,保持原格式: 只要文件比源文件大,就降低质量重试;如果最后还是没有变小,就把原文件还给你。
- 压缩工具,更换了格式: 即使文件变大,你拿到的也是转换后的文件。结果卡片会同时列出两个大小,只有文件变小时才显示百分比,所以要自己比较这两个数字。
- 转换工具: 按滑块的值编码一次(有损输出默认 90%),不检查大小。转换的目的是换格式,所以体积可能变大,也可能变小。
- 目标大小: 只要文件超过你设定的目标,每一轮都会降低质量,并且在没有打开“保持原始分辨率”时,把宽和高各缩小 5%。30 轮后停止;如果没能达到目标,卡片上会标出来。
再压缩或转换之前,先过一遍这份清单
- 文件是不是已经优化过了? 如果它来自 CDN、CMS 或 TinyPNG 这类工具,再压一遍通常省不了多少;我们的测试里分别只省了 3.9% 和 0.4%。收益这么小时,保留原图。
- 是不是要把照片转成 PNG? 只有必须用 PNG 时才这么做。我们的两张 JPEG 分别涨了 10.7 倍和 16.4 倍。
- 是截图还是纯色块图形? 保留 PNG 或改用 WebP。在我们的测试里,90% 质量的 JPG 比 PNG 还大。
- 文件是不是只有几 kB? 图标就保留 PNG 或 SVG。WebP 和 AVIF 的文件头可能比像素数据还重。
- 像素尺寸是不是变大了? 保存前先确认输出尺寸。放大让我们那张缩略图的字节数翻了一倍。
- 转换工具是不是还在 90%? JPG 转 WebP 时,试试 75% 到 80%,再比较大小。
- 元数据还需要吗? 公开发布的小图去掉 EXIF;要归档的照片保留它。
如果你只想在同一格式下让文件变小,就从压缩工具开始,下载前先在结果卡片上对比压缩前后的大小。

