Welcome, guest | Sign In | My Account | Store | Cart

I use this utility to generate an "images.py" module which I use to provide images to my applications via wx.ImageFromStream . You can see an output in my other recipe "A foldable panel with a Windows XP look and feel". The utility is called "convert.py" and can be put in a folder together with the png images. When run, it'll generate the "images.py" file which can be moved to wherever it'll be used. The only thing I'm checking for is that "convert.py" won't overwrite an existing "images.py" file in the same directory.

Python, 117 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import sys
import os
import binascii
from glob import glob

s_header="""import wx
from cStringIO import StringIO
from binascii import a2b_base64

class Images:
    def __init__(self):
        for name in _names:
            img = wx.ImageFromStream(StringIO(a2b_base64(eval(\"_\"+name))))
            img.ConvertAlphaToMask(100)
            exec(\"self.bmp_\"+name+\"=img.ConvertToBitmap()\")
        self._names=_names\n
"""

max_line=78

def split_string(s):
    ls=len(s)
    so=""
    while len(s)>max_line-1:
        so+=s[:max_line-1]+"\\\n"
        s=s[max_line-1:]

    so+=s
    return so

def split_list(s):
    b=s
    s_out=""
    while(len(b)>max_line):
        c=b[0:max_line]
        tail,head=c[::-1].split(",",1)
        head,tail=head[::-1],tail[::-1]
        s_out+=head+",\n"
        b="    "+tail+b[max_line:]

    s_out+=b
    return s_out

def convert_base64(s,var_name):
    so=binascii.b2a_base64(s)
    print "converting %s: %d->%d" % (var_name,len(s),len(so))

    r_out="%s=\"" % var_name
    r_out+=so[:-1]+"\""

    return r_out

def convert(s,var_name):
    l=len(s)
    print "converting %s (%d chars)" % (var_name,l)

    r_out="%s=\"" % var_name
    for c in s:
        o=ord(c)
        if c=="\"":
            c_out="\\\""
        elif c=="\'":
            c_out="\\\'"
        elif c=="\\":
            c_out="\\\\"
        elif o>31 and o<127:
            c_out=c
        elif o<16:
            c_out="\\x0"+hex(o)[2:]
        else:
            c_out="\\x"+hex(o)[2:]

        r_out+=c_out

    r_out+="\""
    return r_out

def main(argv=None):
    #for the time being, get the list from glob...
    png_files=glob(os.path.join(".",'*.png'))

    v_list=[]
    s_vars=""
    for fn in png_files:
        s=open(fn,"rb").read()
        p,fn=os.path.split(fn)
        v=fn[:-4]
        v=v.replace("stock_","")
        v=v.replace("3d-","")
        v=v.replace("-16","")
        v=v.replace("-","_")
        v=v.replace(" ","_")
        v=v.replace(".","_")

        v_list.append(v)

        r=split_string(convert_base64(s,"_"+v))
        s_vars+=r+"\n\n"

    s_names=split_list("_names="+str(v_list))+"\n\n"

    if os.path.exists("images.py"):
        try:
            os.rename("images.py","images.bak")
            print "Your old images.py was renamed images.bak"
        except:
            print "Sorry, I don\'t do deletes..."
            print "Please delete images.bak yourself"

    f=open("images.py","w")
    f.write(s_header)
    f.write(s_names)
    f.write(s_vars)
    f.close()

if __name__ == '__main__':
    main()

The max_line variable defines the lines length for the image data.

2 comments

Denis Barmenkov 17 years, 8 months ago  # | flag

readability of identifiers. I mean, there will be one more line after last [v=v.replace(".","_")]:

import re
...
   v=v.replace(".","_")             # old code
   v = re.sub('_{2,}', '_', v)      # fix!

   v_list.append(v)                 # old code
Egor Zindy (author) 17 years, 8 months ago  # | flag

Yes, that is useful. Converts multiple underscores into single ones. I'll rework my string manipulation code but I think my program should come with a fair warning: "if possible, clean the filenames as much as you can before running the program".

The main reason for the code is to process the openoffice icons (see http://www.novell.com/coolsolutions/feature/1637.html for a zip/tarball).

Their (stock) filenames come as something like "stock_data-save.png" which need to be cleaned-up a bit before they can be used as variable names.

If I get a sec, I'll turn the filename->variable name conversion bit of code into a cookbook recipe (which won't span over 300 lines for a change!)

Cheers, Egor