I'm trying to apply gaussian blur to a PIL.Image which has transparency, but blurring doesn't seem to be applied to the alpha channel.
Here's my code:
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 (which is transparent around the yellow circle):
I see two issues. Obviously, the background color of the image is not the same as the frame, even though the original image has transparent background. The second is that where there is blur, it doesn't seem to merge the yellow from the circle, neither with the pink of the window nor the white background of the image. Instead, there is some kind of a dark component.
What am I doing wrong?
EDIT:
What I expected was something like this:
which was made with GIMP by applying a gaussian blur to the image and putting a pink layer underneath.