ImageDraw module (original) (raw)

The ImageDraw module provides simple 2D graphics forImage objects. You can use this module to create new images, annotate or retouch existing images, and to generate graphics on the fly for web use.

For a more advanced drawing library for PIL, see the aggdraw module.

Example: Draw a gray cross over an image

import sys from PIL import Image, ImageDraw

with Image.open("hopper.jpg") as im:

draw = ImageDraw.Draw(im)
draw.line((0, 0) + im.size, fill=128)
draw.line((0, im.size[1], im.size[0], 0), fill=128)

# write to stdout
im.save(sys.stdout, "PNG")

Concepts

Coordinates

The graphics interface uses the same coordinate system as PIL itself, with (0, 0) in the upper left corner. Any pixels drawn outside of the image bounds will be discarded.

Colors

To specify colors, you can use numbers or tuples just as you would use withPIL.Image.new(). See Colors for more information.

For palette images (mode “P”), use integers as color indexes. In 1.1.4 and later, you can also use RGB 3-tuples or color names (see below). The drawing layer will automatically assign color indexes, as long as you don’t draw with more than 256 colors.

Color names

See Color names for the color names supported by Pillow.

Alpha channel

By default, when drawing onto an existing image, the image’s pixel values are simply replaced by the new color:

im = Image.new("RGBA", (1, 1), (255, 0, 0)) d = ImageDraw.Draw(im) d.rectangle((0, 0, 1, 1), (0, 255, 0, 127)) assert im.getpixel((0, 0)) == (0, 255, 0, 127)

Alpha channel values have no effect when drawing with RGB mode

im = Image.new("RGB", (1, 1), (255, 0, 0)) d = ImageDraw.Draw(im) d.rectangle((0, 0, 1, 1), (0, 255, 0, 127)) assert im.getpixel((0, 0)) == (0, 255, 0)

If you would like to combine translucent color with an RGB image, then initialize the ImageDraw instance with the RGBA mode:

from PIL import Image, ImageDraw im = Image.new("RGB", (1, 1), (255, 0, 0)) d = ImageDraw.Draw(im, "RGBA") d.rectangle((0, 0, 1, 1), (0, 255, 0, 127)) assert im.getpixel((0, 0)) == (128, 127, 0)

If you would like to combine translucent color with an RGBA image underneath, you will need to combine multiple images:

from PIL import Image, ImageDraw im = Image.new("RGBA", (1, 1), (255, 0, 0, 255)) im2 = Image.new("RGBA", (1, 1)) d = ImageDraw.Draw(im2) d.rectangle((0, 0, 1, 1), (0, 255, 0, 127)) im.paste(im2.convert("RGB"), mask=im2) assert im.getpixel((0, 0)) == (128, 127, 0, 255)

Fonts

PIL can use bitmap fonts or OpenType/TrueType fonts.

Bitmap fonts are stored in PIL’s own format, where each font typically consists of two files, one named .pil and the other usually named .pbm. The former contains font metrics, the latter raster data.

To load a bitmap font, use the load functions in the ImageFontmodule.

To load an OpenType/TrueType font, use the truetype function in theImageFont module. Note that this function depends on third-party libraries, and may not be available in all PIL builds.

Example: Draw partial opacity text

from PIL import Image, ImageDraw, ImageFont

get an image

with Image.open("Pillow/Tests/images/hopper.png").convert("RGBA") as base:

# make a blank image for the text, initialized to transparent text color
txt = Image.new("RGBA", base.size, (255, 255, 255, 0))

# get a font
fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
# get a drawing context
d = ImageDraw.Draw(txt)

# draw text, half opacity
d.text((10, 10), "Hello", font=fnt, fill=(255, 255, 255, 128))
# draw text, full opacity
d.text((10, 60), "World", font=fnt, fill=(255, 255, 255, 255))

out = Image.alpha_composite(base, txt)

out.show()

Example: Draw multiline text

from PIL import Image, ImageDraw, ImageFont

create an image

out = Image.new("RGB", (150, 100), (255, 255, 255))

get a font

fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)

get a drawing context

d = ImageDraw.Draw(out)

draw multiline text

d.multiline_text((10, 10), "Hello\nWorld", font=fnt, fill=(0, 0, 0))

out.show()

Functions

PIL.ImageDraw.Draw(im, mode=None)[source]

Creates an object that can be used to draw in the given image.

Note that the image will be modified in place.

Parameters:

Attributes

ImageDraw.fill: bool = False

Selects whether ImageDraw.ink should be used as a fill or outline color.

ImageDraw.font

The current default font.

Can be set per instance:

from PIL import ImageDraw, ImageFont draw = ImageDraw.Draw(image) draw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

Or globally for all future ImageDraw instances:

from PIL import ImageDraw, ImageFont ImageDraw.ImageDraw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

ImageDraw.fontmode

The current font drawing mode.

Set to "1" to disable antialiasing or "L" to enable it.

ImageDraw.ink: int

The internal representation of the current default color.

Methods

ImageDraw.getfont()[source]

Get the current default font, ImageDraw.font.

If the current default font is None, it is initialized with ImageFont.load_default().

Returns:

An image font.

ImageDraw.arc(xy, start, end, fill=None, width=0)[source]

Draws an arc (a portion of a circle outline) between the start and end angles, inside the given bounding box.

Parameters:

ImageDraw.bitmap(xy, bitmap, fill=None)[source]

Draws a bitmap (mask) at the given position, using the current fill color for the non-zero portions. The bitmap should be a valid transparency mask (mode “1”) or matte (mode “L” or “RGBA”).

This is equivalent to doing image.paste(xy, color, bitmap).

To paste pixel data into an image, use thepaste() method on the image itself.

ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1)[source]

Same as arc(), but connects the end points with a straight line.

Parameters:

ImageDraw.circle(xy, radius, fill=None, outline=None, width=1)[source]

Draws a circle with a given radius centering on a point.

Added in version 10.4.0.

Parameters:

ImageDraw.ellipse(xy, fill=None, outline=None, width=1)[source]

Draws an ellipse inside the given bounding box.

Parameters:

ImageDraw.line(xy, fill=None, width=0, joint=None)[source]

Draws a line between the coordinates in the xy list. The coordinate pixels are included in the drawn line.

Parameters:

ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)[source]

Same as arc, but also draws straight lines between the end points and the center of the bounding box.

Parameters:

ImageDraw.point(xy, fill=None)[source]

Draws points (individual pixels) at the given coordinates.

Parameters:

ImageDraw.polygon(xy, fill=None, outline=None, width=1)[source]

Draws a polygon.

The polygon outline consists of straight lines between the given coordinates, plus a straight line between the last and the first coordinate. The coordinate pixels are included in the drawn polygon.

Parameters:

ImageDraw.regular_polygon(bounding_circle, n_sides, rotation=0, fill=None, outline=None, width=1)[source]

Draws a regular polygon inscribed in bounding_circle, with n_sides, and rotation of rotation degrees.

Parameters:

ImageDraw.rectangle(xy, fill=None, outline=None, width=1)[source]

Draws a rectangle.

Parameters:

ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1, corners=None)[source]

Draws a rounded rectangle.

Parameters:

Added in version 8.2.0.

ImageDraw.shape(shape, fill=None, outline=None)[source]

Warning

This method is experimental.

Draw a shape.

ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, stroke_fill=None, embedded_color=False, font_size=None)[source]

Draws the string at the given position.

Parameters:

ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, stroke_fill=None, embedded_color=False, font_size=None)[source]

Draws the string at the given position.

Parameters:

ImageDraw.textlength(text, font=None, direction=None, features=None, language=None, embedded_color=False, font_size=None)[source]

Returns length (in pixels with 1/64 precision) of given text when rendered in font with provided direction, features, and language.

This is the amount by which following text should be offset. Text bounding box may extend past the length in some fonts, e.g. when using italics or accents.

The result is returned as a float; it is a whole number if using basic layout.

Note that the sum of two lengths may not equal the length of a concatenated string due to kerning. If you need to adjust for kerning, include the following character and subtract its length.

For example, instead of

hello = draw.textlength("Hello", font) world = draw.textlength("World", font) hello_world = hello + world # not adjusted for kerning assert hello_world == draw.textlength("HelloWorld", font) # may fail

use

hello = draw.textlength("HelloW", font) - draw.textlength( "W", font ) # adjusted for kerning world = draw.textlength("World", font) hello_world = hello + world # adjusted for kerning assert hello_world == draw.textlength("HelloWorld", font) # True

or disable kerning with (requires libraqm)

hello = draw.textlength("Hello", font, features=["-kern"]) world = draw.textlength("World", font, features=["-kern"]) hello_world = hello + world # kerning is disabled, no need to adjust assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"]) # True

Added in version 8.0.0.

Parameters:

Returns:

Either width for horizontal text, or height for vertical text.

ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, embedded_color=False, font_size=None)[source]

Returns bounding box (in pixels) of given text relative to given anchor when rendered in font with provided direction, features, and language. Only supported for TrueType fonts.

Use textlength() to get the offset of following text with 1/64 pixel precision. The bounding box includes extra margins for some fonts, e.g. italics or accents.

Added in version 8.0.0.

Parameters:

Returns:

(left, top, right, bottom) bounding box

ImageDraw.multiline_textbbox(xy, text, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, embedded_color=False, font_size=None)[source]

Returns bounding box (in pixels) of given text relative to given anchor when rendered in font with provided direction, features, and language. Only supported for TrueType fonts.

Use textlength() to get the offset of following text with 1/64 pixel precision. The bounding box includes extra margins for some fonts, e.g. italics or accents.

Added in version 8.0.0.

Parameters:

Returns:

(left, top, right, bottom) bounding box

PIL.ImageDraw.getdraw(im=None, hints=None)[source]

Warning

This method is experimental.

A more advanced 2D drawing interface for PIL images, based on the WCK interface.

Parameters:

Returns:

A (drawing context, drawing resource factory) tuple.

PIL.ImageDraw.floodfill(image: Image, xy: tuple[int, int], value: float | tuple[int, ...], border: float | tuple[int, ...] | None = None, thresh: float = 0) → None[source]

Warning

This method is experimental.

Fills a bounded region with a given color.

Parameters: