Caption-Anything / image_editing_utils.py
ttengwang
fix bugs of example images and api keys
5c74464
raw
history blame
No virus
2.26 kB
from PIL import Image, ImageDraw, ImageFont
import copy
import numpy as np
def wrap_text(text, font, max_width):
lines = []
words = text.split(' ')
current_line = ''
for word in words:
if font.getsize(current_line + word)[0] <= max_width:
current_line += word + ' '
else:
lines.append(current_line)
current_line = word + ' '
lines.append(current_line)
return lines
def create_bubble_frame(image, text, point, font_path='DejaVuSansCondensed-Bold.ttf', font_size_ratio=0.025):
# Load the image
if type(image) == np.ndarray:
image = Image.fromarray(image)
image = copy.deepcopy(image)
width, height = image.size
# Calculate max_text_width and font_size based on image dimensions and total number of characters
total_chars = len(text)
max_text_width = int(0.4 * width)
font_size = int(height * font_size_ratio)
# Load the font
font = ImageFont.truetype(font_path, font_size)
# Wrap the text to fit within the max_text_width
lines = wrap_text(text, font, max_text_width)
text_width = max([font.getsize(line)[0] for line in lines])
_, text_height = font.getsize(lines[0])
text_height = text_height * len(lines)
# Define bubble frame dimensions
padding = 10
bubble_width = text_width + 2 * padding
bubble_height = text_height + 2 * padding
# Create a new image for the bubble frame
bubble = Image.new('RGBA', (bubble_width, bubble_height), (255, 255, 255, 0))
# Draw the bubble frame on the new image
draw = ImageDraw.Draw(bubble)
# draw.rectangle([(0, 0), (bubble_width - 1, bubble_height - 1)], fill=(255, 255, 255, 0), outline=(255, 255, 255, 0), width=2)
# Draw the wrapped text line by line
y_text = padding
for line in lines:
draw.text((padding, y_text), line, font=font, fill=(255, 255, 255, 255))
y_text += font.getsize(line)[1]
# Calculate the bubble frame position
x, y = point
if x + bubble_width > width:
x = width - bubble_width
if y + bubble_height > height:
y = height - bubble_height
# Paste the bubble frame onto the image
image.paste(bubble, (x, y), bubble)
return image