import numpy as np
from PIL import Image, ImageChops
Image.open¶
Opens and identifies the given image file.
Even though the method Image.open
takes a mode
argument,
it must take the value "r"
.
Notice that the method Image.open
is lazy which means that
the image file remains open and the actual image data is not read from the file until needed.
This behavior might cause issue sometimes.
For example,
let's say that you load many images using the following code
and try to combine them into one picke file for easy access.
images = [Image.open(path) for path in Path(".").glob("*.png")]
You will likely encouter an error saying "too many files opened"
because all image files are opened and not closed.
One simple way to fix this problem is to call the method Image.copy
to use the underlying image data,
which makes the underlying image file closed automatically.
images = [Image.open(path).copy() for path in Path(".").glob("*.png")]
Of course,
you can also manually call the method Image.load
to load the image data and close the image file.
def read_image(path: Path) -> Image:
img = Image.open(path)
img.load()
return img
images = [read_image(path) for path in Path(".").glob("*.png")
img = Image.open("../../home/media/poker/4h.png")
img
Load Corruppted Image¶
You will encounter "IOError: image file truncated" if an image you try to load is corrupted. However, you can still load the image (and fill the truncated part as black pixles) with the following settings. For more details, please refer to Python PIL “IOError: image file truncated” with big images .
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.fromarray¶
When loading a boolean numpy array (representing a black/white image), you can either use
mode=None
(default, auto detect the mode) ormode="L"
(gray scale). Notice that usingmode="1"
(black/white) doesn't load the numpy array correct (which sounds like a bug to me). It is worth noting that when usingmode=None
the underlying numpy array for the image is still boolean while when usingmode="L"
the underlying numpy array is float and the boolean values are converted to 0 or 255.If you every encounter the error "TypeError: Cannot handle this data type" when loading an image using
Image.fromarray
, it means that the type of elements in the array is not support and you need to manually cast the type of elments in the numpy array (tonumpy.uint8
) before callingImage.fromarray
on it. It is suggested that you always ensure the data type of a numpy array is the desired one before loading it as an image. If the data type of an numpy array is correct, you do not have to specify a mode (the default works well). Otherwise, if the data type is not correct it might not help even if you try to specify different modes. The most commonly used data types when dealing with images arenumpy.uint8
andbool
(for black/white images).:::python import numpy as np Imagee.fromarray(arr.astype(np.uint8))
NOTE: Even if
Image.fromarray
accepts amode
parameter, it seems that the modeBGR;24
doesn't work withImage.fromarray
. As an alternative way, you can manually flip a numpy array which is theBGR
representation of an image.Image.fromarray(np.flip(arr, 2))
arr = np.array(img)
Image.fromarray(arr)
img_bw = img.convert("1", dither=False)
img_bw
arr_bw = np.array(img_bw)
arr_bw
Image.fromarray(arr_bw)
np.array(Image.fromarray(arr_bw))
Image.fromarray(arr_bw, mode="L")
np.array(Image.fromarray(arr_bw, mode="L"))
Image.fromarray(arr_bw, mode="1")