Reference

The Image class

class Image
classmethod open(file)

Opens the provided image file detects the format from the image header using Python’s imghdr module.

Returns a subclass of ImageFile

If the image format is unrecognised, this throws a willow.image.UnrecognisedImageFormatError (a subclass of IOError)

classmethod operation()

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))
classmethod converter_from(other_classes, cost=100)

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.

The other_classes parameter 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):
    ...
classmethod converter_to(other_class, cost=100)

A decorator for registering a “to” converter, which is a method that converts this image into an instance of another class.

The other_class parameter 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)

Builtin operations

Here’s a full list of operations provided by Willow out of the box:

get_size()

Returns the size of the image as a tuple of two integers:

width, height = image.get_size()
get_frame_count()

Returns the number of frames in an animated image:

number_of_frames = image.get_frame_count()
has_alpha()

Returns True if the image has an alpha channel.

if image.has_alpha():
    # Image has alpha
has_animation()

Returns True if the image is animated.

if image.has_animation():
    # Image has animation
resize(size)

(Pillow/Wand only)

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))
crop(region)

(Pillow/Wand only)

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))
set_background_color_rgb(color)

(Pillow/Wand only)

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))
auto_orient()

(Pillow/Wand only)

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()
detect_features()

(OpenCV only)

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()
detect_faces(cascade_filename)

(OpenCV only)

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)

(Pillow/Wand only)

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.

Returns a JPEGImageFile wrapping the file.

with open('out.jpg', 'wb') as f:
    image.save_as_jpeg(f)
save_as_png(file, optimize=False)

(Pillow/Wand only)

Saves the image to the specified file-like object in PNG format.

Returns a PNGImageFile wrapping the file.

with open('out.png', 'wb') as f:
    image.save_as_png(f)
save_as_gif(file)

(Pillow/Wand only)

Saves the image to the specified file-like object in GIF format.

returns a GIFImageFile wrapping the file.

with open('out.gif', 'wb') as f:
    image.save_as_gif(f)
get_pillow_image()

(Pillow only)

Returns a PIL.Image object for the specified image. This may be useful for reusing existing code that requires a Pillow image.

do_thing(image.get_pillow_image())

You can convert a PIL.Image object back into a Willow Image using the PillowImage class:

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()
get_wand_image()

(Wand only)

Returns a Wand.Image object for the specified image. This may be useful for reusing existing code that requires a Wand image.

do_thing(image.get_wand_image())

You can convert a Wand.Image object back into a Willow Image using the WandImage class:

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()