Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load images larger than MAX_IMAGE_PIXELS with PIL?

I'm trying to load some images into my Jupiter Notebook but PIL.Image.open() says that the image is too large. The MAX_IMAGE_PIXEL is set in the PIL Image source code but my image is much larger. I'm wondering if there's a way around this?

The code below works for smaller images. I've looked into trying to manually set the MAX_IMAGE_PIXEL but can't seem to do so.

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

im = np.array(Image.open('data/big_image.jpg'), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1,figsize=(10,10))

# Display the image
ax.imshow(im)

plt.show()

The code above returns the following error:

---------------------------------------------------------------------------
DecompressionBombError                    Traceback (most recent call last)
<ipython-input-15-09854c1c6343> in <module>
      3 from PIL import Image
      4 
----> 5 im = np.array(Image.open('data/big_image.jpg'), dtype=np.uint8)
      6 
      7 # Create figure and axes

/opt/anaconda3/lib/python3.7/site-packages/PIL/Image.py in open(fp, mode)
   2640         return None
   2641 
-> 2642     im = _open_core(fp, filename, prefix)
   2643 
   2644     if im is None:

/opt/anaconda3/lib/python3.7/site-packages/PIL/Image.py in _open_core(fp, filename, prefix)
   2631                     fp.seek(0)
   2632                     im = factory(fp, filename)
-> 2633                     _decompression_bomb_check(im.size)
   2634                     return im
   2635             except (SyntaxError, IndexError, TypeError, struct.error):

/opt/anaconda3/lib/python3.7/site-packages/PIL/Image.py in _decompression_bomb_check(size)
   2566             "Image size (%d pixels) exceeds limit of %d pixels, "
   2567             "could be decompression bomb DOS attack." %
-> 2568             (pixels, 2 * MAX_IMAGE_PIXELS))
   2569 
   2570     if pixels > MAX_IMAGE_PIXELS:

DecompressionBombError: Image size (1435500544 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack.

Any help is appreciated!

like image 406
Austin Murphy Avatar asked May 16 '19 17:05

Austin Murphy


People also ask

How do I enlarge a photo PIL?

Simple as that. You wanna use "cv2. INTER_CUBIC" to enlarge (factor > 1) and "cv2. INTER_AREA" to make the images smaller (factor < 1).

How do I resize an image using PIL and maintain its aspect ratio?

To resize an image using PIL and maintain its aspect ratio with Python, we can open the image with Image. open . Then we calculate the new width and height to scale the image to according to the new width. And then we resize the image with the resize method and save the new image with the save method.

How do I resize a PIL image in Python?

To resize an image, you call the resize() method on it, passing in a two-integer tuple argument representing the width and height of the resized image. The function doesn't modify the used image; it instead returns another Image with the new dimensions.

How do I load an image into Python PIL?

To load the image, we simply import the image module from the pillow and call the Image. open(), passing the image filename. Instead of calling the Pillow module, we will call the PIL module as to make it backward compatible with an older module called Python Imaging Library (PIL).


1 Answers

The DecompressionBombError from Pillow is a safety feature for web services, but if you trust the source of the image then it's just an arbitrary limit. An RGB image with 1435500544 pixels has 24 bits per pixel, so it would require roughly 4.3 GB of RAM, which is far beyond the default Pillow limit of 178956970 pixels (about 0.5GB for an RGB image.)
According to their docs, you can do something like:

import numpy as np
from PIL import Image
Image.MAX_IMAGE_PIXELS = None

im = np.array(Image.open('data/big_image.jpg'), dtype=np.uint8)

And it should work. If you anticipate working with large images, a good alternative to Pillow is OpenCV. It's very fast and offers a suite of algorithms oriented around computer vision. The getting started tutorial covers image loading.

import cv2

# Load an color image as a numpy array
img = cv2.imread('messi5.jpg',1)

It's important to note that OpenCV stacks channels as Blue-Green-Red and Pillow stacks them as Red-Green-Blue, but as long as you use the OpenCV API you'll have plenty of options to convert to RGB or any other color space you want.

like image 168
Andrew F Avatar answered Nov 14 '22 22:11

Andrew F