Displaying a transparent PNG image without window in Python

Viewed 665

OS: Windows 10

Python 3.8

I am trying to display PNG images with transparency with no titlebar, or any other indication of window info (imagine sticking a sticker on your screen). I've already done this once in another language by putting an image in a window and removing all the elements of the window, including titlebar and background, but I cannot achieve it in python.

I have already tried Tkinter, but seems like it's not designed to work with PNG transparency and it cannot have separate transparency for parent and child windows.

Now I am trying wxPython. My idea is that it might be possible to make the parent window transparent and the child window (which holds the image) opaque, but cannot figure out if that's even possible.

Here is the simplified version of my attempt:

app = wx.App()

path = 'Images/02.png'

bitmap = wx.Bitmap(path, wx.BITMAP_TYPE_PNG)  # Create bitmap

frame = wx.Frame(None,-1,'Transparent Window',size=(1000,1000)) # Create frame (top level window)
frame.SetTransparent(100)                 # Change transparency of the frame 
panel = wx.Panel(frame, -1)               # Create panel (to hold the image)
wx.StaticBitmap(panel, -1, bitmap)        # Put the image in the panel
panel.SetTransparent(255)                 # Change transparency of the panel (the image)

frame.Show()
app.MainLoop()

But unfortunately ".SetTransparent()" only works on top level window, so I can't set the transparency of the panel to anything else.

But basically, the question is, is it possible to display image with transparency on its own with Python? I am not looking for any specific method of achieving this, the one I provided was just the only one I know. So please help me if you can :)

Edit 1: Tried to use wx.lib.agw.advancedsplash:

import wx
import wx.lib.agw.advancedsplash as AS

app = wx.App()

frame = wx.Frame(None, -1, "AdvancedSplash Test")

imagePath = "Images/05.png"
bitmap = wx.Bitmap(imagePath)

splash = AS.AdvancedSplash(frame, bitmap=bitmap)

app.MainLoop()

But it still fills in transparent areas

3 Answers

You may want to look into the implementation of AdvancedSplash in wx.lib.agw.advancedsplash. It’s sort of a splash screen that adapts itself to the picture you use, and if you have transparencies they will be taken into account.

Transparency is be applied to the frame, so don't worry about the panel, the whole thing becomes transparent.

enter image description here

Be careful how you run this code, as it needs to be killed or Ctrl-C'd.

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, pos=(200,200), style=wx.FRAME_NO_TASKBAR)
        panel1 = wx.Panel(self)
        bitmap = wx.Bitmap('ace2.png', wx.BITMAP_TYPE_PNG)
        image = wx.StaticBitmap(panel1, -1, bitmap)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel1)
        self.SetSizerAndFit(sizer)
        self.Show()
        self.OnTransparent(None)

    def OnTransparent(self, event):        
        self.SetTransparent(180)
        self.Update()
        
app = wx.App()
frame = MyFrame(None, -1)
app.MainLoop()

Try something like this:

import tkinter as tk


root = tk.Tk()
root.overrideredirect(True)
root.config(bg="blue", bd=0, highlightthickness=0)
root.attributes("-transparentcolor", "blue")

canvas = tk.Canvas(root, bg="blue", bd=0, highlightthickness=0)
canvas.pack()

tk_img = tk.PhotoImage(file="cards.png")
canvas.create_image(0, 0, image=tk_img, anchor="nw")

root.mainloop()

It creates an image on the screen like this:

enter image description here

It changes the transparent colour of the window to "blue" (because there isn't any thing blue in the picture that I am using) and sets the background colour to "blue". That makes the window transparent. To show the image I used a tk.Canvas but it might work with tk.Label (haven't tested it).

Please note that this will most likely work only on Windows.

Related