Mỗi pixel trong một ảnh thông thường được mô tả bằng ba con số: lượng đỏ, xanh lục và xanh lam mà nó chứa. Như vậy đủ để biết pixel có màu gì, nhưng không cho biết có nhìn xuyên qua được hay không. Kênh alpha là con số thứ tư của mỗi pixel làm đúng việc đó: nó lưu độ đục, từ trong suốt hoàn toàn đến đục hoàn toàn.
Khi mọi người nói "ảnh PNG nền trong suốt", ý họ là một ảnh có kênh alpha, trong đó các pixel nền có alpha bằng 0. Bài này giải thích con số đó hoạt động thế nào, hai cách phần mềm lưu nó, vì sao mép ảnh bị lỗi, và cách kiểm tra tệp thực sự chứa gì.
RGBA: bốn kênh cho mỗi pixel
MDN định nghĩa kênh alpha rất đơn giản: màu được tạo từ các kênh (đỏ, xanh lục và xanh lam), và để mô tả một màu "mà qua đó có thể nhìn thấy nền ở một mức độ nào đó", người ta thêm kênh thứ tư. Ảnh có đủ bốn kênh được gọi là RGBA.
Giá trị này có thể viết theo nhiều cách, và tất cả đều mang cùng một ý nghĩa:
| Cách ghi | Trong suốt hoàn toàn | Trong suốt một nửa | Đục hoàn toàn |
|---|---|---|---|
| Số nguyên 8 bit (đa số tệp ảnh) | 0 | 128 | 255 |
| Số nguyên 16 bit (PNG 16 bit) | 0 | 32768 | 65535 |
| Phân số (phép tính tổng hợp ảnh, CSS) | 0 | 0.5 | 1 |
| Phần trăm (CSS) | 0% | 50% | 100% |
Hậu tố hex (CSS #rrggbbaa) | 00 | 80 | ff |
Đặc tả PNG nói rất chính xác: alpha bằng 0 là trong suốt hoàn toàn, giá trị lớn nhất theo độ sâu bit là đục hoàn toàn, còn các giá trị ở giữa là những pixel trong suốt một phần "có thể được tổng hợp lên một ảnh nền".
Các giá trị ở giữa đó mới là phần quan trọng. Một ảnh tách nền tốt không chỉ đơn giản là "chủ thể đục, nền trong suốt". Các pixel dọc theo mép, nhất là ở tóc, lông, vải, thủy tinh và vùng nhòe chuyển động, đều trong suốt một phần, và chính điều đó giúp chủ thể trông tự nhiên trên nền mới thay vì như bị cắt bằng kéo.
Một pixel trong suốt được vẽ ra sao
Khi một ứng dụng đặt ảnh của bạn lên trên thứ khác, nó trộn từng pixel với phần phía sau. Đặc tả Compositing and Blending của W3C đưa ra công thức cơ bản:
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)Trong trường hợp phổ biến là nền phía sau đục hoàn toàn, công thức trở thành một phép trung bình có trọng số. Pixel có alpha 0,3 đóng góp 30% màu của chính nó và để 70% màu nền lộ qua.
Alpha thẳng và alpha nhân trước
Có hai cách lưu màu của một pixel trong suốt một phần, và nhầm lẫn giữa chúng là nguồn gốc kinh điển của viền tối hoặc viền sáng.
Alpha thẳng (straight alpha, còn gọi là unassociated hay non-premultiplied) lưu màu như thể pixel đục hoàn toàn, và giữ độ đục riêng. Một pixel đỏ thuần trong suốt một nửa được lưu là đỏ 255, xanh lục 0, xanh lam 0, alpha 128.
Alpha nhân trước (premultiplied alpha, còn gọi là associated) lưu màu đã được nhân sẵn với alpha. Cùng pixel đó được lưu là đỏ 128, xanh lục 0, xanh lam 0, alpha 128. Như đặc tả PNG mô tả, ảnh như vậy "đã được tổng hợp sẵn lên nền đen".
Tệp dùng cách nào tùy vào định dạng và phần mềm:
- PNG luôn dùng alpha thẳng. Đặc tả nói rõ điều này, và lưu ý rằng nhờ vậy trình chỉnh sửa có thể dễ dàng thay đổi độ trong suốt của ảnh.
- Các pipeline đồ họa, game engine và công cụ tổng hợp video thường dùng alpha nhân trước ở bên trong, vì phép trộn đơn giản hơn và bộ lọc hoạt động tốt hơn.
Rắc rối bắt đầu khi một chương trình ghi giá trị nhân trước còn chương trình khác lại đọc như alpha thẳng. Màu dọc theo mép bị tối quá, tạo thành một đường viền đen mảnh. Ngược lại thì mép bị sáng quá. Nếu bạn thấy một viền tối giống nhau trên mọi ảnh tách nền từ cùng một công cụ, sai lệch nhân trước là điều đầu tiên nên nghi ngờ.
Vì sao ảnh tách nền bị quầng
Quầng (halo) là một viền nhìn thấy được quanh chủ thể nhưng không thuộc về chủ thể. Có bốn nguyên nhân phổ biến, mỗi nguyên nhân có cách khắc phục riêng.
1. Nền cũ bị lẫn vào các pixel ở mép
Máy ảnh không bao giờ ghi lại được một đường ranh giới sạch. Một sợi tóc trước hàng rào cây xanh tạo ra những pixel vừa là tóc vừa là cây. Nếu ảnh tách nền giữ màu gốc của các pixel đó và chỉ làm chúng trong suốt một phần, màu xanh vẫn còn lẫn trong đó. Đặt lên nền trắng, chủ thể sẽ có một quầng xanh mờ.
Cách khắc phục là khử nhiễm màu (color decontamination): ước tính màu thật của tiền cảnh cho từng pixel ở mép và ghi màu đó vào thay thế. Photoshop gọi tính năng này là Decontaminate Colors trong không gian làm việc Select and Mask, và thư viện mã nguồn mở rembg có tùy chọn decontaminate làm điều tương tự. Nó thay đổi màu ở mép, không bao giờ thay đổi hình dạng của mặt nạ.
2. Mặt nạ quá cứng
Nếu mặt nạ chỉ có pixel đục hoàn toàn và trong suốt hoàn toàn, mép sẽ bị răng cưa, và phần khử răng cưa trong ảnh gốc để lại một đường màu nền rộng một pixel quanh chủ thể. Những chủ thể mềm như tóc cần một mặt nạ mềm với các giá trị trung gian thực sự.
3. Màu ẩn trong các pixel trong suốt
Trong tệp alpha thẳng, pixel có alpha bằng 0 vẫn có giá trị đỏ, xanh lục và xanh lam. Bạn không thấy chúng, nhưng khi đổi kích thước hoặc làm mờ ảnh, các pixel lân cận bị trộn với nhau, và nếu những màu ẩn đó là trắng hoặc đen, chúng sẽ lan vào mép nhìn thấy được. Các thư viện xử lý ảnh tốt tránh điều này bằng cách nhân trước trước khi đổi kích thước rồi chuyển lại sau đó.
4. Ảnh đã bị làm phẳng lên một màu
GIF và PNG dùng bảng màu thường chỉ hỗ trợ trong suốt kiểu bật hoặc tắt, nên công cụ khử răng cưa mép trên một màu nền (matte), thường là trắng, trước khi lưu. Ảnh đó trông ổn trên nền trắng nhưng hiện viền trắng trên mọi nền tối hơn. Nếu ảnh tách nền sẽ nằm trên nền tối, hãy xuất với kênh alpha đầy đủ.
Mặt nạ, matte và alpha: thuật ngữ
Những từ này chồng lấn nhau và hay bị dùng lẫn lộn. Đây là cách chúng thường được hiểu:
- Kênh alpha: các giá trị độ đục lưu bên trong tệp ảnh, mỗi pixel một giá trị.
- Mặt nạ (mask): một ảnh thang xám quyết định phần nào của ảnh khác được hiển thị. Trong mặt nạ lớp (layer mask) của Photoshop, trắng để hiện, đen để ẩn, còn xám là hiện một phần. Mặt nạ có thể chỉnh sửa mà không động vào pixel gốc, đó là lý do dân chuyên nghiệp tách nền bằng mặt nạ thay vì tẩy xóa.
- Matte: thuật ngữ trong điện ảnh và tổng hợp hình ảnh cho cùng ý tưởng đó, một ảnh thang xám xác định phần được giữ lại. "Matting" là bài toán tính ra matte mềm và chính xác cho những mép khó như tóc.
- Trimap: một bản đồ thô gồm ba vùng (chắc chắn là tiền cảnh, chắc chắn là nền, chưa chắc) mà một số thuật toán matting dùng làm điểm xuất phát.
- Mặt nạ nhị phân hay mặt nạ cứng: chỉ có đen và trắng, không có xám. Ổn với hộp và logo, kém với tóc.
- Ảnh tách nền (cut-out): kết quả cuối cùng, gồm màu của chủ thể cộng với một kênh alpha.
Mặt nạ và kênh alpha chứa cùng một thông tin. Nhiều công cụ cho phép bạn xuất một trong hai: tệp PNG trong suốt có sẵn alpha, hoặc một ảnh mặt nạ đen trắng riêng để bạn tự áp dụng trong trình chỉnh sửa ảnh hay công cụ dựng video.
Định dạng nào lưu được alpha
| Định dạng | Hỗ trợ alpha |
|---|---|
| PNG | Alpha đầy đủ (8 hoặc 16 bit), hoặc một màu trong suốt trong bảng màu |
| WebP | Alpha đầy đủ, ở cả chế độ không mất dữ liệu và có mất dữ liệu |
| AVIF | Alpha đầy đủ |
| GIF | Chỉ bật hoặc tắt: một màu trong bảng màu được đánh dấu là trong suốt |
| JPEG | Không có |
Để xem so sánh đầy đủ các định dạng này, hãy đọc PNG, JPEG hay WebP.
Cách kiểm tra ảnh có trong suốt hay không
Tệp có đuôi .png không chứng minh được là có độ trong suốt. Nhiều PNG đục hoàn toàn, và một số ảnh "trong suốt" tìm thấy trên mạng thực ra là JPEG với nền ô caro xám trắng được vẽ thẳng vào pixel. Dưới đây là những cách kiểm tra đáng tin cậy.
Bằng mắt
Đặt ảnh lên một nền tối và một nền sáng, ví dụ trong slide hoặc công cụ thiết kế. Ảnh tách nền thật sẽ để lộ màu nền quanh chủ thể trong cả hai trường hợp. Nếu bạn vẫn thấy ô caro, đó là một phần của bức ảnh, không phải độ trong suốt.
Với 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 cho biết kênh trong suốt (từ chính xác được in ra khác nhau giữa ImageMagick 6 và 7), còn %[opaque] tính xem mọi pixel có đục hoàn toàn hay không. Kết quả bạn muốn là có kênh alpha và false.
Với Python và 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 transparentBước kiểm tra giá trị cực trị phát hiện trường hợp hay gặp: tệp RGBA mà mọi pixel đều đục.
Khi nền tảng bỏ qua alpha
Một số nơi loại bỏ hoặc bỏ qua độ trong suốt. Etsy cho biết không hỗ trợ PNG trong suốt và vùng trong suốt có thể hiện màu đen, còn các sàn như Amazon và Walmart vốn đã yêu cầu ảnh chính trên nền trắng tinh. Trong những trường hợp đó, hãy tự làm phẳng ảnh tách nền lên màu nền để bạn kiểm soát kết quả. Trên website của bạn, trong slide và công cụ thiết kế, hãy giữ kênh alpha.
Có kênh alpha sạch thật nhanh
Nếu bạn cần ảnh tách nền có mép mềm thay vì mặt nạ cứng, removebackground.dev tạo tệp PNG hoặc WebP nền trong suốt với kênh alpha đầy đủ, và API của nó cũng có thể trả về riêng mặt nạ thang xám.
Câu hỏi thường gặp
RGBA nghĩa là gì?
Đỏ (red), xanh lục (green), xanh lam (blue) và alpha. Ba kênh đầu mô tả màu của pixel, kênh thứ tư mô tả độ đục, từ 0 (trong suốt hoàn toàn) đến giá trị lớn nhất (255 với ảnh 8 bit) là đục hoàn toàn.
Alpha thẳng và alpha nhân trước khác nhau thế nào?
Alpha thẳng lưu màu đầy đủ của pixel và độ đục riêng biệt. Alpha nhân trước lưu màu đã nhân sẵn với độ đục, như thể đã được tổng hợp lên nền đen. PNG luôn dùng alpha thẳng; nhiều công cụ dựng hình và video dùng alpha nhân trước ở bên trong.
Vì sao ảnh tách nền của tôi có viền trắng hoặc viền màu?
Thường là do nền cũ vẫn còn lẫn trong các pixel ở mép, hoặc ảnh đã được khử răng cưa trên nền trắng trước khi lưu. Khử nhiễm màu ở mép, dùng mặt nạ mềm và xuất với kênh alpha đầy đủ thay vì một màu nền sẽ khắc phục hầu hết trường hợp.
Mặt nạ có giống kênh alpha không?
Chúng chứa cùng một thông tin: mỗi pixel một giá trị thang xám cho biết mức độ hiển thị. Kênh alpha được lưu bên trong tệp ảnh; mặt nạ thường là một ảnh thang xám riêng hoặc một mặt nạ lớp trong trình chỉnh sửa.
Làm sao biết một tệp PNG có thật sự trong suốt?
Đặt ảnh lên một nền tối và một nền sáng rồi xem nền có lộ qua không. Hoặc chạy lệnh identify của ImageMagick với %[opaque], hay kiểm tra giá trị nhỏ nhất của kênh alpha trong Pillow; giá trị nhỏ nhất là 255 nghĩa là không có gì trong suốt.
Thử với ảnh của bạn
Tài khoản mới được tặng 50 credit miễn phí. Một credit mỗi ảnh, không gói tháng, và credit không bao giờ hết hạn.
Tách nền ngayNguồn tham khảo
- 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