PIL pixel

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
s0me0ne21483
User
Beiträge: 2
Registriert: Mittwoch 10. Oktober 2018, 18:04

Ich bin gerade daran einen Pixelstick im eigenbau umzusetzten und verzweifle gerade an der Umwandlung des Bildes in eine Textdatei.
Vom Prinzip her funktioniert das Skript einwandfrei, es wandelt fast alle dateien Problemlos um. Naja, fast. Bei manachen .png Dateien scheint die Rückgabe in binär zu sein, es wird anstatt von 3 bzw. 4 Werten ein enziger ausgegeben, der jeweils 1 oder 0 ist.
Die Datei ist unter Windows problemlos zu öffnen, eine beschädigung der Datei scheint mir unwahrscheinlich.

Hier ist der Teil an dem das Programm scheitert:

Code: Alles auswählen

     for pixel in pixels:
                print(pixel)
                band = pixel
                try:
                        red = band[0]
                        green = band[1]
                        blue = band[2]
                        text_file.write("{} {} {}\n".format(red,green,blue))
Diese Fehlermeldung bekomme ich (ohne try)

Code: Alles auswählen

Traceback (most recent call last):
  File "convTest.py", line 34, in <module>
    red = band[0]
TypeError: 'int' object has no attribute '__getitem__'
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@s0me0ne21483: Welche Fehlermeldung bekommst Du denn mit ``try``? Oder was passiert denn dann? Das sieht verdächtig nach einer ”Fehlerbehandlung” aus die keine ist.

Was ist denn `pixels`? Wie kommt dieser Wert zustande?

Wie geht Dein Code mit PNGs um die keine RGB(A)-Pixel enthalten? Also beispielsweise Graustufen oder Graustufen + Transparenzinformation? Und was ist in `pixels` wenn es ein Bild mit Palette ist? RGB-Werte oder Indizes in die Palette?

Was den Wertebereich angeht: Dir ist klar das der nicht nur von 0 bis 255 sondern auch nur bis 1, 3, oder 16 gehen kann, oder auch von 0 bis 65535? Wie gehst Du damit um?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
s0me0ne21483
User
Beiträge: 2
Registriert: Mittwoch 10. Oktober 2018, 18:04

Das 'try' war nur temporär in den Code eingebaut um überhaupt auslesen zu können wie sich die ausgabe ändert. Ich hatte es nur vergessen zu löschen bevor ich den code kopiert habe.
Pixels wird weiter oben zugewiesen, habe ich auch vergessen, hier der komplette Code, falls ich noch etwas vergessen haben sollte.

Code: Alles auswählen

for filename in os.listdir('.'):
   if filename.endswith(".png") or filename.endswith(".jpg"):
        text_file_name = "{}.txt".format(os.path.splitext(filename)[0])
        text_file = open(text_file_name, "w+")
        im = Image.open(filename)

        #resizing the image
        heightPercent = LED_COUNT/float(im.size[1])
        newWidth = int(float(im.size[0])*float(heightPercent))
        im = im.resize((newWidth, LED_COUNT),Image.ANTIALIAS)
        im = im.rotate(90,expand=True)

        pixels = list(im.getdata())

        for pixel in pixels:
                band = pixel
                red = band[0]
                green = band[1]
                blue = band[2]
                text_file.write("{} {} {}\n".format(red,green,blue))

        text_file.close()
Mit dem Dateiformat png habe ich mich nicht groß beschäftigt, deshalb gibt es auch keine großen Umgangsweisen für diese Fälle. Bis auf diesen einen Fall hatte ich jedoch noch keine Probleme, also es war alles im Bereich von 0-255 dargestellt.

Das ist mein erstes Python projekt, daher habe ich noch keine große Erfahrung im Umgang mit der Programmiersprache.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Da ist wohl ein Bild mit Palette dabei, das vorher nach RGB konvertiert werden muß. Textdateien mit Modus 'w+' zu öffnen ist selten sinnvoll.

Code: Alles auswählen

        im = Image.open(filename)
        im = im.convert("RGB")
        #resizing the image
        new_width = LED_COUNT * im.size[0] // im.size[1]
        im = im.resize((new_width, LED_COUNT), Image.ANTIALIAS)
        im = im.rotate(90, expand=True)
        with open(text_file_name, "w") as text_file:
            for pixel in im.getdata():
                red, green, blue = pixel[:3]
                text_file.write("{} {} {}\n".format(red, green, blue))
Antworten