Bildausgabe unvollständig

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
S0S
User
Beiträge: 50
Registriert: Samstag 9. Februar 2013, 18:59

Hallo, ich habe ein Problem mit einer Aufgabe 12 aus der python challenge (http://www.pythonchallenge.com/). Und zwar hat man da eine gfx.Datei gegeben, die aus 5 ineinandergeschachtelten Bilddateien besteht, die man auseinanderdröseln muss.

Mein Code dazu sieht folgendermaßen aus:

Code: Alles auswählen

h = open("evil2.gfx", "rb")
data = h.read()
h.close()

new_data = [[], [], [], [], []]
n = 0

for i in range(len(data)):
    if i%5 == 0:
        new_data[0].append(data[i])
    if i%5 == 1:
        new_data[1].append(data[i])
    if i%5 == 2:
        new_data[2].append(data[i])
    if i%5 == 3:
        new_data[3].append(data[i])
    if i%5 == 4:
        new_data[4].append(data[i])

endungen = ["jpg", "png", "gif", "png", "jpg"]
for j in range(5):
    b = bytearray(new_data[j])
    s = str(b)
    name = "12_"+str(j+1)+"."+str(endungen[j])
    d = open(name, "wb")
    d.write(s)
    d.close()
Das funktioniert auch soweit; es werden also 5 Bilder erzeugt, die prinzipiell auch die richtige Motive zeigen. Allerdings wird vom 4. Bild (12_4.png) nur die obere Hälfte angezeigt:
Bild
Wie es eigentlich aussehen soll, sieht man hier: http://garethrees.org/2007/05/07/python-challenge/ (Achtung, Spoiler!)

Kann sich jemand vorstellen, woran das liegen könnte? Ich habe nämlich keine Ahnung.
BlackJack

@S0S: Um mal aus dem Blog zu zitieren: „The fourth of the five files comes out broken, with a compression encoding error halfway through that scrambles the remainder. The image below shows how it looks in GraphicCoverter.“

Ob und wieviel angezeigt wird, scheint vom Programm abzuhängen mit dem man die Datei anzeigen möchte. ``display`` zeigt mir gar nichts an, Gwenview das was Du siehst, von Pillow bekomme ich beim Laden einen Fehler und beim Versuch das Bild dann anzuzeigen ``SyntaxError: broken PNG file (chunk '\x95\xee\xf7}')``, Firefox kommt beim anzeigen über die Hälfte, endet dann aber in einem hellen Balken für den Rest des Bildes, und der verlinkte Blogger wird wohl irgendetwas verwendet haben was mehr anzeigt inklusive ”Müllpixel”.
S0S
User
Beiträge: 50
Registriert: Samstag 9. Februar 2013, 18:59

Oh, das hatte ich überlesen :oops: Danke schön :-)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@SOS: Dateien öffnet man am besten in Kombination mit dem with-Statement; n wird zwar initialisiert aber nie benutzt; statt der fünf quasi identischen if-Abfragen kann man i%5 auch gleich als Index benutzen; statt Strings mit + zusammenzustückeln solltest Du .format benutzen; statt über einen Index zu iterieren gibt es in Python zip und enumerate.
S0S
User
Beiträge: 50
Registriert: Samstag 9. Februar 2013, 18:59

Danke für deine Verbesserungsvorschläge. Manches (z.B. die umständlichen if-Abfragen oder die Initialisierung von n) kam noch vom Herumprobieren, bis ich ein Programm hatte, das tat, was es sollte, manches wie das with-Statement und die str.format-Funktion kannte ich tatsächlich noch nicht.

Mein überarbeiteter Code sieht jetzt folgendermaßen aus:

Code: Alles auswählen

with open("evil2.gfx", "rb") as h:
    data = h.read()

new_data = [[], [], [], [], []]

for i,d in enumerate(data):
    new_data[i%5].append(d)

for a in range(5):
    b = bytearray(new_data[a])
    print hex(b[0]), hex(b[1]), hex(b[2]), hex(b[3]), hex(b[4]), hex(b[5]), hex(b[6]), hex(b[7])
# => 5 Dateien mit den Endungen jpg, png, gif, png, jpg (siehe https://en.wikipedia.org/wiki/Magic_number_%28programming%29#Magic_numbers_in_files)

endungen = ["jpg", "png", "gif", "png", "jpg"]
for j in range(5):
    b = bytearray(new_data[j])
    s = str(b)
    name = "12_{}.{}".format(str(j+1),str(endungen[j]))
    with open(name, "wb") as o:
        o.write(s)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@SOS: bei format ist es nicht nötig, alles in einen String umzuwandeln.

Code: Alles auswählen

with open("evil2.gfx", "rb") as h:
    data = h.read()

endungen = ["jpg", "png", "gif", "png", "jpg"]
for j, endung in enumerate(endungen):
    name = "12_{}.{}".format(j+1, endung)
    with open(name, "wb") as o:
        o.write(data[j::len(endungen)])
Antworten