Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

imghdr / python - Can't detec type of some images (image extension)

I'm downloading a lot of images from imgur.com with a Python script and since I have all the links in the format http://imgur.com/{id} I have to force download them by replacing the original url with http://i.imgur.com/{id}.gif, then saving all the images without extension. (I know that there is an Imgur's API but I can't use it since it have limitations for this kind of job)

Now after downoading images, I want to use imghdr module to determine the original extension of the image:

>>> import imghdr
>>> imghdr.what('/images/GrEdc')
'gif'

The problem is that this works with a success rate of 80%, the remaining 20% are all identified as 'None' and checking some of them I noticed that they are most likely all .jpg images.

Why imghdr can't detect the format? I'm able to open theese images with Ubuntu's default image viewer even without extension, so I don't think they are corrupted.

like image 347
Hyperion Avatar asked Dec 18 '22 17:12

Hyperion


1 Answers

Note that in 2019, this bug has not been fixed. The solution is available at the link from Paul R.

A way to overcome the problem is to monkeypatch the problem:

# Monkeypatch bug in imagehdr
from imghdr import tests

def test_jpeg1(h, f):
    """JPEG data in JFIF format"""
    if b'JFIF' in h[:23]:
        return 'jpeg'


JPEG_MARK = b'\xff\xd8\xff\xdb\x00C\x00\x08\x06\x06' \
            b'\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f'

def test_jpeg2(h, f):
    """JPEG with small header"""
    if len(h) >= 32 and 67 == h[5] and h[:32] == JPEG_MARK:
        return 'jpeg'


def test_jpeg3(h, f):
    """JPEG data in JFIF or Exif format"""
    if h[6:10] in (b'JFIF', b'Exif') or h[:2] == b'\xff\xd8':
        return 'jpeg'

tests.append(test_jpeg1)
tests.append(test_jpeg2)
tests.append(test_jpeg3)
like image 141
Simon Avatar answered Dec 21 '22 10:12

Simon