bravekingzhang / text2video

半个神器👉一键文本转视频的工具
MIT License
943 stars 167 forks source link

PIL或Pillow库的10.0.0版本中被移除了textsize #3

Closed mybolide closed 6 months ago

mybolide commented 1 year ago

ImageDraw对象的textsize方法,在PIL或Pillow库的10.0.0版本中被移除了,我用textbbox方法来代替了

from PIL import Image, ImageDraw, ImageFont
import jieba

def add_text_to_image(text, image_path, text_color, background, padding=10, target_size=(640, 480), font_path="fonts/Hiragino Sans GB.ttc", font_size=16):
    # Open the image
    image = Image.open(image_path)

    # Resize the image to the target size while maintaining the aspect ratio
    image = image.resize(target_size)

    # Convert the image to RGBA mode
    image = image.convert("RGBA")

    # Create a new transparent image with the same size as the original image
    overlay = Image.new("RGBA", image.size, (0, 0, 0, 0))

    # Create a draw object for the overlay image
    draw = ImageDraw.Draw(overlay)

    # Load the font
    font = ImageFont.truetype(font_path, font_size)

    # Split the text into lines if it exceeds the available width
    lines = []

    # Split the text into individual Chinese characters
    words = [char for char in jieba.cut(text)]
    current_line = words[0]
    for word in words[1:]:
        if draw.textbbox((0, 0), current_line  + word, font=font)[2] <= target_size[0] - 2 * padding: # 修改这里
            current_line +=  word
        else:
            lines.append(current_line)
            current_line = word
    lines.append(current_line)

    # Calculate the height of the background rectangle based on the number of lines
    text_height = draw.textbbox((0, 0), lines[0], font=font)[3] # 修改这里

    if len(lines) == 1:
        box_height = text_height + padding * 2
    else:
        box_height = (text_height + padding) * len(lines) +  padding

    # Calculate the position of the background rectangle
    box_position = ((target_size[0] - draw.textbbox((0, 0), lines[0], font=font)
                    [2]) // 2 - padding, target_size[1] - box_height - padding) # 修改这里

    # Calculate the width of the background rectangle
    box_width = draw.textbbox((0, 0), lines[0], font=font)[2] + 2 * padding # 修改这里

    # Draw a rectangle with the specified background color and alpha
    draw.rectangle(
        (box_position, (box_position[0] + box_width, box_position[1] + box_height)), fill=background)

    # Calculate the starting y-position for drawing the text
    start_y = box_position[1] + padding

    # Draw the text on the overlay image
    for line in lines:
        text_width, text_height = draw.textbbox((0, 0), line, font=font)[2:] # 修改这里
        text_position = ((target_size[0] - text_width) // 2, start_y)
        print(line, text_position)
        draw.text(text_position, line, font=font, fill=text_color)
        start_y += text_height + padding

    # Paste the overlay image onto the original image using alpha composite
    image = Image.alpha_composite(image, overlay)

    # Convert the image back to RGB mode
    image = image.convert("RGB")

    # Save the resulting image
    image.save(image_path)
mrfuturman commented 6 months ago

不错,可以用

bravekingzhang commented 6 months ago

建议直接使用docker的方式部署,另外版本我整理了一下

requests
opencv-python
pydub
pyttsx3
jieba
langdetect
flask
Pillow==9.5.0
openai>=1.0.0
python-dotenv
edge-tts