[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyKDE] bad resolution on designer imported PNGs: solution
From:       Hans-Peter Jansen <hpj () urpla ! net>
Date:       2002-08-01 12:15:00
[Download RAW message or body]

On Wednesday 24 July 2002 14:41, Hans-Peter Jansen wrote:
> On Wednesday 24 July 2002 11:40, Willi Richert wrote:
> > Hi,
> >
> > I have some nice PNG images which I want to use for the toolbar. But,
> > when ddesigner/pyuic generates the icons data they don't look as good any
> > more. I have to use the PNG file name instead so that they look good
> > (QPixmap("forward.png")).
> >
> > You can see the difference in the attached picture (1,2K only). The left
> > is the pyuic generated data, the right is the png given QPixmap as a file
> > path.
> >
> > Any hints?
>
> I came across this a few days before. It's releated to xpm conversion
> of semi transparent shadows in the PNG. I got the feeling, this isn't
> supported in xpm format. Please somebody correct me, if I'm wrong.
>
> I'm thinking about a tool to inline the images in a module, and load
> them via StringIO.

Done now. You can find a first shot on this attached.

img2pyqt.py:

    Inlines a list of images, and embed them in a Python
    module with appropriate code so it can be loaded into
    a PyQt program at runtime.  The benefit is that since
    it is Python source code it can be delivered as a .pyc
    or 'compiled' into the program using freeze, py2exe, etc.

    Each filename is stripped from ext and non alphanumeric characters,
    and 3 functions are created: fileData(), fileIcon() and fileIconSet().
    If file extension is not one of (png, xpm, bmp), the last two are
    ommited.

It leaves me to the question, how pixmaps are handled internally: 
if the same pixmap is used multiple times, do they share memory,
or does each instance occupy additional ram? Phil?

What would the nicest way to integrate this with Qt designer?
Anybody wrapped her/his mind around QMimeSourceFactory here?

> > willi

Enjoy,
  Hans-Peter
["img2pyqt.py" (text/x-python)]

#!/usr/bin/env python
"""
img2pyqt.py:

    Inlines a list of png images, and embed them in a Python
    module with appropriate code so it can be loaded into
    a PyQt program at runtime.  The benefit is that since
    it is Python source code it can be delivered as a .pyc
    or 'compiled' into the program using freeze, py2exe, etc.

Usage:

    img2pyqt.py [options] image_files.. python_file

Options:

    -a  This flag specifies that the python_file should be appended
        to instead of overwritten (if allowed with -o).

    -u  Don't use compression.  Leaves the data uncompressed.

    -o  Overwrite python_file, if exist

Naming:

    Each filename is stripped from ext and non alphanumeric characters,
    and 3 functions are created: fileData(), fileIcon() and fileIconSet().
    If file extension is not one of (png, xpm, bmp), the last two are
    ommited.

Copyright:

    found in wxPython/tools, which implies creator: Robin Dunn

    2002/07/31:
    adjusted to PyQt by Hans-Peter Jansen <hpj@urpla.net>
"""

import sys, os, getopt, time
import cPickle, cStringIO, zlib


def crunch_data(data, compressed):
    # pickle, crunch and convert it to a form suitable for embedding in code
    data = cPickle.dumps(data)
    if compressed:
        data = zlib.compress(data, 9)
    data = repr(data)

    # This next bit is borrowed from PIL.  It is used to wrap the text intelligently.
    fp = cStringIO.StringIO()
    data = data + " "  # buffer for the +1 test
    c = i = 0
    word = ""
    octdigits = "01234567"
    hexdigits = "0123456789abcdef"
    while i < len(data):
        if data[i] != "\\":
            word = data[i]
            i = i + 1
        else:
            if data[i+1] in octdigits:
                for n in range(2, 5):
                    if data[i+n] not in octdigits:
                        break
                word = data[i:i+n]
                i = i + n
            elif data[i+1] == 'x':
                for n in range(2, 5):
                    if data[i+n] not in hexdigits:
                        break
                word = data[i:i+n]
                i = i + n
            else:
                word = data[i:i+2]
                i = i + 2

        l = len(word)
        if c + l >= 78-1:
            fp.write("\\\n")
            c = 0
        fp.write(word)
        c = c + l

    # return the formatted compressed data
    return fp.getvalue()


def main(args):
    if not args or ("-h" in args):
        print __doc__
        return

    append = 0
    compressed = 1
    overwrite = 0
    imgName = ""

    try:
        opts, fileArgs = getopt.getopt(args, "aou")
    except getopt.GetoptError:
        print __doc__
        return

    for opt, val in opts:
        if opt == "-a":
            append = 1
        elif opt == "-o":
            overwrite = 1
        elif opt == "-u":
            compressed = 0

    if len(fileArgs) < 2:
        print __doc__
        return

    image_files = fileArgs[:-1]
    python_file = fileArgs[-1]

    if not append and not overwrite and os.path.exists(python_file):
        print "Error: not in append mode and %s exists" % python_file
        return

    out = None
    while image_files:
        fname = image_files[0]
        del image_files[0]
        f, ext = os.path.splitext(os.path.basename(fname))
        if not f[0].isalpha():
            print "Error: %s doesn't start with an alphabetic character" % f
            continue
        f = map(None, f)
        i = 0
        for c in f:
            if not c.isalnum():
                print "Warning: character <%c> was removed" % c
                del f[i]
            i += 1
        f = "".join(f)
        if not f:
            print "Error: invalid file: %s" % fname
            continue
        varName = f
        ext = ext.lower()
        if ext in ('.png', '.xpm', '.bmp'):
            datatype = "Icon"
        else:
            datatype = "Data"

        data = crunch_data(open(fname, "r").read(), compressed)

        if not out:
            if append:
                out = open(python_file, "a")
            else:
                out = open(python_file, "w")
        if not out:
            print "Error: cannot write to %s" % python_file

        out.write("#" + "-" * 70 + "\n")
        if not append:
            out.write("# This file was generated %s by %s\n#\n"
                      % (time.asctime(time.localtime()), sys.argv[0]))
            out.write("from qt import QIconSet, QPixmap\n")
            if compressed:
                out.write("import cPickle, zlib\n\n\n")
            else:
                out.write("import cPickle\n\n\n")
        append = 1

        if compressed:
            out.write("def %sData():\n\treturn cPickle.loads(zlib.decompress(\n%s))\n\n"
                      % (varName, data))
        else:
            out.write("def %sData():\n\treturn cPickle.loads(\n%s)\n\n"
                      % (varName, data))
        if datatype == "Icon":
            out.write("def %sIcon():\n\tpm = QPixmap()\n\tpm.loadFromData(%sData())\n"
                      "\treturn pm\n\n"
                      "def %sIconSet():\n\treturn QIconSet(%sIcon())\n\n"
                      % tuple([varName] * 4))

        print "Embedded %s into %s using %s" % (fname, python_file, varName)


if __name__ == "__main__":
    main(sys.argv[1:])






_______________________________________________
PyKDE mailing list    PyKDE@mats.gmd.de
http://mats.gmd.de/mailman/listinfo/pykde

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic