Pyglet with Pyinstaller?

759 views
Skip to first unread message

Mitchell Barton

unread,
Dec 15, 2016, 5:39:53 PM12/15/16
to pyglet-users
I've been trying to package my pyglet app into an executable with pyinstaller, but am running into problems. The error I keep on getting has to do with resources - 

Traceback (most recent call last):
  File "yep.py", line 23, in <module>
  File "pyglet/resource.py", line 529, in image
  File "pyglet/resource.py", line 458, in _alloc_image
  File "pyglet/resource.py", line 414, in file
pyglet.resource.ResourceNotFoundException: Resource "ad.jpg" was not found on the path.  Ensure that the filename has the correct captialisation.

I'm using pyglet.resource.image to load images, but this isn't working. Is this something I'm doing wrong with pyglet, or does pyinstaller simply not work with pyglet?

Chris Norman

unread,
Dec 15, 2016, 5:43:33 PM12/15/16
to pyglet...@googlegroups.com

You're probably not including the resource directory in the resulting bundle:


datas = [

    ('resources', 'resources')

]


HTH,

--
You received this message because you are subscribed to the Google Groups "pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyglet-users...@googlegroups.com.
To post to this group, send email to pyglet...@googlegroups.com.
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.

magu...@gmail.com

unread,
Dec 15, 2016, 5:52:01 PM12/15/16
to pyglet-users
Thats been a problem sometimes for myself as well, I've found it tricky to get working at times. I'll try your approach next time I compile something Chris, my own method involves  using a small global function for getting the absolute path when loading resources:
import sys
import os

box
= pyglet.image.load(resource_path('picture.png'))

def resource_path(relative_path):
   
""" Get absolute path to resource, works for dev and for PyInstaller """
   
if hasattr(sys, '_MEIPASS'):
       
return os.path.join(sys._MEIPASS, relative_path)

   
return os.path.join(os.path.abspath("."), relative_path)


Mitchell Barton

unread,
Dec 15, 2016, 6:09:31 PM12/15/16
to pyglet-users
Thanks for responding so quickly, sorry, I should have included the rest of my code in my first post. In the .spec file for pyinstaller I have tried including the images in a folder under 'added_files', that then is included under 'datas', but that could still be the problem. Here is what my code looks like for the .spec file, with 'beats' being a folder of .mp3 files and 'imgs' of jpgs - 

added_files = [
            ('beats', 'beats'),
            ('imgs', 'imgs')
]

a = Analysis(['yep.py'],
    pathex = ['/Users/mitchellbarton/workspace/freestylez'],
    binaries = None,
    datas = added_files,
)

and then in my pyglet script - 

import os, sys, pyglet
from random import shuffle
from random import randint
import subprocess

# basic app info

if getattr( sys, 'frozen', False ) :
        # running in a bundle
        print('bundle')
else :
        # running live
        print('live')

pyglet.options['audio'] = ('openal', 'silent')
window = pyglet.window.Window(width=400, height=500)
window.activate()
window.set_caption('F R E E S T Y L E Z  ( B A T T L E )')
print('worked')
pic1 = pyglet.resource.image('imgs/ad.jpg')
pic2 = pyglet.resource.image('imgs/ad-2.jpg')
pic3 = pyglet.resource.image('imgs/ad-3.jpg')
pic4 = pyglet.resource.image('imgs/ad-4.jpg')
pic5 = pyglet.resource.image('imgs/ad-5.jpg')
picz = [pic1, pic2, pic3, pic4, pic5]
shuffle(picz)

I will also try your function to get the path of the image and see if it works.

--
You received this message because you are subscribed to a topic in the Google Groups "pyglet-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyglet-users/q8diddF_uU8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pyglet-users...@googlegroups.com.

Benjamin Moran

unread,
Dec 19, 2016, 3:52:46 AM12/19/16
to pyglet-users
Hi Mitchell,

I've only tried it briefly, but I think there may be some issues with the pyglet.resource module when freezing using Pyinstaller. It does work, however, if you just copy your /images folder alongside your executable.

By the way, it looks like you're using the resource module incorrectly. It should be something like this:
# add a folder to the resource path
pyglet
.resource.path.append("imgs")
pyglet
.resource.reindex()
From there, you can load any image in the "imgs" path without providing the subdirectory. Like so:
pic = pyglet.resource.image("ad.jpg")

Mitchell Barton

unread,
Dec 21, 2016, 1:31:23 PM12/21/16
to pyglet-users
So I was able to get working when bundled in a folder using the resource_path function! Trying to get it to work bundled as only one file though is not working. Here is my code - 

def resource_path(relative_path):
    #Get absolute path to resource, works for dev and for PyInstaller
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)

    return os.path.join(os.path.abspath("."), relative_path)

pic1 = pyglet.image.load(resource_path('imgs/ad.jpg'))
pic2 = pyglet.image.load(resource_path('imgs/ad-2.jpg'))
pic3 = pyglet.image.load(resource_path('imgs/ad-3.jpg'))
pic4 = pyglet.image.load(resource_path('imgs/ad-4.jpg'))
pic5 = pyglet.image.load(resource_path('imgs/ad-5.jpg'))

This is working perfect, but i get this error when i bundle it into one file - 

File "site-packages/pyglet/image/__init__.py", line 178, in load
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/cy/wd4tdsz11b3g4sq7m6q47sz40000gr/T/_MEIYB5FHD/imgs/ad.jpg'

Pyinstaller talks about how when bundled into one folder it will create a temporary folder (_MEIxxxxxx) but how do I specify this folder as the directory to find images?

magu...@gmail.com

unread,
Dec 21, 2016, 6:30:08 PM12/21/16
to pyglet-users
From the error it seems like its already looking there, the _MEIYB5FHD folder is the temporary folder, although did you pack the images along with the /img/ folder into the exe? If you just packed the images and not the folder then just knock off the /img/ in your load string:

pic1 = pyglet.image.load(resource_path('ad.jpg'))

I tend to wrap assets in a zip file (sans folders) when embedding in an exe, then do this:

myzipfile = zipfile.ZipFile(resource_path('data.zip'),'r')
for fileName in myzipfile.namelist():
   
if fileName == 'picture.PNG':
        myzipfile
.extract(fileName,resource_path(''))
       
self.image = pyglet.image.load(resource_path(fileName))
        os
.remove(resource_path(fileName))


Mitchell Barton

unread,
Dec 22, 2016, 11:31:12 AM12/22/16
to pyglet-users
I was able to fix it, the only reason it wasn't working was because I hadn't updated my spec file. I had been testing with packaging my script into one folder, and once that was working, I tried with one file. When I did this, it created a new spec file, and I simply just forgot to edit it. Once I added the data files into the spec file like so, it worked perfect! Thanks!

added_files = [
    ('beats', 'beats'),
    ('imgs', 'imgs')
]

a = Analysis(['yep.py'],
         pathex=['/Users/mitchell/Workspace/freestylez'],
         binaries=None,
         datas=added_files
)

Reply all
Reply to author
Forward
0 new messages