In Bezug auf die Antwort von Fred the Fantastic :
Nicht jeder JPEG-Marker zwischen C0
- CF
sind SOF
Marker; Ich habe DHT ( C4
), DNL ( C8
) und DAC ( CC
) ausgeschlossen. Beachten Sie, dass ich nicht untersucht habe, ob es überhaupt möglich ist, andere Frames als C0
und C2
auf diese Weise zu analysieren . Die anderen scheinen jedoch ziemlich selten zu sein (ich persönlich bin keinem anderen als C0
und begegnet C2
).
In jedem Fall löst dies das Problem, das in den Kommentaren von Malandy mit Bangles.jpg
(DHT fälschlicherweise als SOF analysiert) erwähnt wurde.
Das andere erwähnte Problem 1431588037-WgsI3vK.jpg
besteht darin, dass imghdr
nur die Header APP0 (EXIF) und APP1 (JFIF) erkannt werden können.
Dies kann behoben werden, indem imghdr ein lockererer Test hinzugefügt wird (z. B. einfach FFD8
oder vielleicht FFD8FF
?) Oder etwas viel komplexeres (möglicherweise sogar Datenvalidierung). Bei einem komplexeren Ansatz habe ich nur Probleme gefunden mit: APP14 ( FFEE
) (Adobe); der erste Marker ist DQT ( FFDB
); und APP2 und Probleme mit eingebetteten ICC_PROFILEs .
Der überarbeitete Code unten hat den Aufruf ebenfalls imghdr.what()
geringfügig geändert :
import struct
import imghdr
def test_jpeg(h, f):
if h[0:4] == '\xff\xd8\xff\xe2' and h[6:17] == b'ICC_PROFILE':
print "A"
return 'jpeg'
if h[0:4] == '\xff\xd8\xff\xee' and h[6:11] == b'Adobe':
return 'jpeg'
if h[0:4] == '\xff\xd8\xff\xdb':
return 'jpeg'
imghdr.tests.append(test_jpeg)
def get_image_size(fname):
'''Determine the image type of fhandle and return its size.
from draco'''
with open(fname, 'rb') as fhandle:
head = fhandle.read(24)
if len(head) != 24:
return
what = imghdr.what(None, head)
if what == 'png':
check = struct.unpack('>i', head[4:8])[0]
if check != 0x0d0a1a0a:
return
width, height = struct.unpack('>ii', head[16:24])
elif what == 'gif':
width, height = struct.unpack('<HH', head[6:10])
elif what == 'jpeg':
try:
fhandle.seek(0)
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf or ftype in (0xc4, 0xc8, 0xcc):
fhandle.seek(size, 1)
byte = fhandle.read(1)
while ord(byte) == 0xff:
byte = fhandle.read(1)
ftype = ord(byte)
size = struct.unpack('>H', fhandle.read(2))[0] - 2
fhandle.seek(1, 1)
height, width = struct.unpack('>HH', fhandle.read(4))
except Exception:
return
else:
return
return width, height
Hinweis: Es wurde eine vollständige Antwort anstelle eines Kommentars erstellt, da dies noch nicht zulässig ist.