4

I'm trying to get a JPEG image resource from the web into a NumPy array image representation similar to the array returned by scipy.misc.imread. Instead of saving the image to disk, as in the example below:

import requests
from scipy import misc
def load_image(url):
    res = requests.get(url) 
    if res == 200 and 'jpeg' in res.headers['content-type']: 
        with open('image.jpg', 'wb') as fp: 
            for chunk in res: 
                fp.write(chunk)
        img_arr = misc.imread('image.jpg') 
        return img_arr
    else: 
        return None

I'd like to load the image directly into memory. Is there a way to do so?

Divakar
  • 212,295
  • 18
  • 231
  • 332
Nikhil Shinday
  • 816
  • 8
  • 18

2 Answers2

7

Since you mentioned scipy.misc.imread, we could use it to hide the part of Image.open. Thus, the implementation would look like this -

from scipy import misc

res = requests.get(url)
img_arr = misc.imread(BytesIO(res.content))

Performance-wise it seems comparable to the four stages of conversion as listed in the other post.

Divakar
  • 212,295
  • 18
  • 231
  • 332
3

I found a solution that circumvents writing to disk:

from io import BytesIO
import requests
import numpy as np 
from PIL import Image
def load_image(url): 
    res = requests.get(url)
    if res == 200 and 'jpeg' in res.headers['content-type']:
        img_arr = np.array(Image.open(BytesIO(res.content)))
        return img_arr
    else: 
        return None

As far as I can tell, I'm converting between three different representations: bytes -> BytesIO -> PIL.Image -> np.array

is there a more performant way to do it?

Nikhil Shinday
  • 816
  • 8
  • 18