Seite 1 von 1

PIL, GIF und Transparenz

Verfasst: Donnerstag 23. Juni 2005, 17:57
von Spacegate
Hallo,

wenn ich mit der PIL ein GIF89a öffne und dann in eine neue Datei speichere, sind Bildpunkte die zuvor vollständig transparent sind, plötzlich weiß und opak.

Hier das relevante Codefragment:

Code: Alles auswählen

import Image
im = Image.open('Test.gif')
im.save('Testkopie.gif', 'GIF')
Was mach ich falsch?

Im Handbuch zur PIL kann man unter 'save' nachlesen, daß man 'save' auch mit 'options' für den 'writer' aufrufen kann. Dann gibt es einen Verweis auf eine spätere Textstelle im Handbuch, an der die 'options' definiert sein sollen. Die referenzierte Textstelle kann ich aber beim besten Willen nicht finden.

Danke für eure Hinweise.

Edit (Leonidas): Code in Python-Tags gesetzt.

Verfasst: Freitag 24. Juni 2005, 00:14
von BlackJack
Man muss wohl das Schlüsselwort-Argument `transparency` mit dem Farbindex, der Transparent sein soll aufrufen. Den Index findet man im `Image.info` Attribut (ein Dictionary) vom geladenen Bild.

Ich peile es nicht

Verfasst: Sonntag 26. Juni 2005, 15:03
von Spacegate
Danke für Deine Antwort BlackJack.

Ich versteh es immer noch nicht: Das mit dem Schlüssel 'transparency' habe ich dank Deiner Hilfe jetzt auch gefunden oder hoffe dies zumindest. Was aber heißt 'mit dem Farbindex, der transparent sein soll, aufrufen'.

Verfasst: Montag 27. Juni 2005, 12:34
von Leonidas
Es ist so: ein einem GIF kannst du eine arbe definieren, die Transparent sein soll. Diese wird dann nicht mehr als eigentliche Farbe dargestellt, sondern als durchsichtig.

Klingt komisch, ist aber GIF.

Thanks a lot.

Verfasst: Dienstag 28. Juni 2005, 15:55
von Gast
Jetzt ist wieder alles klar auf der Andrea Doria ...

Spacegate

Das bringt mich noch zur Verzweiflung

Verfasst: Mittwoch 29. Juni 2005, 15:04
von Spacegate
Hallo,

jetzt hab ich es durchprobiert und es kommt kein transparentes Bild aus meiner Klasse Bild. Den Farbindex für die transparente Farbe zu setzen hilft entweder nix oder ich hab es falsch gemacht. Ich habe es mit der Anweisung
'bildname'.info[transparency] = 225
probiert und zwar sowohl bei laden des Bildes als auch vor den abspeichern. Außerdem habe ich es mit und ohne den Wechsel des Bildmodus von 'P' auf 'RGBA' versucht. nix hilft. Nach dem save hat das Bild die Transparenz verloren.

Der folgende Code funktioniert bis auf die Transparenz. Die Klassen Urbild und Bild sorgen in einem CGI dafür, daß Bilder, die der Client benötigt, entsprechend verkleinert und gedreht auf dem Server vorliegen. Meine Stümpereien mit dem Transparency-Attribut habe ich wieder rausgeschmissen, damit Du das nicht machen mußt, wenn Du mir zeigen willst wie es geht.

Code: Alles auswählen


import Image, os
MEDIEN = ' Pfadname'

class Urbild:

    URBILDPFAD = MEDIEN + 'Urbilder/'

    def __init__(self, urbild):
        self.bildart = '.gif'
        pfad = self.URBILDPFAD + urbild  + self.bildart
        if not os.path.exists(pfad):
            self.bildart = '.jpg'
            pfad = self.URBILDPFAD + urbild + '.jpg'
        self.bild = Image.open(pfad)


class Bild:

    BILDERSUB = 'Bilder/'
    BILDPFAD = MEDIEN + BILDERSUB

    def __init__(self, urbildname, verkleinerung, drehwinkel):
        urbild = Urbild(urbildname)
        self.bildname = urbildname + '-' + str(verkleinerung) + \
                        '-' + str(drehwinkel) + urbild.bildart
        self.pfad = self.BILDPFAD + self.bildname
        if not os.path.exists(self.pfad):
            ausdehnung = urbild.bild.size
            kleinbild = urbild.bild.resize((ausdehnung[0] - 2 * verkleinerung, \
                                            ausdehnung[1] - 2 * verkleinerung) )
            drehbild = kleinbild.rotate(drehwinkel)
            if urbild.bildart == '.gif':
                drehbild.save(self.pfad, 'GIF')
            else:
                drehbild.save(self.pfad, 'JPEG')

    def webpfad(self):
        return MEDIENPFAD + self.BILDERSUB + self.bildname

    def dateiname(self):
        return self.bildname

Edit (Leonidas): Code in Python-Tags gesetzt.

Verfasst: Sonntag 3. Juli 2005, 01:54
von Olliminatore
PIL-handbook hat geschrieben:The library reads GIF87a and GIF89a versions of the GIF file format. The library writes
run-length encoded GIF87a files.
Das normale PIL kann leider keine transparenten/komprimierten GIFs speichern.
Ich habe mal irgendwo was von Zusatz-Modulen gelesen die das können.
Ob es das (kommerzielle)PIL-Plus noch gibt weiss ich auch nicht. Ich bin zwar in der "Image-SIG mailing list" aber bekomme so gut wie nie eine Antwort :evil:.

Fredrik Lundh ist ja noch recht aktiv aber von einer :shock: 10 Jahre alten Library könnte man dann doch mehr erwarten.

[edit] Als transparente alternative gibt es nur PNG.

Verfasst: Sonntag 3. Juli 2005, 08:54
von Leonidas
Olliminatore hat geschrieben:
PIL-handbook hat geschrieben:The library reads GIF87a and GIF89a versions of the GIF file format. The library writes
run-length encoded GIF87a files.
Das normale PIL kann leider keine transparenten/komprimierten GIFs speichern.
Und RLE ist keine Komprimierung? ;)
Olliminatore hat geschrieben:Ich habe mal irgendwo was von Zusatz-Modulen gelesen die das können.
Ob es das (kommerzielle)PIL-Plus noch gibt weiss ich auch nicht. Ich bin zwar in der "Image-SIG mailing list" aber bekomme so gut wie nie eine Antwort :evil:.

Fredrik Lundh ist ja noch recht aktiv aber von einer :shock: 10 Jahre alten Library könnte man dann doch mehr erwarten.
Wenn PIL das nicht kann, warum steht dann in der Changelog von 1.1.4, das der Bug im GIF-Writer im Zusammenspiel mit Transparenzen entfernt wurde?

Verfasst: Sonntag 3. Juli 2005, 12:50
von Olliminatore
Leonidas hat geschrieben:Und RLE ist keine Komprimierung? :wink:
Ja doch, ich meinte diese 2. Komprimierung. :P
Ich habe mir mal das GifImagePlugin angesehn und das zur Komprimierung gefunden:

Code: Alles auswählen

def _save_netpbm(im, fp, filename):

    #
    # If you need real GIF compression and/or RGB quantization, you
    # can use the external NETPBM/PBMPLUS utilities.  See comments
    # below for information on how to enable this.

    import os
    file = im._dump()
    if im.mode != "RGB":
        os.system("ppmtogif %s >%s" % (file, filename))
    else:
        os.system("ppmquant 256 %s | ppmtogif >%s" % (file, filename))
    try: os.unlink(file)
    except: pass
Wenn PIL das nicht kann, warum steht dann in der Changelog von 1.1.4, das der Bug im GIF-Writer im Zusammenspiel mit Transparenzen entfernt wurde?
Ohu* Ja, ich habe hier nur das 1.3 Handbook :oops:. (war schon ziemlich spät :P)
Ich bekomme es jedenfalls auch nicht hin. :?
Im GifImagePlugin steht ja auch was von "save transparency".

Verfasst: Sonntag 3. Juli 2005, 14:03
von Olliminatore
Ich habe es nur mit einer Änderung im GifImagePlugin Zeile 268 erfolgreich geschafft.
Keine Ahnung warum "im.encoderinfo" beim speichern leer ist. (habe es mit print getestet)

Code: Alles auswählen

 >>>       transparency = im.encoderinfo["transparency"]  # old
       transparency = im.info["transparency"]  # new


Im original Code (von Denis Benoit) steht es auch so (im.info).

Wie könnte ich diese Frage (in english) am besten in der "Image-SIG mailing list" stellen, so das ich auch eine Antwort erhalte?
Ich habe nur eine 5 in Englisch (auch kein Abi).

[edit english=on] Vieleicht so!?:
Topic: GIF transparency
Hey folks,

I tried to save a GIF with transparency unsuccessfully.
Which are the options for this?
I has only success if i change the GifImagePlugin line 268 to
> transparency = im.info["transparency"]
Is that a Bug?

Vielen Dank!

Verfasst: Dienstag 5. Juli 2005, 11:06
von Spacegate
Ohne eure Hilfe würde ich jetzt total im Wald stehen. Mein Pythonprogramm mit mehreren tausend LOCs, müsste ich in den Eimer treten und wüßte gar nicht so recht warum eigentlich.
Philipp, der mir beim Entwickeln hilft, ist ein eingefleischter PHP-Fan. Er sagt eigentlich jeden Tag zu mir: "Warum denn ausgerechnet Python? Wenn man Python benutzt, steht man doch ganz alleine da!" Dank euch kann ich jetzt beweisen, daß dem nicht so ist. Ich kann mein Python weiter nutzen und muß es nicht durch was Semiprofessionelles wie PHP ersetzen.

Das mit der PIL ist allerdings ein echter Hammer. An die Mailingliste und die Emailadresse für den kostenlosen Support habe ich mich trotz mäßigen Englisch schon gewandt und keine Antwort erhalten. Da die Transparenz für mich unverzichtbar ist, werde ich nun versuchen die PIL+ zu kaufen. Falls ich das schaffe, bekommt ihr beide eine private Email von mir mit einem "Erfolgsbericht".

Spacegate

PS.: Einen Fünfer in Englisch hast Du wirklich nicht verdient, Olliminatore. Trotzdem sind in Deiner Mail Fehler. Ich versuche mal, Deinen Text zu verbessern. Aber Achtung: Ich kann auch nur Filserenglisch:
Topic: GIF transparency
Hallo folks,
I have tried to save a GIF containing transparent pixel in different attempts and had no success, since I could not figure out the right options for the save.
Is there any option ensuring transparent pixel to be saved as transparent or is there any other way to ship around this edge?
To overcome the transparency problem I have inspected the code of your GifImagePlugin. By fortunity I found that transparent pixel will be saved right, if I will change line 268 of the plugin to
> transparency = im.info["transparency"]
Will this solution work in any case?

Re: Vielen Dank!

Verfasst: Dienstag 5. Juli 2005, 11:38
von gerold
Spacegate hat geschrieben: Das mit der PIL ist allerdings ein echter Hammer.
Hi Spacegate!

Kann es sein, dass du eine zu alte PIL-Version einsetzt? Welche PIL-Version verwendest du?

Die Version bekommst du raus, wenn du in einer Python-Konsole folgende Zeilen eingibst:

Code: Alles auswählen

import Image
print Image.VERSION
mfg
Gerold
:-)

Neuer gehts nicht

Verfasst: Dienstag 5. Juli 2005, 13:15
von Spacegate
Wir nutzen hier Python 2.4 mit der passenden Version der PIL. Haben wir beim Update von Python 2.3 auf Python 2.4 frisch downgeloaded. An altbackener Software kann es also nicht liegen. Dann schon eher an unseren Programmierkünsten.
Im Übrigen hat ist der Olliminatore der Ursache des Problems bis auf den Grund nachgegangen. Er hat die Source der PIL inspiziert (siehe oben). Es ist ein Bug in der PIL, der - na sagen wir mal, ganz vielleicht nicht rein zufällig da reingerutscht ist.

Trotzdem: Herzlichen Dank für Deinen Hinweis

Re: Neuer gehts nicht

Verfasst: Dienstag 5. Juli 2005, 13:21
von gerold
Spacegate hat geschrieben: Im Übrigen hat ist der Olliminatore der Ursache des Problems bis auf den Grund nachgegangen. Er hat die Source der PIL inspiziert (siehe oben). Es ist ein Bug in der PIL, der - na sagen wir mal, ganz vielleicht nicht rein zufällig da reingerutscht ist.
Hi Spacegate!

Das hatte ich irgendwie überlesen...

mfg
Gerold
:-)

Verfasst: Dienstag 5. Juli 2005, 21:35
von BlackJack
Also ich benutze hier PIL 1.1.5 und das hat keinen Bug. Ich kann GIFs mit Transparenz speichern.

Olliminatores "Fehlerbeseitigung" ist auch keine wenn ich das richtig sehe, weil bei mir die Zeile, die er beseitigt bzw. ersetzt hat auch so drin steht. Wenn das im original so stand, dann wird das wahrscheinlich genau der Bug gewesen sein, der laut ChangeLog gefixt wurde. Olliminatore hat ihn also wieder eingebaut!

Wenn in `im.encoderinfo` nichts drinsteht, dann liegt das höchstwahrscheinlich daran, das man die Optionen beim `im.save()` nicht angegeben hat. Sonst wüsste ich nicht wieso es leer sein könnte.

Bug reengineering

Verfasst: Sonntag 10. Juli 2005, 15:29
von Spacegate
Hallo BlackJack, hallo gerold,

danke für euere Beiträge!

Vermutlich hat BlackJack recht mit seiner Bug-Theorie. Das nehm ich aber ganz pragmatisch. Wenn es mit Ollimatore rekonstruierten Bug funkt und das tut es, bin ich über eine echte Krise weg. Außerdem hat der Ollimatore die Stelle im Sourcecode lokalisiert, an der es brennt. Das ist ganz unabhängig von Bug oder nicht Bug eine echte Leistung. Ehre, wem Ehre gebührt!

Spacegate

Verfasst: Montag 11. Juli 2005, 19:50
von Olliminatore
Hallo @Spacegate,
vielen Dank :)
(auch wenn ich "noch" nicht so ein "Könner" bin).

Ja, BlackJack hat vollkommen recht. Nach seinem (noch maligen)letzten Hinweis klappt es bei mir jetzt auch.
Deshalb auch nochmal Danke BlackJack.
Man hätte ja auch einen (klärenden) Beispiel-code posten können :P, die mir (für PIL) etwas schwer zu finden (zu scheinen) sind.
(Was ich hiermit bei dieser Gelegenheit tun möchte. Der Vollständigkeit halber und um noch ein paar Unklarheiten zu eliminieren.)

Code: Alles auswählen

im.save(filename,"gif",**{"transparency":1,"optimize":1})
Richtig?
Wobei ich kein GIF optimieren konnte, die "optimze" Option scheint, (trotzdem auch) nicht richtig zu funktionieren!?!
Beim öffnen des Resultates hat sich auch mein (Grafik)Viewer mit einem Fehler terminiert.

Verfasst: Montag 11. Juli 2005, 22:44
von BlackJack
Olliminatore hat geschrieben:

Code: Alles auswählen

im.save(filename,"gif",**{"transparency":1,"optimize":1}))
Wenn man die Angaben "von Hand" macht, dann sind einfache keyword-Parameter vielleicht einfacher zu lesen:

Code: Alles auswählen

im.save(filename,"gif", transparency=1, optimize=1)
Ansonsten kann man unter Umständen die Informationen aus dem `info` Attribut einfach wiederverwenden:

Code: Alles auswählen

im.save(filename,"gif", **im.info)

Verfasst: Samstag 20. Mai 2006, 15:04
von oscar15
Ich hab aber kein modul namens Image!??!

Verfasst: Samstag 20. Mai 2006, 15:35
von Leonidas
oscar15 hat geschrieben:Ich hab aber kein modul namens Image!??!
Du musst ja auch die Python Imaging Library (PIL) installiert haben, siehe Topic ;) Die stellt eben unter anderen Image bereit