Wie extrahiere ich die Breite und Höhe eines PNG aus der Kopfzeile in Ziel c?

8

Ich muss die Dimensionen von Bildern online finden, ohne sie herunterladen zu müssen. Um dies zu erreichen, mache ich das:

%Vor%

Dies (das Herunterladen der ersten 100 Bytes) funktioniert überraschend und ich bekomme auf diese Weise die richtigen Abmessungen für PNGs.

Aber ich denke nicht, dass dies ein sehr eleganter Ansatz ist. Zuerst habe ich die ersten 100 Bytes durch einfaches Raten und Überprüfen heruntergeladen, so klein wie möglich gemacht und trotzdem funktioniert es gut.

Anscheinend in einer PNG-Datei gibt es dieses Ding, das ein IHDR in der Überschrift genannt wird, und ich muss es finden und direkt danach sind es die Breite und die Höhe. Dies gibt mir den Eindruck, dass ich die Daten durchlaufen und diesen IHDR finden und die Dimensionen erhalten sollte. Das Problem ist, wenn ich NSLog die Daten bekomme ich etwas wie folgt:

%Vor%

Ich habe keine Ahnung, wie ich mit meinem NSData-Objekt umgehen und das IHDR-Token erkennen und dann die Dinge, die danach kommen, in Zahlen umwandeln werde. Ich habe auch keine Ahnung, wenn nur 100 Bytes für eine PNG angefordert werden, die zu viel verlangt, nur um die Dimensionen zu erhalten, oder wenn sie nicht genug verlangt

    
Macmee 23.05.2013, 22:21
quelle

1 Antwort

16

Begründung

Gemäß der PNG-Spezifikation :

  

Die ersten acht Bytes einer PNG-Datei enthalten immer Folgendes   (Dezimal) Werte: 137 80 78 71 13 10 26 10

Sie müssen diese also lesen, um sicherzustellen, dass Sie wirklich eine PNG-Datei haben.

Dann,

  

Der IHDR-Chunk muss zuerst erscheinen. Es enthält:

     

Breite: 4 Bytes

     

Höhe: 4 Bytes

     

usw. ...

Entsprechend der Struktur von Chunks müssen Sie zuerst die vier Bytes lesen, die die Länge des Datenfeldes des Chunks darstellen, und dann die vier Bytes, die den Namen des Chunks darstellen , dann die zwei 32-Bit-Ganzzahlen, die Breite und Höhe darstellen, insgesamt acht Bytes.

Die genaue Mindestanzahl von Bytes, die Sie lesen müssen, um Breite und Höhe zu bestimmen, ist also 8 + 4 + 4 + 8 = 24 Bytes .

Objective-C-Code

Sobald Sie Ihr NSData-Objekt haben, müssen Sie nur auf die Bytes zugreifen, die es enthält:

%Vor%

Optional, aber ich empfehle es stark, überprüfen Sie, ob Sie tatsächlich eine PNG-Datei haben:

%Vor%

Stellen Sie sicher, dass Sie ein IHDR haben:

%Vor%

Auf die Breite und die Höhe kann als big-endian vorzeichenlose Ints mit Offset 24 minus 8 bzw. minus 4 Byte zugegriffen werden:

%Vor%

Bearbeiten : Puffer-Lesecode korrigiert: PNG speichert Ganzzahlen tatsächlich in Big-Endian.

    
SirDarius 23.05.2013, 22:41
quelle