Mike From Work
Mike From Work

Reputation: 13

How do I make the background of an image, that is pasted on top of another image, transparent in pillow?

I'm making a chess bot which will run in a chat program reacting and moving pieces according to commands from users. As such, I am trying to make it paste png images of chess pieces on top of a png background image of a chessboard by using the python package pillow.

In any other software, the chess pieces have transparent backgrounds and whatever is behind them show through but when I paste it on top of the chessboard using pillow the chess-piece gets a grey background which does not match the tile on the chessboard.

Is there a way in which I can paste the chess-piece image on top of my chessboard background without the added grey background colour of the chess-piece? Or is there an alternative way of doing this in python which will give the desired result?

I'm not done with the bot and the game logic but as an example, I have included some code illustrating how I've pasted one image on top of the other one below:

from PIL import Image

board = Image.open('assets/chessboard.png')
w_pawn = Image.open('assets/w_pawn_png_shadow_128px.png')

a_eight = (102, 30, 210, 158)  # Left, top, right and bottom coordinates of where the piece is pasted onto the board

battle_board = board.copy()
battle_board.paste(w_pawn, a_eight)
battle_board.show()

Just to quickly show what the output looks like I've included a screenshot of what a pawn looks like when it's pasted onto the board:

A white pawn in A8 with faulty background colour

enter image description here

Chessboard

white pawn

Upvotes: 1

Views: 665

Answers (1)

martineau
martineau

Reputation: 123541

OK, here's how to do it using the PIL.Image.alpha_composite() PIL Image class static function that I recommended in the comments. It performs an image-processing operation known as alpha compositing.

Update: I discovered there's also an Image.alpha_composite() method that does a similar operation, but does it "in-place" — which potentially could provide better performance (although the current documentation says that is currently not the case). Because that might change in the future, I've modified the code shown to make use of it to take advantage of possible future changes.

Since there's no alpha_composite_paste() function, an image the same size as the background chessboard image must first be created with a fully transparent background. The chess-piece is then pasted onto it in the desired location.

Once all that's done, you now have two identically sized images — as required by alpha_composite()— the compositing is then applied…the final step of the process.

from PIL import Image

# Two RGBA images.
board = Image.open('chessboard.png')
w_pawn = Image.open('w_pawn_png_shadow_128px.png')

a_eight = (102, 30, 210, 158)  # Left, top, right and bottom coordinates of where
                               # the piece is pasted onto the board

battle_board = board.copy()

# First make a fully transparent image the same size as the chessboard image.
tmp_img = Image.new('RGBA', battle_board.size, color=(0,0,0,0))
tmp_img.paste(w_pawn, box=a_eight)  # Paste chess-piece on it at desired posn.
battle_board.alpha_composite(tmp_img)  # Composite tmp_img onto board img "in-place".
battle_board.show()  # TaDa!

Here's the result:

resulting image showing transparency was preserved

Upvotes: 1

Related Questions