Opens the provided image file detects the format from the image header using Python’s
Returns a subclass of
If the image format is unrecognised, this throws a
willow.image.UnrecognisedImageFormatError(a subclass of
A decorator for registering operations.
The operations will be automatically registered when the image class is registered.
from willow.image import Image class MyImage(Image): @Image.operation def resize(self, size): return MyImage(self.image.resize(size))
A decorator for registering a “from” converter, which is a classmethod that converts an instance of another image class into an instance of this one.
other_classesparameter specifies which classes this converter can convert from. It can be a single class or a list.
from willow.image import Image class MyImage(Image): ... @classmethod @Image.converter_from(JPEGImageFile) def open_jpeg_file(cls, image_file): return cls(image=open_jpeg(image_file.f))
It can also be applied multiple times to the same function allowing different costs to be specified for different classes:
@classmethod @Image.converter_from([JPEGImageFile, PNGImageFile]) @Image.converter_from(GIFImageFile, cost=200) def open_file(cls, image_file): ...
A decorator for registering a “to” converter, which is a method that converts this image into an instance of another class.
other_classparameter specifies which class this function converts to. An individual “to” converter can only convert to a single class.
from willow.image import Image class MyImage(Image): ... @Image.converter_to(PillowImage) def convert_to_pillow(self): image = PIL.Image() # Code to create PIL image object here return PillowImage(image)
Here’s a full list of operations provided by Willow out of the box:
Returns the size of the image as a tuple of two integers:
width, height = image.get_size()
Returns the number of frames in an animated image:
number_of_frames = image.get_frame_count()
Trueif the image has an alpha channel.
if image.has_alpha(): # Image has alpha
Trueif the image is animated.
if image.has_animation(): # Image has animation
Stretches the image to fit the specified size. Size must be a sequence of two integers:
# Resize the image to 100x100 pixels resized_image = source_image.resize((100, 100))
Cuts out the specified region of the image. The region must be a sequence of four integers (top, left, right, bottom):
# Cut out a square from the middle of the image cropped_image = source_image.resize((100, 100, 200, 200))
If the image has an alpha channel, this will add a background colour using the alpha channel as a mask. The alpha channel will be removed from the resulting image.
The background colour must be specified as a tuple of three integers with values between 0 - 255.
This operation will convert the image to RGB format, but will not do anything if there is not an alpha channel.
# Set the background colour of the image to white image = source_image.set_background_color_rgb((255, 255, 255))
Some JPEG files have orientation data in an EXIF tag that needs to be applied to the image. This method applies this orientation to the image (it is a no-op for other image formats).
This should be run before performing any other image operations.
image = image.auto_orient()
Uses OpenCV to find the most prominent corners in the image. Useful for detecting interesting features for cropping against.
Returns a list of two integer tuples containing the coordinates of each point on the image
points = image.detect_features()
Uses OpenCV’s cascade classification to detect faces in the image.
By default the
haarcascade_frontalface_alt2.xml(provided by OpenCV) cascade file is used. You can specifiy the filename to a different cascade file in the first parameter.
Returns a list of four integer tuples containing the left, top, right, bottom locations of each face detected in the image.
faces = image.detect_faces()
save_as_jpeg(file, quality=85, optimize=False)¶
Saves the image to the specified file-like object in JPEG format.
Note: If the image has an alpha channel, this operation may raise an exception or save a broken image (depending on the backend being used). To resolve this, use the
set_background_color_rgb()method to replace the alpha channel with a solid background color before saving as JPEG.
JPEGImageFilewrapping the file.
with open('out.jpg', 'wb') as f: image.save_as_jpeg(f)
Saves the image to the specified file-like object in PNG format.
PNGImageFilewrapping the file.
with open('out.png', 'wb') as f: image.save_as_png(f)
Saves the image to the specified file-like object in GIF format.
GIFImageFilewrapping the file.
with open('out.gif', 'wb') as f: image.save_as_gif(f)
save_as_webp(file, quality=80, lossless=False)¶
Saves the image to the specified file-like object in WEBP format.
WebPImageFilewrapping the file.
with open('out.webp', 'wb') as f: image.save_as_webp(f)
PIL.Imageobject for the specified image. This may be useful for reusing existing code that requires a Pillow image.
You can convert a
PIL.Imageobject back into a Willow
import PIL.Image from willow.plugins.pillow import PillowImage pillow_image = PIL.Image.open('test.jpg') image = PillowImage(pillow_image) # Now you can use any Willow operation on that image faces = image.detect_faces()
Wand.Imageobject for the specified image. This may be useful for reusing existing code that requires a Wand image.
You can convert a
Wand.Imageobject back into a Willow
from wand.image import Image from willow.plugins.wand import WandImage # wand_image is an instance of Wand.Image wand_image = Image(filename='pikachu.png') image = WandImage(wand_image) # Now you can use any Willow operation on that image faces = image.detect_faces()