PIL 的高斯模糊不考虑 alpha

问题描述 投票:0回答:1

我正在尝试将高斯模糊应用于具有透明度的 PIL.Image,但模糊似乎不适用于 alpha 通道。

这是我的代码:

import wx
from PIL import Image, ImageFilter
import io

class HaloButton(wx.Button):
    def __init__(self, parent, image, id=wx.ID_ANY, label='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=wx.ButtonNameStr):
        super().__init__(parent, id, label, pos, size, style, validator, name)
        self._image = image.copy()
        self.Bind(wx.EVT_PAINT, self._OnPaint)

    def _OnPaint(self, event):
        dc = wx.PaintDC(self)
        dc.Clear()
        pil_image = self._image.copy()
        blurred_image = pil_image.filter(ImageFilter.GaussianBlur(radius=15))
        bitmap = wx.Bitmap.FromBufferRGBA(blurred_image.size[0], blurred_image.size[1], blurred_image.tobytes())
        dc.DrawBitmap(bitmap, 0, 0)


if __name__ == '__main__':
    app = wx.App()

    frame = wx.Frame(parent=None, title='Halo Button Example', size=(400, 400), style=wx.DEFAULT_FRAME_STYLE)
    frame.SetBackgroundColour((255, 192, 203))  # Rose

    panel = wx.Panel(frame, size=(400, 400), style=wx.SUNKEN_BORDER)
    pil_image = Image.open("image.png")
    button = HaloButton(panel, pil_image, size=(100, 100))
    button.SetPosition((150, 150))

    frame.Show()
    app.MainLoop()

image.png(黄色圆圈周围是透明的):
enter image description here

以及生成的帧:
enter image description here

我看到两个问题。显然,即使原始图像具有透明背景,图像的背景颜色也与框架不同。第二个是,在模糊的地方,它似乎没有融合圆圈中的黄色,也没有与窗户的粉红色或图像的白色背景融合。相反,存在某种黑暗成分。

我做错了什么?

python-imaging-library wxpython gaussianblur
1个回答
0
投票

模糊:

模糊

import wx
from PIL import Image, ImageFilter
import io

class HaloButton(wx.Button):
    def __init__(self, parent, image, id=wx.ID_ANY, label='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=wx.ButtonNameStr):
        super().__init__(parent, id, label, pos, size, style, validator, name)
    
        self._image = image.copy()

        self.Bind(wx.EVT_PAINT, self.OnPaint)
    
    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        #dc.Clear()
        pil_image = self._image.copy()
        blurred_image = pil_image.filter(ImageFilter.GaussianBlur(radius=15))
        bitmap = wx.Bitmap.FromBufferRGBA(blurred_image.size[0], blurred_image.size[1], blurred_image.tobytes())
        dc.DrawBitmap(bitmap, 0, 0)

class Frame(wx.Frame):
    def __init__(self, parent, id, title):
        super().__init__(parent, -1, title, size=(400, 400), style=wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE)

        self.SetBackgroundColour((255, 192, 203))  # Rose
        self.panel = wx.Panel(self, size=(400, 400), style=wx.SUNKEN_BORDER| wx.TRANSPARENT_WINDOW)
        self.Bind(wx.EVT_BUTTON, self.OnClick)
        self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
        pil_image = Image.open("image.png").convert('RGBA')
        button = HaloButton(self.panel, pil_image, size=(100, 100))
        button.SetPosition((150, 150))

    def OnEnter(self, event):   # setHover
        print("Refresh")
        self.Refresh()

    def OnClick(self, event):
        print("Click! (%d)\n" % event.GetId())
        self.Refresh()
    
class App(wx.App):
    def OnInit(self):
        frame = Frame(None, -1, "Halo Button Example")
        self.SetTopWindow(frame)
        frame.Centre()
        frame.Show(True)

        return True

def main():
    app = App(False)
    app.MainLoop()

if __name__ == "__main__" :
    main()

并且没有模糊:

不模糊

import wx
from PIL import Image, ImageFilter
import io

class HaloButton(wx.Button):
    def __init__(self, parent, image, id=wx.ID_ANY, label='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=wx.ButtonNameStr):
        super().__init__(parent, id, label, pos, size, style, validator, name)

        self._image = image.copy()
    
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        #dc.Clear()
        pil_image = self._image.copy()
        blurred_image = pil_image.filter(ImageFilter.GaussianBlur(radius=15))
        blurred_image.putalpha(pil_image.getchannel('A'))  # Preserve transparency
        bitmap = wx.Bitmap.FromBufferRGBA(blurred_image.size[0], blurred_image.size[1], blurred_image.tobytes())
        dc.DrawBitmap(bitmap, 0, 0)

class Frame(wx.Frame):
    def __init__(self, parent, id, title):
        super().__init__(parent, -1, title, size=(400, 400), style=wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE)

        self.SetBackgroundColour((255, 192, 203))  # Rose
        self.panel = wx.Panel(self, size=(400, 400), style=wx.SUNKEN_BORDER| wx.TRANSPARENT_WINDOW)
        self.Bind(wx.EVT_BUTTON, self.OnClick)
        self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
        pil_image = Image.open("image.png").convert('RGBA')
        button = HaloButton(self.panel, pil_image, size=(100, 100))
        button.SetPosition((150, 150))

    def OnEnter(self, event):   # setHover
        print("Refresh")
        self.Refresh()

    def OnClick(self, event):
        print("Click! (%d)\n" % event.GetId())
        self.Refresh()
    
class App(wx.App):
    def OnInit(self):
        frame = Frame(None, -1, "Halo Button Example")
        self.SetTopWindow(frame)
        frame.Centre()
        frame.Show(True)

        return True

def main():
    app = App(False)
    app.MainLoop()

if __name__ == "__main__" :
    main()
© www.soinside.com 2019 - 2024. All rights reserved.