Sie können curl
damit Teile des Bildes herunterladen. Es hängt alles davon ab, wie robust es sein muss. Ein Testfall könnte aus den ersten 500 Bytes bestehen. Scheint für eine Menge von zu arbeiten png
und jpg
dann identify
oder ähnliches zu verwenden, um die Größe zu überprüfen.
curl -o 500-peek -r0-500 "http://example.net/some-image.png"
Bearbeiten:
Es ist lange her, dass ich Bildparser geschrieben habe, aber ich habe darüber nachgedacht und einen Teil meines Gedächtnisses aufgefrischt.
Ich vermute, dass es alle Arten von Bildern sind, die Sie überprüfen möchten (aber andererseits vielleicht auch nicht). Ich werde einige der gebräuchlichsten beschreiben : PNG
, JPEG
(JFIF) und GIF
.
PNG:
Diese sind einfach, wenn es um die Extraktion von Größe geht. Ein png
Header speichert die Größe innerhalb der ersten 24 Bytes. Zuerst kommt ein fester Header:
byte value description
0 0x89 Bit-check. 0x89 has bit 7 set.
1-3 PNG The letters P,N and G
4-5 \r\n Newline check.
6 ^z MS-DOS won't print data beyond this using `print`
7 \n *nix newline.
Als nächstes kommen Brocken durch die Akte. Sie bestehen aus einem festen Feld von Länge, Typ und Prüfsumme. Zusätzlich ein optionaler Datenabschnitt mit Längengröße .
Zum Glück ist der erste Block immer ein IHDR
mit diesem Layout:
byte description
0-3 Image Width
4-7 Image Height
8 Bits per sample or per palette index
... ...
Damit haben wir, dass die Größen Byte 16-20 und 21-24 sind. Sie können die Daten durch zB hexdump sichern:
hexdump -vn29 -e '"Bit-test: " /1 "%02x" "\n" "Magic : " 3/1 "%_c" "\n" "DOS-EOL : " 2/1 "%02x" "\n" "DOS-EOF : " /1 "%02x" "\n" "NIX-EOL : " /1 "%02x" "\n" "Chunk Size: " 4/1 "%02u" "\n" "Chunk-type: " 4/1 "%_c" "\n" "Img-Width : " 4/1 "%02x" "\n" "Img-Height: " 4/1 "%02x" "\n" /1 "Depth : %u bit" "\n" /1 "Color : %u" "\n" /1 "Compr.: %u" "\n" /1 "Filter: %u" "\n" /1 "Interl: %u" "\n"' sample.png
Auf einem Big Endian / Motorola-Computer können die Größen auch direkt gedruckt werden durch:
hexdump -s16 -n8 -e '1/4 "%u" "\n"' sample.png
Bei Little Endian / Intel ist dies jedoch nicht so einfach und auch nicht sehr portabel.
Auf diese Weise könnten wir ein bash + hexdump-Skript wie folgt implementieren:
png_hex='16/1 "%02x" " " 4/1 "%02x" " " 4/1 "%02x" "\n"'
png_valid="89504e470d0a1a0a0000000d49484452"
function png_wh()
{
read -r chunk1 img_w img_h<<<$(hexdump -vn24 -e "$png_hex" "$1")
if [[ "$chunk1" != "$png_valid" ]]; then
printf "Not valid PNG: \`%s'\n" "$1" >&2
return 1
fi
printf "%10ux%-10u\t%s\n" "0x$img_w" "0x$img_h" "$1"
return 0
}
if [[ "$1" == "-v" ]]; then verbose=1; shift; fi
while [[ "$1" ]]; do png_wh "$1"; shift; done
Dies ist jedoch nicht direkt effizient. Obwohl es einen größeren Block (75-100 Bytes) erfordert, identify
ist es eher schneller. Oder schreiben Sie die Routine in z. B. C, was schneller wäre als Bibliotheksaufrufe.
JPEG:
Wenn es darum jpg
geht, ist es nicht so einfach. Es beginnt auch mit einem Signatur-Header , aber der Größenblock hat keinen festen Versatz. Nach dem Header:
byte value
0-1 ffd8 SOI (Start Of Image)
2-3 ffe0 JFIF marker
4-5 <block-size> Size of this block including this number
6-10 JFIF\0 ...
11-12 <version>
13 ...
Ein neuer Block wird durch eine Zwei-Byte-Markierung angegeben, die mit beginnt 0xff
. Derjenige, der Informationen über Dimensionen enthält, hat den Wert 0xffc0
, kann aber ziemlich viel in den Daten vergraben sein.
Mit anderen Worten, man überspringt Bytes in Blockgröße , prüft die Markierung, überspringt Bytes in Blockgröße , liest die Markierung usw., bis die richtige kommt.
Wenn gefunden, werden die Größen um jeweils zwei Bytes am Versatz 3 und 5 nach der Markierung gespeichert .
0-1 ffc0 SOF marker
2-3 <block-size> Size of this block including this number
4 <bits> Sample precision.
5-6 <Y-size> Height
7-8 <X-size> Width
9 <components> Three for color baseline, one for grayscale.
Schrieb ein einfaches C-Programm, um einige Dateien und etwa 10.000 JPG-Bilder zu überprüfen. Ungefähr 50% hatten die Größeninformationen innerhalb der ersten 500 Bytes, meistens 50% zwischen ca. 100 und 200. Das Schlimmste war rund 80.000 Bytes. Ein Bild, während wir Bilder sprechen:
GIF:
Obwohl in gif normalerweise mehrere Bilder gespeichert werden können, hat es eine in der Kopfzeile angegebene Leinwandgröße , die groß genug ist, um die Bilder aufzunehmen. Es ist so einfach wie mit PNG und erfordert sogar Fieberbytes: 10. Nach Magie und Version finden wir Größen. Beispiel aus einem 364x472-Bild:
<byte> <hex> <value>
0-2 474946 GIF Magic
3-5 383961 89a Version (87a or 89a)
6-7 6c01 364 Logical Screen Width
8-9 d801 472 Logical Screen Height
Mit anderen Worten, Sie können die ersten sechs Bytes überprüfen, um festzustellen, ob es sich um ein GIF handelt, und dann die nächsten vier für Größen lesen.
Andere Formate:
Hätte weitergehen können, aber ich schätze, ich höre hier vorerst auf.