Ahmad M.
Ahmad M.

Reputation: 524

How to get bounding box coordinates around entire text?

I am using PIL to draw an image and write text on it. After this, I want to draw and get bounding boxes coordinates [(x1, y1), (x2, y2)] for the text on the image. How can I do this ? See below:

from IPython.display import Image 
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw

# Colour Codes
colours = {"black":(0,0,0),
           "white": (255,255,255)
           }

# Image Description
canvas_width = 200
canvas_height = 200
img_center = (canvas_width/2, canvas_height/2)

# Text Description
size = 50
text = "Text"
font = fonts[2]
font = ImageFont.truetype(font, size)

# File Description
image_name = text

# Generate data:

## Create image canvas
img=Image.new("RGBA", (canvas_width,canvas_height), colours["black"])
draw = ImageDraw.Draw(img)

## Add text on canvas
draw.text(img_center, text, colours["white"], font=font, anchor="mm")

## Draw Bounding Box on Text
draw.rectangle(font.getbbox(text))
print("Text at:", font.getbbox(text))

# Display Image
draw = ImageDraw.Draw(img)
display(img)

# Save Image
# img.save(image_name+".png")
print("Image Saved as: ", image_name+".png")

Current output:

enter image description here

Upvotes: 0

Views: 6607

Answers (1)

HansHirse
HansHirse

Reputation: 18925

If you want to have the bounding box of the text w.r.t. its location in the image, you need to call getbbox on img, not font. Nevertheless, doing so will give unwanted behaviour also:

Text at:  (0, 0, 200, 200)

That's because you initialize a RGBA image without actually using the alpha channel. Thus, the alpha channel is 255 for all pixels, such that "the bounding box of the non-zero regions in the image" is just the full image. So, if there's no actual need for an alpha channel, simply initialize a RGB image.

I shortened your code and applied the stated modifications:

from PIL import Image, ImageDraw, ImageFont

# Image
canvas_width = 200
canvas_height = 200
img_center = (canvas_width/2, canvas_height/2)
img = Image.new('RGB', (canvas_width, canvas_height), (0, 0, 0))

# Drawing
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('arial.ttf', 50)
draw.text(img_center, 'Text', (255, 255, 255), font=font, anchor='mm')
draw.rectangle(img.getbbox())
draw = ImageDraw.Draw(img)

print('Text at: ', img.getbbox())

Print output:

Text at:  (52, 82, 150, 119)

Image output:

Output

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
Pillow:        8.1.0

Upvotes: 2

Related Questions