Enabling JPEG support for QImage in py2exe-compiled Python scripts?
Asked Answered
C

12

10

I'm trying to use a JPEG image in a QImage object from a Python script, with PyQt4.

The script itself works perfectly, the image loads and can be manipulated and rendered and all. However, when I try to "compile" this script with py2exe, everything works but the JPEG image. Replacing it with a PNG equivalent works, but since my program downloads images from the web, they won't always be in PNG format and I can't afford converting them all with another library.

I've discovered that JPEG image support for QImage, along with other image formats, is provided by some DLLs in the \qt\plugins\imageformats directory (they're called qjpeg4.dll and qjpeg4d.dll). I think I need to use them somehow in my executable, but I don't know how. I've tried simply copying them to my exe directory, no luck. I've tried, as indicated here, to include those files as data_files in the setup.py script, but no luck (it looks like all it does is copying these files to the exe's directory, so it changes nothing from copying them manually anyway).

I'm sure there's a handful of applications out there using PyQt with JPEG images, how do they do it? It seemed like a trivial task but I'm stuck on it now.

Also, I want my app to be cross-platform (why else would I be coding in Python?), I hope I won't run into such packaging trouble (it's not the only one) when packaging for OS X or Linux. Will I?

Claritaclarity answered 20/5, 2009 at 2:33 Comment(0)
E
14

After hours of stumbling around with the same issue, I’d like to share the solution that worked for me on windows vista: using python2.6

copy the following directory into your dist directory generated by py2exe:

C:\Python26\Lib\site-packages\PyQt4\plugins\imageformats

I just dropped the imageformats directory directly into my dist directory, without any further modifications to qt.conf or anything like that. I haven’t tried it, but this may work for phonon as well.

Edieedification answered 7/12, 2009 at 17:18 Comment(1)
Some guys comment was inline in answer: I used this solution too. Its perfect work on win7 32/64, xp sp3 professional (32bit). BUT, its fail on xp sp2 (32bit), i compare xp sp3 and xp sp2 by "Process Explorer", xp sp2 missing ..\imageformats*.dll i have no idea to solved... does anybody have solution?Carabin
S
1

I'll have to confess I never managed to get the py2exe + pyqt combination quite right (and, py2exe doesn't help at all with cross-platform packaging). PyInstaller seems to be much better -- the docs at http://www.pyinstaller.org/ are old, but the svn trunk is much more recent. Some docs are in slides given at the recent Pycon Italia Tre conference -- http://www.pycon.it/static/stuff/slides/distribuire-programmi-python-con-pyinstaller.pdf -- and, the slides are in English, and contain the current maintainer's email, so they should help! (And, let's all lobby the current maintainer to update the docs...!-)

Seow answered 20/5, 2009 at 2:56 Comment(1)
No luck. I grabbed the latest SVN snapshot of PyInstaller and it was able to compile my program, but it had no JPEG support andhad none of the imageformats plugins despite the SupportedPackages page's claim that they're fully supported. But PyInstaller's way of detecting Qt's plugins dir is broken and returned an invalid path, which I fixed by creating a symlink (or "junction" as they're called on NTFS). I gave the script another try, and this time it did detect the Qt4 plugins and copied them to the exe's directory, but upon running the exe again, still no JPEG support! :(Claritaclarity
C
1

Try adding a qt.conf file to your exe's directory, to tell qt where to find binaries and plugins.

Something like the following works for the simple case, where you just dump all dll's in the same dir as the exe:

[Paths]
Prefix = .
Plugins = .

Update: Then copy your plugins-contents (the imageformat/sqldriver directories etc) to the exe dir. I don't think you can load plugin dlls from the same directory as the exe. See Qt plugin doc for details on plugon subdirectories. (Or, leave out the 'plugins = .' and copy the plugins dir to the exe dir, so you have /plugins/imageloaders/qjpeg4.dll).

Carabin answered 22/5, 2009 at 22:30 Comment(3)
Yeah, I tried that too, but still nothing :( Only PNG images load. I'm thinking I should consider converting all images with another module/library. Any suggestions as to which one I should use?Claritaclarity
How about removing the plugins line and copying the qt-plugins directory manually to the output dir (so you have <exedir>/plugins/imageloaders/qjpeg4.dll). Also, does it work if you use pyqt's qt.conf?Carabin
Oh. DevIL is commonly used by many to load images. Haven't tried it myself cause I always use larger libs.Carabin
A
1

Etienne -- Thank you for the tip. After much reading and trial-and-error, I arrived at the same conclusion: use PIL to show jpegs in a py2app-generated app.

http://www.thetoryparty.com/wp/2009/08/27/pyqt-and-py2app-seriously-i-dont-know-what-to-do-with-you-when-youre-like-this/

What I guess is that the proposed solutions for py2exe/Windows don't necessarily apply to py2app/OSX.

Aparri answered 27/8, 2009 at 21:8 Comment(0)
B
1

I'm on OSX Leopard. Let's suppose you have an application MyApp.app.

  • Put the libraries libqjpeg.dylib and libqgif.dylib in
    MyApp.app/Contents/plugins/imageformats/
  • Put this in qt.conf in MyApp.app/Contents/resources/:

    [Paths]
    Prefix = .
    Binaries = .
    

On my machine (Leopard) this works.

Boehike answered 21/9, 2009 at 19:51 Comment(0)
C
0

After trying all the above solutions in vain, I just ended up using PIL to load my images. Since I wanted to convert these images to a texture in an OpenGL Qt widget, the result was the same whether I load the image using Qt or PIL. Still, I'm baffled that such a basic thing as loading JPEGs is so complicated in a GUI library as well-known and widely used as Qt.

Claritaclarity answered 27/5, 2009 at 22:46 Comment(0)
H
0

I had the exact same problem. Fixed it using this : http://mail.python.org/pipermail/python-list/2008-June/669374.html

  1. Copy Qt plugins to the directory: $YOUR_DIST_PATH/PyQt4/plugins;
  2. Copy qt.conf to your dist directory;
  3. Edit qt.conf, change Prefix to ./PyQt4
Haimes answered 2/6, 2009 at 8:31 Comment(1)
I did try that, in vain :( I guess I'm the one doing something wrong here, but whatever, my program works... for now.Claritaclarity
T
0

on windows, suggested solutions work perfectly.

however, on osx can't make it work even with instructions here above.

question is: the libqjpeg.dylib and libqgif.dylib files are located in the /Developer/Applications/Qt/plugins/imageformats/ directory, and that if you have installed Qt itself, not just PyQt. these files do not work for me.

in PyQt distribution, i see the files libqjpeg.bundle and libqgif.bundle in /opt/local/libexec/qt4-mac/plugins/imageformats/, however these are not libraries, and btw i cannot open their contents either, even if they have the .bundle extension. using these files instead does not work either.

i am curious to know what have you done to make it work on osx. i have installed PyQt following this guide.

Tepee answered 26/9, 2009 at 13:29 Comment(0)
J
0

For me, the problem was solved just copying the "qt.conf" for the directory of the executable.

You can find the "qt.conf" in ...\PythonXX\Lib\site-packages\PyQt4\qt.conf.

Thanks for help.

Julian answered 12/1, 2010 at 12:57 Comment(1)
Hi, just one correction... The problem was solved when I copied the file "qt.conf" and the folder "imageformats". You can find the folder in "...\PythonXX\Lib\site-packages\PyQt4\plugins " :-) Thanks.Julian
D
0

Everything above failed for me until I realized that I was bundling the .exe (that is, I had the option "bundle_files" : 2 in my setup.py. I changed it to bundle_files = 2, and now it works great.

The above solutions are fine. Specifically, I just added the following line in my setup.py: data = [ ("imageformats", glob.glob("C:\Python26\Lib\site-packages\PyQt4\plugins\imageformats*.dll")) ]

(in addition to other files, of course).

Then, the image loading dlls are in MY_EXE_DIR/imageformats

I didn't need a qt.conf to make this work, though I'm sure you could use it if you want to keep your directory tree less cluttered.

Dree answered 14/12, 2010 at 20:21 Comment(0)
S
0

It is possible to use the JPEG plugin with a py2exe'd script, even using bundle_files. You need to arrange two things to get this to work properly:

  1. Copy PyQt4/plugins/imageformats to the output directory of py2exe (default: dist)

    You only have to copy the formats you actually need.

  2. When use the bundle_files option you need to execlude the Qt dll files from the zipfile using the --dll-excludes option for pyexe.

    You still have to copy the Qt DLLs to the output directory some other way (such as by using the data_files option).

Salinger answered 21/4, 2011 at 13:58 Comment(0)
T
0

Thanks for your helpful answers for the question! I have encountered same problem as you did and no solutions could help. Hopefully, I was using VCS and found that old version of my app loaded JPEG images correctly and new versions stopped doing it. I caught this bug using PySide v1.2.2.

To enable libraries loading, I used the same solution as @Macke did (i.e. added and edited qt.conf).

My qt.conf was next:

[Paths]
Binaries = .
Plugins = qtplugins

C:\Python27\Lib\site-packages\PySide\plugins directory was copied to qtplugins directory, so I had next directories:

qtplugins\accessible
qtplugins\codecs
qtplugins\graphicssystems
qtplugins\iconengines
qtplugins\imageformats

I had next code:

class NotesCalendar(QtGui.QCalendarWidget):
    note_icon = QtGui.QImage("res/16note.png")

Moving class variable NotesCalendar.note_icon to constructor solved the problem and Qt started loading its libraries correctly. Seems that class variable constructor interrupted some internal PySide stuff.

It works with no problems on Windows. Specifying correct qt.conf and copying plugins directory is enough to enable JPEG support in py2exe + PySide build. Of course, you must have no problems in your own code.

I hope this will save someone a day! ;)

Therrien answered 5/10, 2016 at 23:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.