PNG转JPG

把带透明通道的 PNG 转成 JPEG:先指定白、黑或自定义背景色把 alpha 合成掉,再按 0.30~1.00 的质量导出,转换前后体积与压缩比实时显示。整个过程在你的浏览器里用 canvas 完成,没有上传。

未选择图片,下面是默认参数(质量 0.92、白色底)下对基准图 1920×1080 的估算:约 371.1 KiB。
原始尺寸1920×1080(演示值)
原始 PNG 体积2.60 MiB
预期 JPEG 体积371.1 KiB
体积比7.16×(演示值)

转换结果会显示在这里。上面这组数字是基准图 1920×1080 的演示值,选出你自己的图片后会换成实测值。

提示:宽度、质量这些输入框里按 Enter 可以直接重新估算;图片只在本地解码,关闭标签页后不留副本。

使用方法

  1. 点「1. 选择本地 PNG 图片」挑一张图。PNG、JPEG、WebP、GIF、BMP 都能读进来,但只有带 alpha 通道的 PNG 才会真正用到背景填充这一步。
  2. 载入后结果区会显示原始尺寸与原始 PNG 体积,两个值都来自文件本身,不做任何估算。
  3. 在「2. 透明背景填充色」里选白、黑或自定义。这一步不是可选项:JPEG 格式本身没有 alpha 通道,不指定底色,透明区域在多数内核上会直接变成黑色。
  4. 选了「自定义颜色」时,「3. 自定义颜色」里按 #RRGGBB 写六位十六进制,默认 #f5f5f5。写错格式会被拦下来并告诉你哪里不对。
  5. 拖动「4. JPEG 质量」滑块,范围 0.30~1.00,默认 0.92。松手后大约四分之一秒,结果区就会给出这一档质量下的实际体积。
  6. 点「转换并下载 JPEG」,浏览器在本地编码后直接触发下载,文件名形如 converted-1920x1080-q92.jpg。

PNG转JPG 这个工具能解决什么问题

一是上传口只收 JPG。很多后台、报名系统、电商平台的图片入口只允许 JPG,PNG 会被直接拒绝。这类入口通常还限体积,所以转换时顺手把质量调到合适档位,比先转后压少走一步。

二是把透明底铺成固定底色。设计稿里的 Logo、图标、水印常常是透明背景的 PNG,一旦贴到白色商品页或黑色活动页上,如果底色没管,透明区就会变成黑块。这个 PNG转JPG 工具把底色当成必填项,先把 alpha 合成掉再编码。

三是估算体积再决定要不要转。JPEG 是有损格式,同尺寸下体积通常只有 PNG 的几分之一到十几分之一,但具体省多少完全取决于画面内容。本页在编码前后都给你看真实字节数,而不是让你转完才发现体积没降。

四是给带半透明的素材做定稿。阴影、渐变蒙版这种半透明像素,转 JPEG 时必须按 out = src×a + bg×(1−a) 逐通道混合。本页直接把公式写进流程,输出的就是合成后的 24 位真彩。

原理:PNG 的无损 DEFLATE 与 JPEG 的有损 DCT

PNG 走的是无损路线。它由 W3C 在 ISO/IEC 15948 里定义,文件开头固定是 8 字节签名 89 50 4E 47 0D 0A 1A 0A,后面跟 IHDR、IDAT、IEND 等数据块。像素先经过行滤波,规范一共定义了 5 种滤波类型:None、Sub、Up、Average、Paeth,编码器逐行挑「滤波后字节绝对值之和最小」的那一种,再交给 DEFLATE(RFC 1951,装在 zlib 容器里就是 RFC 1950)压缩。因为全过程只做可逆变换,解出来的像素和原图逐位相同。

PNG 的色彩类型有 5 种、位深有 5 档。色彩类型分别是 0 灰度、2 真彩 RGB、3 索引调色板、4 灰度加 alpha、6 真彩加 alpha;位深可以是 1、2、4、8、16。于是同一张 1920×1080 的图,光未压缩扫描线就能差出三十倍:1 位索引色是 (1920÷8+1)×1080 = 260,280 字节,32 位真彩 RGBA 是 (1920×4+1)×1080 = 8,295,480 字节,后者是前者的 31.87 倍。

JPEG 走的是有损路线。基线流程由 ITU-T T.81(等价于 ISO/IEC 10918-1)规定:先把 RGB 转成 YCbCr,色度按 4:2:0 抽样,再把画面切成 8×8 的小块做二维 DCT-II 变换。1920×1080 一共是 240×135 = 32,400 个亮度块,加上两张色度图各 120×68 = 8,160 块,合计 48,720 块、每块 64 个系数。系数随后被锚定在标准量化表(Annex K)上取整,这一「除以量化步长再四舍五入」的动作就是画质损失的来源,之后才是 zigzag 扫描 + 差分 DC + 游程编码 + Huffman 熵编码。

质量参数改的是量化表,不是编码器开关。常见换算里,quality 先取整成百分数 Q,再算缩放系数 scale = Q < 50 ? 5000÷Q : 200 − 2×Q,最后 Q′ = clamp(floor((基准值×scale + 50) ÷ 100), 1, 255)。本页默认的 0.92 对应 scale = 16:亮度 DC 基准值 16 被压到 3,低频 AC 基准值 11 压到 2,最高频那格基准值 99 压到 16。质量填 1.00 时 scale = 0,整张量化表都被夹到 1——看似「不量化」了,但 DCT 系数本身要取整、像素也要落回 8 位整数,损失照样存在,所以 JPEG 没有无损档。

alpha 通道是这一步最硬的技术差异。JPEG 没有 alpha 平面,只有 24 位真彩,画布上的半透明像素必须提前压平。画布的合成规则是 premultiplied alpha,一个完全透明像素的 RGB 分量是 0,也就是黑;导出 JPEG 时如果没先铺底色,多数内核会把这个 0 原样写进去,于是透明区变黑。正确做法是先 fillRect 一层底色再 drawImage,按 out = src×a + bg×(1−a) 逐通道混合:全透明像素 a=0 在白底上得到 255、在黑底上得到 0;半透明像素取 src=0、a=128/255 时,白底得到 127 的灰、黑底仍是 0。另一个后果是位宽统一:不管源 PNG 原本是 1 位索引还是 64 位真彩,转成 JPEG 之后一律是每像素 24 位,1920×1080 的扫描线恒为 6,221,880 字节。

导出接口要在同步和异步之间选。toDataURL() 是同步的,它会把二进制按 base64 编码成文本,体积膨胀 33.33%:一张 500,000 字节的 JPEG 会变成 666,668 个字符,大图足以让页面卡住。本页用异步的 toBlob(callback, 'image/jpeg', quality),直接把 Blob 交回来,既没有 base64 膨胀,也不会长时间占住主线程。

完整示例(数值仅作演示)

页面打开时的默认条件是:质量 0.92、背景色 白色 #FFFFFF、尺寸不变(1920×1080)。下面这组数字来自一张 1920×1080 的合成基准照片,PNG 侧是真实行滤波加 DEFLATE 压缩后的字节数,JPEG 侧是真实 DCT + 量化 + 熵编码算出的字节数。

  • 基准 PNG 合计 2,720,340 字节 ≈ 2.60 MiB,其中 IDAT 数据块本身 2,720,283 字节;
  • 同一张图转成 JPEG、质量 0.92,约 379,959 字节 ≈ 371.1 KiB,体积比 7.16×,也就是只剩原来的 14.0%;
  • 把质量顶到 1.00,JPEG 涨到约 602,737 字节,仍然是 PNG 的 4.51 分之一,说明「JPEG 省体积」这件事和质量档位无关;
  • 一张 1 位索引色的 1920×1080 PNG,扫描线只有 260,280 字节;转成 JPEG 后扫描线变成 6,221,880 字节,反向膨胀 23.90 倍;
  • 带透明的图:全透明像素在黑底下得到 0、白底下得到 255;
  • 半透明像素 src=0、a=128/255 在白底下得到 127,说明底色不只影响透明区,也影响半透明区的最终颜色。

再看一个边界例子:源图如果是 7680×4320 的 32 位真彩 RGBA PNG,像素数 33,177,600,虽然没超过 canvas 单边上限 65535,但导入导出都要占掉一百多 MiB 内存,这类图建议先用尺寸调整工具缩小再转。

输入范围、位宽与扫描线对照表

下表把 PNG 各种色彩类型换算成「未压缩扫描线」字节数,再对照转成 JPEG 之后的固定 24 位扫描线。扫描线的算法都是 (宽度×每像素位数÷8 + 1)×高度,末尾那个 +1 是规范要求的每行 1 字节滤波类型标记。倒数第二列越大,说明这一趟转换把像素数据撑得越开。

源 PNG 类型(1920×1080)每像素位宽扫描线字节数转 JPEG 后(24 位)比值
1 位索引(≤2 色)1260,280 B6,221,880 B23.90×
2 位索引(≤4 色)2519,480 B6,221,880 B11.98×
4 位索引(≤16 色)41,037,880 B6,221,880 B5.99×
8 位索引(≤256 色)82,074,680 B6,221,880 B3.00×
8 位灰度82,074,680 B6,221,880 B3.00×
8 位灰度+alpha164,148,280 B6,221,880 B1.50×
16 位灰度164,148,280 B6,221,880 B1.50×
16 位灰度+alpha328,295,480 B6,221,880 B0.75×
8 位真彩 RGB246,221,880 B6,221,880 B1.00×
8 位真彩 RGBA328,295,480 B6,221,880 B0.75×
16 位真彩 RGB4812,442,680 B6,221,880 B0.50×
16 位真彩 RGBA6416,589,880 B6,221,880 B0.38×

点「加载更多行」会补上换分辨率的几行,点「导出 CSV」把当前可见的整张表存成带 BOM 的 CSV(Excel 打开不乱码),点「复制对照表」复制成制表符分隔的文本,可以直接粘进表格软件。

边界与精度说明

  • 尺寸上限是硬约束。canvas 单边最大 65535 像素,总面积上限 2 的 28 次方 = 268,435,456 像素(约 16384×16384)。越界时浏览器不抛异常,只会给一张空白图,所以本页在选图后先做面积校验再编码。
  • 质量只接受 0.30~1.00。HTML 规范里写明,传给 toBlob 的 quality 只要不在 0.0~1.0 之间,就按默认值 0.92 处理。也就是说填 0 和填 1.5 都会静默变成 0.92,本页因此直接拦下并说明原因,而不是让你以为参数生效了。
  • 质量的物理分辨率是 0.01。编码器把 quality 取整成百分数档位,0.8195 和 0.8223 都会落到同一档 Q=82,量化表完全相同、输出字节数一模一样。滑块步长设 0.01 已经覆盖全部可用档位。
  • 16 位与 48 位源会被降到 8 位。JPEG 基线只支持 8 位样本,PNG 的 16 位灰度、48 位真彩进了 canvas 就按 8 位处理,色调层次会减少,位深越高这一步的信息损失越明显。
  • 色度会被 4:2:0 抽样。Chromium 系导出 JPEG 默认把 Cb、Cr 各缩到一半宽高,色度原始数据因此只有亮度的四分之一,一张 1920×1080 的图原始总量是 Y 的 2,073,600 加两张色度各 518,400,合计 3,110,400 字节、合每像素 1.5 字节。色块边缘、细红线这类高频色差会有可见损失。
  • 输出不含 EXIF。canvas 输出的是纯像素位图,相机的型号、镜头、光圈、快门、拍摄时间、GPS 都不会带过去,原图的方向标记也一并消失(方向已经在解码阶段被应用,画面本身是正的)。
  • 本页只换格式,不改尺寸。输出像素与原图一致;想要边转边缩,请配合尺寸调整工具先改像素再回来转换。
  • 颜色按 sRGB 解释。原 PNG 若带 Display P3 等宽色域标记,转换后按 sRGB 解释会显得略淡,需要专业色彩流程请用桌面软件处理。

常见问题

转完透明背景为什么变黑了?

因为 JPEG 没有 alpha 通道,而 canvas 的透明像素是 premultiplied 存储的:a=0 的位置 RGB 分量就是 0,也就是黑。导出时若没有先铺底色,这个 0 会被原样写进 JPEG。正确做法是先 fillRect 一层底色再画图,本页把背景色做成必填项,白底、黑底或自定义都可以,全透明像素在白底上会得到 255、黑底上得到 0。

质量填 1.00 是不是就是无损?

不是。质量 1.00 时缩放系数算出来是 0,整张量化表被夹到最小值 1,但 8×8 DCT 的系数仍然要四舍五入成整数,像素也要落回 8 位,这两步都是不可逆的。实测同一张 1920×1080 基准图,质量 1.00 的 JPEG 约 602,737 字节,仍然只有 PNG 的 4.51 分之一——体积差距本身就是有损的证据。要无损请留在 PNG 或改用 WebP 的无损模式。

图片会上传到服务器吗?

不会。文件通过 File 对象在本地解码,底色合成和 JPEG 编码都在你的浏览器里用 canvas 完成,导出走 toBlob。想自己确认,打开开发者工具的网络面板,选一张 PNG 再点转换,全程不会有任何新请求。

为什么有的图转完体积反而变大了?

两种情况最常见。一是源图本来就是 1 位或 4 位索引色的小图标,扫描线只有 260,280 字节,转成 24 位 JPEG 后扫描线变成 6,221,880 字节,涨了 23.90 倍,压缩比再高也追不回来;二是源图色块极大、颜色极少(比如纯色截图或线框图),PNG 的 DEFLATE 能把它们压到几十字节,而 JPEG 的 Huffman 编码对这类画面效率很差。遇到这种情况建议保留 PNG,或者改用无损 WebP。

能一次转换多张吗?

不能。这个 PNG转JPG 工具刻意做成一次一张:编码是 CPU 密集操作,而且每张图合适的质量档位并不相同,批量套用同一档质量很容易把一部分图压坏。多张素材的批处理建议用桌面端软件。

转换后画质会差多少?

取决于内容和质量档位。质量 0.92 时压缩比通常还在高位、肉眼几乎看不出差别;0.85 以下的差异才开始出现在细纹理和渐变上。判断标准是看你最终怎么用:只在屏幕上看、尺寸不超过原图,0.80~0.92 都够用;要放大、要印刷,就尽量留在 0.92 以上,或者干脆别转。

为什么转换后拍摄信息都没了?

因为 canvas 输出的是纯像素位图,不带任何元数据。EXIF 里的相机型号、镜头、光圈、快门、ISO、拍摄时间和 GPS 坐标都不会写进 JPEG,PNG 原有的色彩配置标记也不会保留。对在意隐私的人是好事,对需要归档拍摄参数的人是损失。

半透明的阴影转出来灰蒙蒙的,正常吗?

正常,这是合成公式的必然结果。半透明像素按 out = src×a + bg×(1−a) 与底色混合,阴影本身是半透明黑色,铺在深色底上会比铺在白底上更暗、更接近底色。想让阴影保持设计稿的样子,就把背景色选成设计稿用的那个底色,而不是一律用白色。

相关工具