user27984094
user27984094

Reputation: 3

Transparent background PNG in wxpython

Currently using WXpython creating a chess puzzle game and I'm trying to display 2 images, one on top of the other.

The issue is, despite the original image of the white pawn in my files having a transparent background, all the transparent pixels appear to be converted to white and block the image displayed behind.

I don't want to just create one image of the pieces on the board, as that would be very tedious.

Is there anyway i could make the background if the image transparent in wxpython?

boardIMG = "chessboard.PNG"
        self.board_img = wx.Image(boardIMG, wx.BITMAP_TYPE_PNG).Rescale(500,500).ConvertToBitmap()
        wx.StaticBitmap(self, -1, self.board_img, (0, 0), (self.board_img.GetWidth(), self.board_img.GetHeight()))

        WpawnIMG = "Wpawn.PNG"
        self.Wpawn_img = wx.Image(WpawnIMG, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        wx.StaticBitmap(self, -1, self.Wpawn_img, (0,0), (self.Wpawn_img.GetWidth(), self.Wpawn_img.GetHeight()))

I have tried using python pillow to change pixel colors, using EVT_PAINT and mask as i have looked at similar issues on here, however have not found someone with the same issue.

Upvotes: 0

Views: 77

Answers (1)

Headcrab
Headcrab

Reputation: 7133

The transparency support of wxPython's StaticBitmap control seems to be platform-dependent. Using more or less your exact code and these two images I got from Wikipedia:

Chess boardWhite pawn

import wx
class MainWindow(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title, size=(500, 500))
        
        boardIMG = "chessboard.png"
        self.board_img = wx.Image(boardIMG, wx.BITMAP_TYPE_PNG).Rescale(500,500).ConvertToBitmap()
        wx.StaticBitmap(self, -1, self.board_img, (0, 0), (self.board_img.GetWidth(), self.board_img.GetHeight()))

        WpawnIMG = "whitepawn.png"
        self.Wpawn_img = wx.Image(WpawnIMG, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        wx.StaticBitmap(self, -1, self.Wpawn_img, (0,0), (self.Wpawn_img.GetWidth(), self.Wpawn_img.GetHeight()))

app = wx.App()
frame = MainWindow(None, -1, "Window")
frame.Show(1)
app.MainLoop()

I got the following results on Linux and Windows, respectively:

Linux, transparent Windows, non-transparent

An easy way to make it work on Windows as well is to handle OnPaint as follows:

import wx
class MainWindow(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title, size=(500, 500))
        
        boardIMG = "chessboard.png"
        self.board_img = wx.Image(boardIMG, wx.BITMAP_TYPE_PNG).Rescale(500,500).ConvertToBitmap()
        
        WpawnIMG = "whitepawn.png"
        self.Wpawn_img = wx.Bitmap(WpawnIMG) # can just use instead of the line below
        #self.Wpawn_img = wx.Image(WpawnIMG, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, evt):
        dc = wx.PaintDC(self)

        # draw the board first
        dc.DrawBitmap(self.board_img, 0, 0)

        # then the pieces
        for i in range(3):
            # image, horizontal pos, vertical pos
            dc.DrawBitmap(self.Wpawn_img, i * 150, 0)

app = wx.App()
frame = MainWindow(None, -1, "Window")
frame.Show(1)
app.MainLoop()

Cross-platform with OnPaint

Update the screen after updating their coordinates, and you'll have it not so much more complex than with StaticBitmap controls.

Upvotes: 0

Related Questions