[Rod Stephens Books]
Index Books Python Examples About Rod Contact
[Mastodon] [Bluesky]
[Build Your Own Ray Tracer With Python]

[Beginning Database Design Solutions, Second Edition]

[Beginning Software Engineering, Second Edition]

[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

Title: Draw rotated text with PIL in Python

[Rotated text drawn with PIL in Python]

The idea is relatively simple, although the details are somewhat involved. Here's the general procedure.

  1. See how big the text will be
  2. Draw the text on a new image
  3. Draw the text in white on a black mask image
  4. Rotate the text and mask images
  5. Paste the rotated text onto the destination image using the mask

The following pil_rotated_text method follows this approach.

def pil_rotated_text(image, dr, cx, cy, angle, text, fill, font): # Get the bounding box. bbox = dr.textbbox((cx, cy), text, font=font) # Make the text and mask images. wid = math.ceil(bbox[2] - bbox[0] + 10) hgt = math.ceil(bbox[3] - bbox[1] + 10) text_image = Image.new('RGB', (wid, hgt), 'white') text_dr = ImageDraw.Draw(text_image) mask_image = Image.new('RGBA', (wid, hgt), (0,0,0,0)) mask_dr = ImageDraw.Draw(mask_image) # Draw the text centered on the image and mask. mid_x = wid / 2 mid_y = hgt / 2 anchor = 'mm' align = 'center' text_dr.multiline_text((mid_x, mid_y), text=text, fill=fill, font=font, anchor=anchor, align=align) mask_dr.multiline_text((mid_x, mid_y), text=text, fill='white', font=font, anchor=anchor, align=align) # Rotate the image and mask. text_image = text_image.rotate(angle, expand=True, resample=Image.Resampling.BILINEAR) mask_image = mask_image.rotate(angle, expand=True, resample=Image.Resampling.BILINEAR) # See where to paste the image. x = round(cx - text_image.width / 2) y = round(cy - text_image.height / 2) # Use the mask to paste the text onto the destination image. image.paste(text_image, (x, y), mask_image)

This code just follows the earlier general procedure, but there are a few points worth mentioning.

First, when you rotate an image, the result may take up more room horizontally and/or vertically. For example, if you rotate a 100 × 100 pixel square by 45°, the resulting image is 141.4 pixels on a side. Setting expand = True in the call to rotate allows that function to expand the result image if necessary.

Also note that this example positions the text centered at the point cx, cy). If you want to align the text differently, for example by positioning its upper left corner, you'll need to modify the code. You could probably come up with a general solution, but I'm going to leave this as it is for now.

Download the example to experiment with it and to see additional details.

© 2024 - 2025 Rocky Mountain Computer Consulting, Inc. All rights reserved.