[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] screen position in middle of desk / icon with alpha - using wx to load pygame



This example is just to show: yes. you CAN put a pygame display in the middle of your screen (on windows only, i guess?) and have a transparancy key in your icon bitmap. Something that bothered me for a long time :)

yes, I know wx is no good. If any one knows a better way, please share!

(I used some bits and pieces of two examples I found on the net; how to load pygame with wx, and ImageLib. This is all very preliminary. Just proof of concept. Still needs an idle handler too)
---
minigame.py
---
#!/usr/bin/env python
import WxLib

def inputhandler(pygame):
   for event in pygame.event.get():
   #print dir(pygame)
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: #detect escape
           print "escape"
           return False #signal program to stop execution
       elif not event.type==pygame.MOUSEMOTION:
           print str(event)
   return True

if __name__=='__main__':
   WxLib.initiatescreen("Title",(150,250),inputhandler,'icon.bmp')

---
WxLib.py
---
#!/usr/bin/env python
import wx
import os
import thread
import ImageLib # to load icon from bitmap

def initiatescreen(caption="!", size=(300,200),eventhandler=None, icon=None):
   app = wx.PySimpleApp()
   frame = MyFrame(None, -1, caption, size, eventhandler, icon)
   frame.Show()
   app.MainLoop()
   del frame
   del app

class SDLThread(object):
   def __init__(self,screen, eventhandler=None , parentframe=None):
       self.parentframe=parentframe
       self.screen = screen
       self.eventhandler=eventhandler
       self.pygame=pygame

   def Start(self):
       self.running=True
       thread.start_new_thread(self.Loop, ())

   def Stop(self):
       self.running=False

   def Loop(self):
       while self.running:
           try:
               if not self.eventhandler==None:
                   self.running=self.eventhandler( self.pygame)
                   if not self.running:
                       self.parentframe.Close()
           except:
               self.Stop()

class SDLPanel(wx.Panel):
   def __init__(self,parentframe,ID,tplSize, eventhandler):
       global pygame
       wx.Panel.__init__(self, parentframe, ID, size=tplSize)
       self.Fit()
       os.environ['SDL_WINDOWID'] = str(self.GetHandle())
       os.environ['SDL_VIDEODRIVER'] = 'windib'
import pygame # this has to happen after setting the environment variables.
       pygame.display.init()
       screen = pygame.display.set_mode(tplSize)
       self.thread = SDLThread( screen, eventhandler, parentframe)
       self.thread.Start()

   def __del__(self):
       self.thread.Stop()

class MyFrame(wx.Frame):
def __init__(self, parent, ID, strTitle, tplSize, eventhandler=None, iconname=None): wx.Frame.__init__(self, parent, ID, strTitle, size=tplSize, style=wx.SYSTEM_MENU|wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX|wx.RESIZE_BORDER | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
       self.Centre()
       if not iconname==None:
           bmp = ImageLib.filetobitmap(iconname , (0,0))
           icon1 = ImageLib.bitmaptoicon(bmp)
           self.SetIcon(icon1)
       self.pnlSDL = SDLPanel(self, -1, tplSize, eventhandler)
---

---
ImageLib.py
---
#!/usr/bin/env python
import wx
import Image # for PIL conversion functions
DEFAULT_AUTMASK = (0,0)

def filetopil(filename):
   """
   Loads an PIL image from a file.

NTE: this function is the same as Image.open(filename), using the PIL library.
   It is provided for completeness.

   @param filename: The relative or absolute filename.
   """
   return Image.open(filename)

def filetoimage(filename):
   """
   Loads an image from a file.

NTE: this function is the same as wx.Image(filename), using the wxWidgets library.
   It is provided for completeness.

   @param filename: The relative or absolute filename.
   """
   return wx.Image(filename)

def filetobitmap(filename, automask = DEFAULT_AUTMASK, depth=-1 ):
   """
   Loads an image and converts it immediatelly to a bitmap.

   @param filename: Name of the file
   @type filename: string
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)
@param depth: Used to define the color depth (-1 means depth of current screen or visual)

Note: you can specify other parameters here. They will be passed to the L{Image} constructor.
   Please see L{Imageinit__} for all parameters.
   """
   return imagetobitmap(filetoimage(filename),automask,depth =depth)

def file2icon(filename, automask = DEFAULT_AUTMASK):
   """
   Loads an image and converts it immediatelly to a wx.Icon instance.

   @param filename: Name of the file
   @type filename: string
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)

Note: you can specify other parameters here. They will be passed to the L{Image} constructor.
   Please see L{Imageinit__} for all parameters.
   """
   bmp = filetobitmap(filename, automask)
   return bitmaptoicon(bmp)

def piltobitmap(pil,automask=None,depth=-1):
   """
   Convert PIL Image to wx.Bitmap.

   @param pil: A PIL Image object
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)
   """
   return imagetobitmap(piltoimage(pil),depth=depth)

def piltoimage(pil):
   """
   Convert PIL Image to wx.Image.
   """
   image = wx.EmptyImage(pil.size[0], pil.size[1])
   image.SetData(pil.convert('RGB').tostring())
   return image

def imagetopil(image):
   """
   Convert wx.Image to PIL Image.
   """
   pil = Image.new('RGB', (image.GetWidth(), image.GetHeight()))
   pil.fromstring(image.GetData())
   return pil

def imagetobitmap(image,automask=None,depth=-1):
   """Convert wx.Image to PIL Image.

   @param image: A wx.Image instance
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)

@param depth: Used to define the color depth (-1 means depth of current screen or visual)
   """
   bmp = wx.BitmapFromImage(image,depth=depth)
   return automaskbitmap(bmp,automask,image)

def imagetoicon(image,automask=DEFAULT_AUTMASK,depth=-1):
   """
   Convert wx.Image to wx.Icon.

   @param image: A wx.Image instance
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)
   """
   return bitmaptoicon(imagetobitmap(image,automask,depth=depth))

def bitmaptoicon(bmp):
   """
   Convert wx.Bitmap to wx.Icon.

   NTE: The bitmap should already have a mask assigned. If you want to
   set a mask for a bitmap, please use the L{automaskbitmap} function.

   @param bmp: A wx.Bitmap instance
   """
   ico = wx.Icon('',bmp.GetWidth(),bmp.GetHeight())
   ico.CopyFromBitmap(bmp)
   return ico

def bitmaptopil(bitmap):
   """
   Convert wx.Bitmap to PIL Image.
   """
   return imagetopil(bitmaptoimage(bitmap))

def bitmaptoimage(bitmap):
   """
   Convert wx.Bitmap to wx.Image.
   """
   return wx.ImageFromBitmap(bitmap)

def automaskbitmap(bitmap,automask=DEFAULT_AUTMASK,image=None):
   """
   Add a mask (transparency layer) to a bitmap.

   NTE: this function has a side effect! (Changes the bitmap parameter.)

   @param bitmap: A wx.Bitmap instance
   @param automask: What point you want to use for transparency:
   None -do not add mask (no transparency)
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)

   @param image: a wx.Image for automask calculation (not needed).

   @return: the same bitmap.
   """
   if not automask is None:
       if image is None:
           image = bitmaptoimage(bitmap)
   pil = imagetopil(image)
   bitmap.SetMask(wx.Mask(bitmap,getmaskcolor(pil,automask)))
   return bitmap

def resizeimage(image,newsize,must_copy=False):
   """
   Resize a wx.Image correctly (with antialiasing).

   @param newsize: a tuple of (width,height)
@param must_copy: If you set this flag then this function will always return a new instance
   of the given image, even when no resizing is needed.
@return: this function will not resize if the size is already correct and it will return the original image instance unless the must_copy flag set. When resizing needed, it will create a new wx.Image instance, resized with antialiasing (the only one correct resizing method).
   """
   oldsize = (image.GetWidth(),image.GetHeight())
   if oldsize != newsize:
       return piltoimage(resizepil(imagetopil(image),newsize,False))
   else:
       if must_copy:
           return wx.Image(image)
       else:
           return image

def copybitmap(bmp,automask=None):
   """
   Return a copy of a bitmap.

   @param bmp: a wx.Bitmap instance
   @return a copy of the parameter.

   NTE: Also copies the mask.
   """
   width,height,depth = bmp.GetWidth(), bmp.GetHeight(), bmp.GetDepth()
   res = wx.EmptyBitmap(width,height,depth)
   new_dc = wx.MemoryDC()
   old_dc = wx.MemoryDC()
   new_dc.S(res)
   old_dc.S(bmp)
   try:
       new_dc.Blit(0,0,width,height,old_dc,0,0,useMask=True)
   finally:
       new_dc.S(wx.NullBitmap)
       old_dc.S(wx.NullBitmap)
       automaskbitmap(res,automask)
   return res

def resizepil(pil,newsize,must_copy=True):
   """
   Resize a PIL Image correctly (with antialiasing).

   @param newsize: a tuple of (width,height)
   @param must_copy: clear this flag if you do not want to create a copy of
   the PIL object (will cause a function side effect)
   @return: the resized PIL image
   """
   if must_copy:
       res = pil.copy()
   else:
       res = pil
   return res.resize(newsize,Image.ANTIALIAS)

def getmaskcolor(pil,automask = DEFAULT_AUTMASK):
   """
   Determine mask color for a PIL object

   @param pil: A PIL Image object
   @param automask: What point you want to use for transparency:
   None -no transparency
   (0,0) -color of top left pixel (L{DEFAULT_AUTMASK})
   (0,-1) -color of the bottom left pixel
   (-1,0) -color of the top right pixel
   (-1,-1) -color of the bottom right pixel
   (x,y) -color of pixel (x,y) (where -1 means the biggest coordinate)
   """
   (width,height) = pil.size
   (x,y) = automask
   if x < 0:
       x = width - 1
   if y < 0:
       y = height - 1
   return pil.getpixel((x,y))
---

_________________________________________________________________
Make every IM count. Download Messenger and join the i?m Initiative now. It?s free. http://im.live.com/messenger/im/home/?source=TAGHM