为什么这段代码不支持png图片的透明度?

1 投票
4 回答
973 浏览
提问于 2025-04-16 01:30

我发现问题的原因是图片,因为代码在其他有透明背景的png图片上运行正常。但是,它在我需要的那张图片上却不行。这对我来说很重要,因为我想做一个好看的窗口形状。

这张图片:

alt text

这段代码:

import wx

class PictureWindow(wx.Frame):
    def __init__(self, parent, id, title, pic_location):

        # For PNGs. Must be PNG-8 for transparency...
        self.bmp = wx.Image(pic_location, wx.BITMAP_TYPE_PNG).ConvertToBitmap()

        framesize = (self.bmp.GetWidth(), self.bmp.GetHeight())

        # Launch a frame the size of our image. Note the position and style stuff...
        # (Set pos to (-1, -1) to let the OS place it.
        # This style wx.FRAME_SHAPED is a frameless plain window.
        wx.Frame.__init__(self, parent, id, title, size=framesize, pos = (50, 50), style = wx.FRAME_SHAPED)

        r = wx.RegionFromBitmap(self.bmp)
        self.SetShape(r)

        # Define the panel and place the pic
        panel = wx.Panel(self, -1)
        self.mainPic = wx.StaticBitmap(panel, -1, self.bmp)

        # Set an icon for the window if we'd like
        #icon1 = wx.Icon("icon.ico", wx.BITMAP_TYPE_ICO)
        #self.SetIcon(icon1)

        self.Show()

        # The paint stuff is only necessary if doing a shaped window
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Main()


    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0, True)

    def Main(self):
        sizer = wx.GridBagSizer()
        button = wx.Button(self,-1,label="Click me !")
        sizer.Add(button, (0,1))


# What pic are we opening?
pic_location = r"C:\Users\user\Pictures\CPUBAR\A4.png" # PNG must be png-8 for             transparency...

app = wx.App(redirect=0) # the redirect parameter keeps stdout from opening a wx gui window
PictureWindow(None, -1, 'Picture Viewer', pic_location)
app.MainLoop()

顺便说一下,我是在Windows 7上操作的。

4 个回答

0

你的代码说需要使用png-8格式才能让透明效果生效。首先,这张图片是png-8格式吗?其次,为什么透明效果必须用这个格式呢?

0

你正在把图片转换成位图格式,但位图是不支持透明背景的。

7

wx.RegionFromBitmap这个功能是用来根据位图的遮罩来设置形状的。如果你的源图像有透明通道(也就是alpha通道),那么它就不会有遮罩,这样wx.RegionFromBitmap就无法判断应该用什么形状。你可以把源图像转换成所有像素要么完全不透明,要么完全透明,这样wx.Image就会用遮罩来加载,而不是用透明通道。或者你也可以在运行时使用wx.Image的ConvertAlphaToMask方法进行转换,然后再把它转成wx.Bitmap。

撰写回答