How do I replace the alpha channel of any image (png, jpg, rgb, rbga) with specified background color? It must also work with images that do not have an alpha channel.
Asked
Active
Viewed 3.9k times
3 Answers
39
This can be done by checking if the image is transparent
def remove_transparency(im, bg_colour=(255, 255, 255)):
# Only process if image has transparency (http://stackoverflow.com/a/1963146)
if im.mode in ('RGBA', 'LA') or (im.mode == 'P' and 'transparency' in im.info):
# Need to convert to RGBA if LA format due to a bug in PIL (http://stackoverflow.com/a/1963146)
alpha = im.convert('RGBA').split()[-1]
# Create a new background image of our matt color.
# Must be RGBA because paste requires both images have the same format
# (http://stackoverflow.com/a/8720632 and http://stackoverflow.com/a/9459208)
bg = Image.new("RGBA", im.size, bg_colour + (255,))
bg.paste(im, mask=alpha)
return bg
else:
return im

Humphrey
- 4,108
- 2
- 28
- 27
-
3In modern versions of Pillow you can probably use `.getchannel('A')` instead of `.split()[-1]`. – gps Jun 09 '18 at 18:52
-
4After pasting the image onto the background, I had to also convert to RGB using `bg.convert('RGB')` – tutuDajuju Jan 04 '19 at 14:03
22
I'd suggest using Image.alpha_composite
.
This code can avoid a tuple index out of range
error if png has no alpha channel.
from PIL import Image
png = Image.open(img_path).convert('RGBA')
background = Image.new('RGBA', png.size, (255,255,255))
alpha_composite = Image.alpha_composite(background, png)
alpha_composite.save('foo.jpg', 'JPEG', quality=80)
I also recommend you inspect both results with a image.show()
.
Credits for this answer goes to shuuji3 and others who helped build a vast answers repertoire in this other question.

Vinícius M
- 554
- 6
- 15
-
If the source image is always a PNG, this should be fine, but if it may encounter an image type that doesn't have transparency, e.g. a .jpg, this produces an `OSError: cannot write mode RGBA as JPEG`. I added a check when opening the image to resolve this. – alstr May 23 '22 at 14:03
4
I updated Vincius M's code with the user, tutuDajuju, suggestion to make [height, width, 3] matrix (not [height, width, 4]):
from PIL import Image
import numpy as np
png = Image.open(img_path).convert('RGBA')
background = Image.new('RGBA', png.size, (255,255,255))
alpha_composite = Image.alpha_composite(background, png)
# if you check the matrix dimension, channel, it would be still 4.
h, w, channel = np.asarray(alpha_composite).shape
alpha_composite_3 = alpha_composite.convert('RGB')
# if you check the matrix dimension, channel, it would be 3.
h, w, channel = np.asarray(alpha_composite_3).shape

Cloud Cho
- 1,594
- 19
- 22
-
1You need to add the `.shape` to the numpy array to accessthe `h, w, channel` variables. – jegertor Jul 10 '23 at 16:43
-