普通图片中的每个像素都由三个数字描述:它包含多少红、绿、蓝。这足以说明像素是什么颜色,却说明不了能否透过它看到后面的东西。alpha 通道就是每个像素的第四个数字,专门做这件事:它存储不透明度,范围从完全透明到完全不透明。
人们说“透明背景的 PNG”,指的是带有 alpha 通道、且背景像素的 alpha 为零的图片。本指南解释这个数字如何起作用、软件存储它的两种方式、边缘为什么会出问题,以及如何检查文件里到底有什么。
RGBA:每个像素四个通道
MDN 对 alpha 通道的定义很简单:颜色由通道(红、绿、蓝)组成,要描述一种“在一定程度上可以透过它看到背景”的颜色,就要加上第四个通道。四个通道都有的图片称为 RGBA。
这个值有几种写法,含义都一样:
| 表示法 | 完全透明 | 半透明 | 完全不透明 |
|---|---|---|---|
| 8 位整数(大多数图片文件) | 0 | 128 | 255 |
| 16 位整数(16 位 PNG) | 0 | 32768 | 65535 |
| 小数(合成运算、CSS) | 0 | 0.5 | 1 |
| 百分比(CSS) | 0% | 50% | 100% |
十六进制后缀(CSS #rrggbbaa) | 00 | 80 | ff |
PNG 规范说得很精确:alpha 值为零表示完全透明,该位深的最大值表示完全不透明,中间值则是“可以与背景图像合成”的半透明像素。
这些中间值才是关键。好的抠图不只是“主体不透明、背景透明”。边缘上的像素,尤其是头发、毛发、织物、玻璃和运动模糊处的像素,是部分透明的,正是它们让主体放在新背景上看起来自然,而不像是用剪刀剪下来的。
透明像素是怎样绘制的
当应用把你的图片叠放在其他内容上时,会把每个像素和它后面的内容混合。W3C 的合成与混合规范给出了基本公式:
result = Cs x as + Cb x ab x (1 - as)
Cs, as = color and alpha of your image (the source)
Cb, ab = color and alpha of what is behind it (the backdrop)在背景不透明这种常见情况下,它就变成一个加权平均。一个 alpha 为 0.3 的像素贡献 30% 自己的颜色,让 70% 的背景透过来。
直通 alpha 与预乘 alpha
存储半透明像素的颜色有两种方式,把它们搞混是出现深色或亮色边缘的典型原因。
直通 alpha(也叫非关联或非预乘 alpha)按像素完全不透明时的样子存储颜色,并单独保存不透明度。一个半透明的纯红像素存储为红 255、绿 0、蓝 0、alpha 128。
预乘 alpha(也叫关联 alpha)存储的是已经乘以 alpha 的颜色。同一个像素存储为红 128、绿 0、蓝 0、alpha 128。用 PNG 规范的话说,这样的图像“已经与黑色背景合成过了”。
文件用哪一种,取决于格式和软件:
- PNG 始终使用直通 alpha。规范明确这样规定,并指出这让编辑器可以轻松修改图像的透明度。
- 图形管线、游戏引擎和视频合成工具内部通常使用预乘 alpha,因为混合运算更简单,滤波效果也更好。
当一个程序写入预乘值、另一个程序却按直通值读取时,问题就来了。边缘的颜色会过暗,形成一圈细细的黑边。反过来则会让边缘过亮。如果某个工具输出的每张抠图都有一致的深色边缘,首先要怀疑的就是预乘不匹配。
抠图为什么会有光晕
光晕是主体周围一圈本不属于它的可见边缘。常见原因有四种,各有各的解决办法。
1. 旧背景渗进了边缘像素
相机永远拍不出干净的边界。一缕头发衬着绿色树篱,产生的像素一部分是头发、一部分是树篱。如果抠图保留这些像素的原始颜色、只是让它们变成半透明,绿色就会一直混在里面。放到白色背景上,主体就带着一圈淡淡的绿光。
解决办法是颜色净化:为每个边缘像素估算真实的前景色,然后写入这个颜色。Photoshop 在“选择并遮住”工作区中把它叫作“净化颜色”,开源的 rembg 库有一个 decontaminate 选项,作用相同。它只改变边缘颜色,从不改变蒙版的形状。
2. 蒙版太硬
如果蒙版只有完全不透明和完全透明的像素,边缘就会出现锯齿,原照片中的抗锯齿还会在主体周围留下一像素宽的背景色线条。头发这类柔和的主体需要带有真实中间值的柔和蒙版。
3. 透明像素中隐藏的颜色
在直通 alpha 文件中,alpha 为零的像素仍然有红、绿、蓝值。你看不见它们,但缩放或模糊图片时会混合相邻像素,如果这些隐藏的颜色是白色或黑色,就会渗进可见的边缘。好的图像库会在缩放前先预乘、缩放后再转换回来,以避免这个问题。
4. 图片被合并到了某种颜色上
GIF 和调色板 PNG 通常只支持“开或关”的透明,所以工具在保存前会把边缘对着一种杂边色(通常是白色)做抗锯齿。这样的图片放在白色上看起来没问题,放在任何更深的颜色上都会显出白边。如果你的抠图要放在深色背景上,请用完整的 alpha 导出。
蒙版、遮罩和 alpha:术语解释
这些词含义有重叠,用法也比较随意。它们通常的意思如下:
- alpha 通道: 存储在图片文件内部的不透明度值,每个像素一个。
- 蒙版: 一张灰度图,控制另一张图的哪些部分可见。在 Photoshop 的图层蒙版中,白色显示、黑色隐藏,灰色部分可见。蒙版可以在不动原始像素的情况下编辑,所以专业人士用蒙版而不是橡皮擦来去除背景。
- 遮罩(matte): 电影和合成领域对同一概念的称呼,即定义保留内容的灰度图。“抠像”(matting)指的是为头发这类难处理的边缘计算出柔和、准确的遮罩。
- 三分图(trimap): 一张粗略的三区域图(确定是前景、确定是背景、不确定),一些抠像算法以它为起点。
- 二值蒙版或硬蒙版: 只有黑白、没有灰色。适合方块和 logo,不适合头发。
- 抠图: 最终结果,即主体的颜色加上 alpha 通道。
蒙版和 alpha 通道承载的是相同的信息。很多工具两种都能导出:一种是内置 alpha 的透明 PNG,另一种是单独的黑白蒙版图,你可以在编辑器或视频工具中自己应用。
哪些格式能存储 alpha
| 格式 | alpha 支持 |
|---|---|
| PNG | 完整 alpha(8 位或 16 位),或单一透明调色板颜色 |
| WebP | 完整 alpha,无损和有损模式都支持 |
| AVIF | 完整 alpha |
| GIF | 只有开或关:把一种调色板颜色标记为透明 |
| JPEG | 不支持 |
这些格式的完整对比,请参阅 PNG、JPEG 与 WebP 对比。
如何检查图片是否有透明
文件以 .png 结尾并不能证明它是透明的。很多 PNG 是完全不透明的,网上找到的一些“透明”图片其实是把灰白棋盘格画进像素里的 JPEG。下面是可靠的检查方法。
用肉眼
把图片分别放在深色和浅色背景上,例如放进幻灯片或设计工具。真正的抠图在两种情况下都会在主体周围显示出背景色。如果仍然看到棋盘格,它就是图片的一部分,而不是透明。
用 ImageMagick
# Does the file have an alpha channel at all?
identify -format "%A\n" photo.png
# Is it fully opaque anyway? (true means no visible transparency)
identify -format "%[opaque]\n" photo.png%A 报告透明通道(打印出的具体字样在 ImageMagick 6 和 7 之间有所不同),%[opaque] 会计算是否每个像素都完全不透明。你希望看到的是有 alpha 通道,并且结果为 false。
用 Python 和 Pillow
from PIL import Image
im = Image.open("photo.png")
print(im.mode) # RGBA or LA means an alpha channel
print(im.has_transparency_data) # True if the file carries any transparency info
if "A" in im.getbands():
lo, hi = im.getchannel("A").getextrema()
print("alpha range:", lo, hi) # lo == 255 means nothing is transparent极值检查能发现一种常见情况:RGBA 文件中的每个像素其实都是不透明的。
平台忽略 alpha 时
有些地方会去掉或忽略透明。Etsy 表示不支持透明 PNG,透明区域可能显示为黑色,而 Amazon 和 Walmart 等电商平台本来就要求主图使用纯白背景。在这些情况下,请自己把抠图合并到背景色上,这样结果由你掌控。在你自己的网站、幻灯片和设计工具中,保留 alpha。
快速获得干净的 alpha 通道
如果你需要的是边缘柔和的抠图而不是硬蒙版,removebackground.dev 会生成带完整 alpha 通道的透明 PNG 或 WebP 文件,它的 API 还可以单独返回灰度蒙版。
常见问题
RGBA 是什么意思?
红、绿、蓝和 alpha。前三个描述像素的颜色,第四个描述它的不透明度,从 0(完全透明)到最大值(8 位图像中为 255)表示完全不透明。
直通 alpha 和预乘 alpha 有什么区别?
直通 alpha 把像素的完整颜色和不透明度分开存储。预乘 alpha 存储的是已经乘以不透明度的颜色,就像已经和黑色背景合成过一样。PNG 始终使用直通 alpha;很多渲染和视频工具内部使用预乘 alpha。
为什么我的抠图有一圈白色或彩色轮廓?
通常是旧背景仍然混在边缘像素里,或者图片在保存前对着白色做了抗锯齿。净化边缘颜色、使用柔和蒙版,并用完整 alpha 而不是杂边色导出,可以解决大多数情况。
蒙版和 alpha 通道是一回事吗?
它们承载相同的信息:每个像素一个灰度值,表示它有多可见。alpha 通道存储在图片文件内部;蒙版通常是一张单独的灰度图,或编辑器中的图层蒙版。
怎么知道一张 PNG 是否真的透明?
把它分别放在深色和浅色背景上,看背景是否透出来。也可以用 ImageMagick 的 identify 配合 %[opaque],或在 Pillow 中检查 alpha 通道的最小值;最小值为 255 表示没有任何透明部分。
用你自己的图片试试
新账户可获得 50 个免费额度。每张图片 1 个额度,无需订阅,额度永不过期。
去除背景资料来源
- MDN: Alpha (alpha channel) glossary entry
- W3C: Portable Network Graphics (PNG) Specification (Third Edition)
- W3C: Compositing and Blending Level 1, simple alpha compositing
- MDN: Image file type and format guide
- Adobe Help: Select and Mask in Photoshop
- Adobe: Remove background with AI in Photoshop (layer masks)
- rembg README: color decontamination and edge modes
- ImageMagick: Format and print image properties (escapes)
- Pillow: Image module reference
- Etsy Help: Requirements and best practices for images in your Etsy shop