×

Discussion Board

Results 1 to 7 of 7

Hybrid View

  1. #1
    Regular Contributor
    Join Date
    Jan 2005
    Location
    Bangkok, Thailand
    Posts
    148

    Lightbulb Using Icon as Image

    After begging for so long, I got a chance to see 1.1.5 documentation
    yesterday. (Thanks, dev team)
    So, I reported a minor documentation error, and read around
    if there are something new that I had missed.
    Here is what I had missed last time (when I read just from source)
    - ListBox allow icon image
    see http://www.bigbold.com/snippets/posts/show/422

    Wow, now I can make the UI look more professional.
    I might be able to draw these image myself (no, actually).
    I might load lots and lots of available icons (in the system)
    and put it into my app or my game(our topic today).

    However, the Icon and the Image are different stuff.
    Icon belongs to appuifw. Image belongs to graphics.
    You can put Icon into ListBox, you can't put Image there.
    You can put Image on the Canvas, you can't put Icon there.
    Why, oh why! They are all just graphics, they should be
    all interchangable. (but they aren't, ... yet)

    What can an ameture hacker, like me.. , do?
    DIY, of course ^_^
    To make everything interchangable, I make a conversion
    graph of what can be converted to what. Showing overview
    Here's the result

    mbm => Icon (=>screenshot =>Image ?)
    bmp => Image <=> png
    bitarray => Image

    To make a graph tranversible from anywhere to anywhere,
    where must I bridge?
    Many key missing parts are
    Image => mbm
    Image => bmp
    Image => bitarray (with GetPixel() that I requested)
    png => bitarray (mod from PIL)
    mbm <=> bitarray (hack mbm spec)

    Of all these, the last two is the most important.
    The most useful one will be mbm => bitarray
    which will bring most avaiable logo to Image.
    So, I will start here.

    ==================================

  2. #2
    Regular Contributor
    Join Date
    Jan 2005
    Location
    Bangkok, Thailand
    Posts
    148
    Hacking *.mbm isn't as easy as I first thought.
    I remember last time when I did bmp<=>bitarray, that one
    is much easier (more readable spec, some python code).
    I did that to create my own canvas (before 1.1).

    I read mbm spec from here first.
    http://www.newlc.com/article.php3?id_article=59
    However, when I look into the real mbm file
    z:\system\data\avkon.mbm it is different because it's not
    DirectFileStore type, but a Clip Are File on ROM type.
    Luckily, it links to Frodo's page at
    http://huizen.dds.nl/~frodol/psiconv/html/MBM_File.html
    which link to another page
    http://www.frodol.dds.nl/psiconv/htm...r_Section.html
    which link to the eventually useful 2 pages
    http://www.frodol.dds.nl/psiconv/htm..._Art_File.html
    http://www.frodol.dds.nl/psiconv/htm...a_Section.html
    (Let me note that all these are 404, avaiable only in google cache)

    So, I play with it for a few hours.. failing to view mbm file
    on my windows machine... then succeeding in manually
    decode the rle method. Redo it with some python code...
    worried about endians... all those stuff you typically face
    when you did a file-format hacking...
    Eventually, I found that in avkon.mbm there are
    - totally 503 icon files
    - 295 are 1-bit, 191 are 8-bit, 17 are 16-bit (why not 24?)
    - 118 are 1-bit(rle8), 177 are 1-bit(no-rle)

    I decide to focus on reading
    - 1-bit icon (majority, no need to do pallete).
    - On ROM z:\\ (majority: (z=66, c=3, e=24)).
    - both no rle and rle-8
    Then I can draw the bitarray on Image.new() using im.point(...)
    Make them all into a module (no OO yet). So, when I want to
    use it I can just use

    import icon_image
    im = icon_image.open('z:\\system\\data\\avkon.mbm', 28)
    # then use im just like any other image
    # You can even use just icon_image.open(idx=28), being lazy.

    Working on
    - 8-bit, 16-bit, 24-bit
    - other RLE encoding
    - DirectFileStore on C:\ and E:\
    - save as .mbm
    - PNG to bitarray (mod. to PIL)
    are left as challenges to those who want a REAL python challenge

    The code of icon_image.py version 0.1 follows
    =========================================

  3. #3
    Regular Contributor
    Join Date
    Jan 2005
    Location
    Bangkok, Thailand
    Posts
    148
    Code:
    # icon_image.py
    # called by just import icon_image
    # im = icon_image(file_mbm, idx)
    from graphics import Image
    from struct import unpack
    
    def readL(f, pos=None):
        if pos is not None:
            f.seek(pos)
        return unpack('L', f.read(4))[0]
    
    def open(file_mbm='z:\\system\\data\\avkon.mbm', idx = 28):
    
        # read icon data from mbm file
        f = file(file_mbm, 'rb')
        if readL(f) != 0x10000041:
            return None  # work for mbm on ROM (z:) only
        start = readL(f, 8+4*idx)
        f.seek(start+20)
        length = readL(f) - readL(f)  # pd_size - offset
        width, height = readL(f), readL(f)
        enc = readL(f, start+56)
        f.seek(start+68)
        data_encoded = f.read(length)
    
        # decode the data
        data_padded = rle_decode(data_encoded, enc)
        mat = bit_matrix(data_padded, width, height)
        
        im = Image.new((width, height), '1')
        for j in range(height):
            for i in range(width):
                im.point((i,j), mat[j][i]*0xffffff)
        return im
    
    # Decode of 8-bit RLE
    # Either to repeat-(n+1)-times or not repeat (100-n) bytes
    def rle_decode(bytes, enc=1):
        if not enc: return bytes
        out = []
        i = 0
        while i < len(bytes):
            n = ord(bytes[i])
            i += 1
            if n < 0x80:
                out.append( bytes[i] * (n+1) )
                i += 1
            else:
                n = 0x100 - n
                out.append( bytes[i:i+n] )
                i += n
        return ''.join(out)
    
    # from bytes to bit matrix
    # Each line was padded to 4-byte boundary, must discard the end
    def bit_matrix(bytes, width, height):
        mat = []
        k = 0
        for j in range(height):
            line = []
            while len(line)<width:
                longint, = unpack('L', bytes[k: k+4])
                k += 4
                toget = min(width - len(line), 32)
                for i in range(toget):
                    longint, r = divmod(longint, 2)
                    line.append(int(r))
            mat.append(line)
        return mat
    Or download it from
    http://larndham.net/service/pys60/icon_image.py
    Last edited by korakotc; 2005-07-03 at 00:38.

  4. #4
    Regular Contributor
    Join Date
    Jan 2005
    Location
    Bangkok, Thailand
    Posts
    148
    Some of you may like to know what are available in avkon.mbm
    So, here is how to check
    Code:
    onebit_im = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 28, 29, 30, 31, 32, 33, 34,
    35, 37, 39, 40, 41, 43, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 59,
    61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91,
    93, 95, 97, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115,
     117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147,
     149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
     181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211,
     213, 215, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230,
     231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
     247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
     263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,
     295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, 325,
     327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357,
     359, 361, 363, 365, 367, 372, 374, 376, 378, 380, 382, 384, 386, 387, 388, 390,
     391, 392, 394, 395, 396, 398, 407, 408, 410, 412, 413, 414, 416, 417, 418, 420,
     429, 430, 432, 433, 435, 437, 438, 440, 442, 444, 446, 447, 448, 449, 450, 451,
     453, 454, 455, 457, 458, 459, 461, 462, 463, 465, 467, 469, 471, 472, 473, 475,
     477, 479, 480, 481, 482, 483, 498, 500, 502]
    
    from appuifw import *
    import icon_image, e32
    
    app.body = c = Canvas()
    for i in onebit_im:
       c.blit(icon_image.open(idx=i))
       e32.ao_sleep(1)
       c.clear()
    Last edited by korakotc; 2005-07-03 at 00:37.

  5. #5
    Super Contributor
    Join Date
    Dec 2004
    Posts
    643
    Tip: your code will be easier to read if you post it inside a code-tag like this:
    Code:
    for foo in bar:
      print foo

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    16
    Hi Korakotc,

    thanks for your steady flow of cool code/ideas! It helps me a lot to get started. I also very much appreciate your website (esp. the rss-feed), it's great!

    I'm also going to use this one here...

    Thanks,

    Joost

  7. #7
    Registered User
    Join Date
    Feb 2005
    Location
    Belgium (Europe)
    Posts
    1,352

    Re: Using Icon as Image

    hello Korakot ,

    I added info method for giving infos on bitmap in mbm

    Code:
    def info(file_mbm='z:\\system\\data\\avkon.mbm', idx = 28):
    
        # read icon data from mbm file
        f = file(file_mbm, 'rb')
        if readL(f) != 0x10000041:
            return None  # work for mbm on ROM (z:) only
        start = readL(f, 8+4*idx)
        print '%d[%d:%d:(%d)%d'%(idx,start,start+20,start+56,start+68)
        f.seek(start+20)
        length = readL(f) - readL(f)  # pd_size - offset
        width, height = readL(f), readL(f)
        enc = readL(f, start+56)
        f.seek(start+68)
        data_encoded = f.read(length)
    
        # decode the data
        data_padded = rle_decode(data_encoded, enc)
        return (length,width, height,len(data_padded))
        # decode the data
    #    data_padded = rle_decode(data_encoded, enc)
    #    mat = bit_matrix(data_padded, width, height)
        
    
    # Decode of 8-bit RLE
    # Either to repeat-(n+1)-times or not repeat (100-n) bytes

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×