3

I have a python app, that I got from here and modified to my needs, but I would like to put the images I use for icons within the script, I am aware there might be performance issues but it's not a problem at the moment, all I need is leave all the files in one, so I can change with my friends and across my computers easily. So my question is, how can I use an embedded icon image (png files, can be any type) with this line of code that it gets a path to a file, in place of the file itself?

   def set_icon(self, path):
    icon = wx.IconFromBitmap(wx.Bitmap(path))
    self.SetIcon(icon, TRAY_TOOLTIP)

I tried with img2py, base64, nothing worked, so I thought it might be the path needed not the file. How could I change/modify the script (or the wx lib) to make it work with embedded files instead of their paths?

Community
  • 1
  • 1

1 Answers1

4

The way I usually accomplish this is to combine base64 and zlib

Generate the embedded image data by

    from zlib import compress
    from base64 import b64encode
    with open("image.png", "rb") as fileobj:
        data = b64encode(compress(fileobj.read()))

copy 'data' to your script using triple quotes and inserting line breaks as needed.

data = """Tm90IGFjdHVhbCBwaWN0dXJlIGRhdGE="""

When you need to re-create the image data, just reverse the encoding and compression

from base64 import b64decode
from zlib import decompress
image_data = decompress(b64decode(data))

How you re-create your bitmap object depends on your version of wxpython. Using the phoenix build you can call create a wx.Image from a stream and then a wx.Bitmap from an image

from io import BytesIO
stream = BytesIO(bytearray(image_data)) # just bytes() for py3
image = wx.Image(stream, wx.BITMAP_TYPE_ANY) # wx.ImageFromStream for legacy wx
bitmap = wx.Bitmap(image) # wx.BitmapFromImage for legacy wx

In my uses I haven't noticed a performance impact, even when using several embedded files

user2682863
  • 3,097
  • 1
  • 24
  • 38
  • 2
    There are some tools included with wxPython that help encode an image file into a python module as a `PyEmbeddedImage` object, which has methods for turning it into a `wx.Image`, `wx.Bitmap` or etc. See `python -m wx.tools.img2py --help` – RobinDunn Feb 25 '17 at 21:04