[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: Align text drawn with PIL in Python

[Text drawn with various alignments with PIL in Python]

My post Draw text with PIL in Python explained how to draw text on a PIL image. As you saw in that example, the ImageDraw object's text method can even draw multi-line text.

This post shows how you can align multi-line text.

The key is the ImageDraw class's multiline_text method. Here's that method's signature.

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)

For more detailed information, see this Read the Docs post.

This example focuses on two parameters: align and anchor.

Alignment

The align parameter determines whether the text is lined up on the left, centered, or lined up on the right. That parameter can take the values left, center, or right and is pretty easy to understand.

The anchor parameter determines how the text lines up with respect to the point xy. This value should be a two-character text anchor value that indicates how the text should be arranged vertically and horizontally.

The following list describes the horizontal anchor values:

  • l - Left. The anchor position xy is to the left of the text.
  • m - Middle. The anchor position is centered with the text.
  • r - Right. The anchor position is to the right of the text.
  • s - Baseline. This only applies to vertical text that you might use in languages such as Japanese and Chinese. With this value, the anchor point is aligned at the text's baseline, which is in the middle of the text horizontally.

The following list describes the vertical anchor values:

  • a - Ascender. The anchor is even with the text's ascender. (The ascender is the part of the letter that sticks up above the font's "mean line." For example, it's the part of the "t" and "h" characters that stick up above the "e" in "the.")
  • t - Top. The anchor is even with the top of the text. This only works for single-line text so it's not shown by this example. Its location may also depend on the specific text, so generally the "a" ascender value is better.
  • m - Middle. The anchor is centered vertically with the text.
  • s - Baseline. The anchor is aligned with the baseline of the first line of text. (This probably makes the most sense if the text is in a single line.)
  • b - Bottom. The anchor is aligned with the bottom of the text. This only works with single-line text.
  • d - Descender. The anchor is aligned with the last line's descender. (The descender is the part of the letter below the baseline. For example, the "p" in "pet" sticks down below the "et" characters.)
Note that the anchor values seem kind of backward. They determine how the anchor point is positioned with respect to the text, but normally you want to position the text with respect to the anchor point. For example, suppose you want the text vertically centered to the right of the point (x, y) as shown in the bottom left pictures at the top of this post. To do that, you need to set the anchor to lm meaning the anchor point should be to the left of the text and centered in the middle vertically.

Python Code

The heart of the example is the following draw_sample method.

def draw_sample(self, dr, font, x, y, align, anchor): radius = 3 text = f'The first line\nAnchor: {anchor}\nLine 3' dr.multiline_text((x, y), text=text, fill='blue', font=font, anchor=anchor, align=align) dr.ellipse((x - radius, y - radius, x + radius, y + radius), fill='yellow', outline='black')

This method draws a piece of sample text at a specified location with the indicated alignment and anchor. It first builds a sample string, plugging the anchor value into the string. It then calls the multiline_text method to draw the text.

The method finishes by drawing a small yellow circle at the anchor point so you can see how it relates to the text's position.

The main program just calls this method several times to draw samples in various arrangements.

Conclusion

Download the example to see additional details. Use the program to see how each anchor value positions the text. Use the radio buttons to test different align values. Feel free to modify the code to try other anchor values.

For more information about font metrics (ascenders, descenders, baselines, etc.), see the Wikipidia post Typeface.

For more details about how text anchors work, see this Read the Docs post.

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