Angled Text#
Angled Text for all angles#
The text is advances in an anticlockwise direction when it is rotated.
Angled Text Properties#
Pil has no built-in option to create text at an angle, however it does have other modules that can produce the desired effect. The method is based on that provided by stenci angled text
Show/Hide Angled Text Attributes
PIL text has the following properties
- xy
Top left text corner
- text
Text to be written, if it contains a newline, then it is passed onto multiline_text
- fill
Text colour
- font
ImageFont instance
- anchor
Specify alternate anchor points, used on TTF fonts.
The angled text has the following additions and changes.
- im
PIL image handle, link to the calling program
- at
anchor to text middle
- angle
text angle in degrees
- aall
integer showing whether to have all angles, default all angles 1
Create Angled Text#
Constrained Angled Text#
The text angle is restricted so that no angle produces upside down writing.
Make a function that can produce the rotated text, in essence an image of the text is created and rotated, then is pasted back into the parent image. The text image is created with an RGBA attribute set to transparent, the parent image does not need an RGBA attribute, RGB will suffice. This way a dark surround of the angled text is avoided. Remember image rotation is reckoned anticlockwise.
When the text is rotated set the expand attribute on, also set the
resample filter to BICUBIC (LANCZOS does not work with rotate). The
rotated text is
pasted directly into the parent image at coordinates given. During
rotation the box surrounding the image changes size, so determine its new
size before pasting. The text image is used as its own mask for pasting.
When determining how the text sits in the parent image remember that in PIL the upper left corner of the text is used to position it. At different angles the relative position of the upper left corner and the position of the text placement shifts, according to the sector and angle. In tkinter the text uses its centre as the anchor point when positioned in the parent image. This latter method simplifies text positioning and will be used for our angled text. The necessary adjustment is not too onerous.
Show/Hide Code test_angled_text.py
from PIL import Image, ImageFont, ImageDraw
from DimLinesPIL import polar2cart
# https://stackoverflow.com/questions/245447/how-do-i-draw-text-at-an-angle-using-pythons-pil
# stenci
# text aligned middle of text
def angled_text(im, at, text, angle, font=None, fill=(0,0,0), aall=1):
if font is None:
font = ImageFont.load_default()
(wide, height) = font.getsize(text)
wide = wide + 10
image1 = Image.new('RGBA', (wide, height), (255,255,255,0))
draw1 = ImageDraw.Draw(image1)
draw1.text((0, 0), text=text, font=font, fill=fill)
# ensure angles within 0 to 360
angle = 360 + angle if angle < 0 else angle
angle = angle if angle < 360 else angle - 360
if aall == 0:
if 90 <= angle < 180:
angle = angle + 180
if 180 <= angle < 270:
angle = angle - 180
px, py = at
# rotate angle in degrees anticlockwise
image1 = image1.rotate(-angle, expand=1, resample=Image.BICUBIC)
sx, sy = image1.size
if 0 <= angle < 90:
im.paste(image1, (px-sx//2, py-sy//2, px + sx-sx//2, py + sy-sy//2), image1)
elif 90 <= angle <= 180:
im.paste(image1, (px-sx//2, py - sy+sy//2, px + sx-sx//2, py+sy//2 ), image1)
elif 180 < angle < 270:
im.paste(image1, (px-sx+sx//2, py-sy+sy//2, px+sx//2, py+sy//2 ), image1)
elif 270 <= angle < 360:
im.paste(image1, (px-sx//2, py-sy//2, px + sx-sx//2, py + sy-sy//2), image1)
#print('angle',angle,'wide,height' ,wide,height,'px,py',px,py,'sx,sy',sx,sy)
if __name__ == "__main__":
Text = "Chihuly Exhibit"
Angle = 0
Font = ImageFont.truetype('consola.ttf', 25)
tsize = Font.getsize(Text + str(0000))
w = 501
h = 501
image2 = Image.new('RGB', (w, h), (255,255,221))
pt = (200,120) #(w//2, h//2)
a = (0, 45, 90, 135, 180, 225, 270, 315)
for j in range(len(a)):
pt = polar2cart(pt, a[j], tsize[0]//2)
#print(pt)
angled_text(image2, pt, Text +' '+ str(a[j]), a[j], font=Font,
fill=(0,0,0), aall=1)
#angled_text(image2, pt, Text +' '+ str(Angle), Angle, font=Font, fill=(0,0,0))
image2.show()
#image2.save('../../temp/angled_text.png')
Todo
Multiline angled text is not yet sorted out