3

I'm playing around in python trying to download some images from imgur. I've been using the urrlib and urllib.retrieve but you need to specify the extension when saving the file. This isn't a problem for most posts since the link has for example .jpg in it, but I'm not sure what to do when the extension isn't there. My question is if there is any way to determine the image format of the file before downloading it. The question is mostly imgur specific, but I wouldn't mind a solution for most image-hosting sites.

Thanks in advance

  • 1
    Imgur has [an API](http://api.imgur.com/). You should look into that instead of scraping manually. Otherwise, there is always the [`imghdr` module](https://docs.python.org/3/library/imghdr.html). – Carsten Feb 26 '16 at 14:09
  • Ah thanks, I'll look into it! – user5977016 Feb 26 '16 at 14:26

2 Answers2

1

You can use imghdr.what(filename[, h]) in Python 2.7 and Python 3 to determine the image type.

Read here for more info, if you're using Python 2.7.

Read here for more info, if you're using Python 3.

Andriy Stolyar
  • 585
  • 9
  • 21
  • Still, it's as easy as saving to a temp file, checking the image format, and moving the file to the appropriate destination. – Carsten Feb 26 '16 at 14:41
0

Assuming the picture has no file extension, there's no way to determine which type it is before you download it. All image formats sets their initial bytes to a particular value. To inspect these 'magic' initial bytes check out https://github.com/ahupp/python-magic - it matches the initial bytes against known image formats.

The code below downloads a picture from imgur and determines which file type it is.

import magic
import requests
import shutil

r = requests.get('http://i.imgur.com/yed5Zfk.gif', stream=True)  ##Download picture
if r.status_code == 200:
    with open('~/Desktop/picture', 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)

print magic.from_file('~/Desktop/picture')  ##Determine type

## Prints: 'GIF image data, version 89a, 360 x 270'