pygame on win32, image.fromstring()

T

tlviewer

hello,

The script below is a prototype for loading playing card images
from the bitmap resource in cards.dll (WinXP)

I like the idea of not keeping copies of the images
as files.

I'm able to extract the card images as files, then load
them in pygame as a surface, but I keep getting errors
when directly loading the image as string.

The call below never works, what I'm I doing wrong?
gm.image.fromstring()

I tried to use PIL too, but I can't tell yet if
pygame will accept the image string from PIL.

# begin python
import win32api as wi

import string as st
import pygame as gm
import Image as im
hnd = wi.LoadLibrary("c:/winnt/system32/cards.dll")

# this header works for 71x96x1BPP image
# must be one line
header = [ chr(0x42), chr(0x4D), chr(0xDE), chr(0x0D), chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x4A), chr(0x00), chr(0x00), chr(0x00)]

#sheader = ''.join([ chr(header[x]) for x in range(len(header))])
str = wi.LoadResource( hnd, 2, 11, 1033)
fp = open( "e:/batch/python/aceclub.bmp", "wt")

str = st.join(header,'') + str

fp.write( str)
fp.close ()

wi.FreeLibrary(hnd)
print len(str)

# gives: ValueError: String length does not equal format and resolution size
img = gm.image.fromstring(str,(71,96),"P")

#print img.mode

#fp = open("e:/batch/msdn/Bitmap_11.bmp", "rb")
obj = gm.image.load("e:/batch/python/aceclub.bmp")

print obj.get_rect()
 
G

Greg Krohn

tlviewer said:
hello,
hi

fp = open( "e:/batch/python/aceclub.bmp", "wt")

wt? Should this be wb?
# gives: ValueError: String length does not equal format and resolution size
img = gm.image.fromstring(str,(71,96),"P")

The pygame docs say "P" is for 8bit pallete indices. When I look at the
properties of aceclub.bmp, Windows says it's Bit Depth is 4. I'm not sure if
they're talking about the same thing, though. If so, you could probably use PIL
to convert the depth.

-greg
 
T

tlviewer

Greg Krohn said:
wt? Should this be wb?


The pygame docs say "P" is for 8bit pallete indices. When I look at the
properties of aceclub.bmp, Windows says it's Bit Depth is 4. I'm not sure if
they're talking about the same thing, though. If so, you could probably use PIL
to convert the depth.

Yes, that was the trouble. Based on your suggestion, I now massage the
image string with PIL, then fromstring() works!

obj =Image.open(StringIO.StringIO(str))

#obj.convert( mode='P')
# conversion is implicit, mode is 'P' already
img = gm.image.fromstring(obj.tostring(),(71,96),"P")

Next I'm going to load all 53 card resources into a list (array) of strings,
then
write it out, pickled. That should smooth out loading the game when I use
4-6 decks (Blackjack-21).

thanks for getting to my post so quickly,
tlviewer
--
 
T

tlviewer

tlviewer said:
Next I'm going to load all 53 card resources into a list (array) of
strings, then write it out, pickled. That should smooth out loading the
game when I use 4-6 decks (Blackjack-21).

# -*- coding: cp1252 -*-
"""
keywords: resource bitmap pickle
description: pickle resources from cards.dll
requires:
Pygame from www.pygame.org,
PIL from www.pythonware.com/products/pil/

WinXP out:
63 ioerror
64 ioerror
66 resource skipped
saving pickled list
closing
debugging <Surface(71x96x8 SW)> <rect(0, 0, 71, 96)>

"""

# imports
import win32api as wi
import string as st
import pygame as gm
import Image as im
import StringIO
import win32con as wc

import os, sys
import pickle as pkl

# OS independent path -- win32 only
sysroot = os.environ.get('SYSTEMROOT')

# get module handle for cards DLL
hnd = wi.LoadLibrary(sysroot + '/system32/cards.dll')

"""
Loadresource returns the card image without a header! I dumped these
header strings from ResourceHacker. There are only 2 kinds: one for the
pictures, and one for Ace+numbers.
"""
# this header works for 71x96x1BPP image
pic_header = [ chr(0x42), chr(0x4D), chr(0xDE), chr(0x0D), chr(0x00), \
chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x4A), \
chr(0x00), chr(0x00), chr(0x00)]
num_header = [ chr(0x42), chr(0x4D), chr(0xA0), chr(0x04), chr(0x00), \
chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x00), chr(0x20), \
chr(0x00), chr(0x00), chr(0x00)]


fname = 'pkl_deck.dat'
fname = os.curdir + '/' + fname
debugr=1

#init main array to hold the cards as strings
arr_cards=[]

def cards(fname):
#sheader = ''.join([ chr(header[x]) for x in range(len(header))])
if debugr!=0:
str = wi.LoadResource( hnd, 2, 1, 1033)
str = st.join(num_header,'') + str
fp = open( os.curdir + '/aceclub.bmp', "wb")
fp.write( str)
fp.close ()

for i in range(1,68):
#default header (num)
#print "fetch ", i
header = num_header
if i % 13 > 10:
header = pic_header
try:
str = wi.LoadResource( hnd, wc.RT_BITMAP, i, 1033)
except:
print "%d" % i, " resource skipped"
continue
str = st.join(header,'') + str
try:
obj = im.open(StringIO.StringIO(str))
arr_cards.insert(i,obj.tostring())
except IOError:
print "%d" % i, " ioerror"
pass

wi.FreeLibrary(hnd)
#
# pickle out the list
print "saving pickled list"
fp = open(os.curdir + '/pkl_deck.dat', "wb")
try:
pkl.dump( arr_cards, fp, 1) #binary size Win2k:312kB WinXP:445kB
except:
print "errored, but still closing file"
fp.close()
else:
print "closing"
fp.close()
#fp = open("e:/batch/msdn/Bitmap_11.bmp", "rb")

## main ##

# retrieve the deck from our pickled list, or repickle the list to file

if not os.path.exists(fname):
cards(fname)
else:
fp = open(os.curdir + '/pkl_deck.dat','rb')
val=fp.read()
print "pickled list len=",len(val)
fp.close
arr_cards=pkl.loads(val)

if debugr!=0:
img = gm.image.fromstring(arr_cards[11],(71,96),"P")
print "debugging",img, img.get_rect()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top