Seite 1 von 1

Bildausgabe unvollständig

Verfasst: Samstag 5. März 2016, 10:13
von S0S
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.

Re: Bildausgabe unvollständig

Verfasst: Samstag 5. März 2016, 11:45
von 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”.

Re: Bildausgabe unvollständig

Verfasst: Samstag 5. März 2016, 12:57
von S0S
Oh, das hatte ich überlesen :oops: Danke schön :-)

Re: Bildausgabe unvollständig

Verfasst: Samstag 5. März 2016, 18:45
von Sirius3
@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.

Re: Bildausgabe unvollständig

Verfasst: Sonntag 6. März 2016, 11:19
von S0S
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)

Re: Bildausgabe unvollständig

Verfasst: Sonntag 6. März 2016, 12:34
von Sirius3
@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)])