Forum Archive

scene.load_pil_image

misha_turnbull

I am working on a chess game. I have all the images I need stored in a folder: Chess/gui_pythonista/imgs/ and a file Chess/gui_pythonista/sprites.py. In the file, I want to load the images from the images folder to something that can be used by scene.image(). Here is the code in sprites.py:

import scene
import Image
import os

folder = 'imgs'
format = 'Chess set images {} {}.jpg'
files = [os.path.join(folder, format.format(color, type))
         for type in ('pawn', 'rook', 'queen', 'king', 'bishop', 'knight')
         for color in ('black', 'white')]

img_names = {}
for file in files:
    name = os.path.split(file)[1]
    im = Image.open(file).convert('RGBA')
    im.show()
    img = scene.load_pil_image(im)
    img_names.update({name: img})

if __name__ == '__main__':
    for key in img_names:
        print key, img_names[key]

However, in the file Chess/gui_pythonista/screen_main.py file, where I from Chess.gui_pythonista.sprites import img_names, and use something like scene.image(img_names[piece_img]), all I get is a white box.

Would putting the code in sprites.py in the screen_main.py fix this?

JonB

Where are you importing img_names? I mean from within main, or from within setup() or some other part of the scene class? I seem to recall Scene classes have some odd behavior, in terms of order of code execution.

Are you sure the images are actually getting loaded correctly? Does this work properly when running sprites.py? Have you tried a print img_names from your screen_main.py.

Is there any particular reason you're using load_pil_image as opposed to load_image_file? The conversion might be doing something funny, might be worth verifying the alpha values are properly set.

ccc

As @JonB said, the trick is to load the images in or after scene.setup() otherwise you get white icons.

The following downloads the Images.zip file from GitHub, unzips the images, and shows them in a scene.Scene():

import os, requests, scene, zipfile
filename = 'Chess Images.zip'
url = 'https://raw.githubusercontent.com/671620616/Chess/master/Images.zip'
content = requests.get(url).content
with open(filename, 'w') as out_file:
        out_file.write(content)
zipfile.ZipFile(filename).extractall()
path = './Images/'
# the next line will produce white icons unless run in/after scene.setup()
#images = [scene.load_image_file(path + fn) for fn in os.listdir(path)]

class MyScene (scene.Scene):
    def __init__(self):
        scene.run(self)

    def setup(self):
        self.images = [scene.load_image_file(path + fn) for fn in os.listdir(path)]

    def draw(self):
        scene.background(0, 0, .75)
        for i, image in enumerate(self.images):
            scene.image(image, i*85, 0)

MyScene()
misha_turnbull

@JonB I import img_names in the main part of the file -- I'll shift it to be in the setup and load it into a list. Originally I had been using load_image_file but I thought I'd rule out the possibility it was that causing the problem so I switched to load_pil_image. I'm assuming load_image_file is faster and will switch back to that.

@ccc do you think it would be possible to load the images into a dictionary? I'd prefer not to use a list as that might end up needing exec or eval() neither of which are good. From the piece class itself (as youll be able to see shortly - I'm uploading the code today) I have the 'color' and 'ptype' attributres which respectivley represent the color and piece type eg. 'white' & 'pawn'. This would allow me to use a dictionary with keys like {'white_pawn': xxx, 'black_king': yyy} and I could use a loop to render the images something like:

for piece in self.game.board.pieces:
    img = self.images['{}_{}'.format(piece.color.color, piece.ptype)]
    scene.image(img, x, y)

as opposed to having to do something long and complicated with types of the piece etc.