Python Forum
image generation with text style
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
image generation with text style
#1
Photo 
Hi!

A respectful thank you in advance for your help

I would like to expand the functionality of my program. I want the program to recognize the opening and closing tags, and within the dialogue style block, if I insert these tags, that part and only that part should be italicized, while all other styles remain unchanged. Please help me implement this feature!


from PIL import Image, ImageDraw, ImageFont, ImageFilter, PngImagePlugin
import os

# Adding narrator style
# Adding tpng feature
# Skipping existing files based on META data
# Recognizing [NLA] & [NRA] from DOCTYPE5 OK

def create_image(text, output_path):
    # Create a new image with a black background
    img = Image.new('RGB', (512, 448), color=(0, 0, 0))
    draw = ImageDraw.Draw(img)
    
    # Set up fonts and sizes
    regular_font = ImageFont.truetype("arial.ttf", 14, encoding="unic")
    italic_font = ImageFont.truetype("ariali.ttf", 14, encoding="unic")
    title_font = ImageFont.truetype("arial.ttf", 24, encoding="unic")
    centered_font = ImageFont.truetype("arial.ttf", 14, encoding="unic")
    white_bg_font = ImageFont.truetype("arial.ttf", 26, encoding="unic")
    blue_center_font = ImageFont.truetype("arial.ttf", 24, encoding="unic")
    
    # Define text styles
    styles = {
        "title": {"font": title_font, "fill": (245, 245, 245)},
        "narrator": {"font": italic_font, "fill": (80, 131, 213)},
        "dialogue": {"font": regular_font, "fill": (171, 171, 171)},
        "centered": {"font": centered_font, "fill": (255, 255, 255)},
        "narratorc": {"font": italic_font, "fill": (80, 131, 213)},
        "white_bg": {"font": white_bg_font, "fill": (255, 255, 255)},
        "blue_center": {"font": blue_center_font, "fill": (5, 20, 220)}
    }
    
    # Set line spacing and extra spacing for different styles
    line_spacing = {
        "title": 15,
        "narrator": 6,
        "dialogue": 6,
        "centered": 6,
        "narratorc": 6
    }
    extra_spacing = {
        "title": 0,
        "narrator": 0,
        "dialogue": 0,
        "centered": 0,
        "narratorc": 0
    }
    
    # Add text with styles
    y_position = 20
    max_width = img.width - 40

    # New variables to handle [NLA] and [NRA] codes
    show_prev = True
    show_next = True
    
    for line in text.split('\n'):
        
        if "[NLA]" in line:
            show_prev = False
        
        if "[NRA]" in line:
            show_next = False
        
        if line.startswith("+"):
            y_position += extra_spacing["dialogue"]
            line = line[1:].strip()
        
        if line.startswith("[title]"):
            style = styles["title"]
            line = line.replace("[title]", "")
            position = (img.width // 2 - draw.textbbox((0, 0), line, font=style["font"])[2] // 2, y_position)
            
            # Add white background text with larger blur effect
            draw.text((position[0], position[1]), line, font=styles["white_bg"]["font"], fill=styles["white_bg"]["fill"])
            img_blur_white = img.filter(ImageFilter.GaussianBlur(radius=15))
            img.paste(img_blur_white)            
            # Add light blue centered text with medium blur effect
            draw.text((position[0], position[1]), line, font=styles["blue_center"]["font"], fill=styles["blue_center"]["fill"])
            img_blur_blue = img.filter(ImageFilter.GaussianBlur(radius=5))
            img.paste(img_blur_blue)
            
            # Add front white text
            draw.text(position, line, font=style["font"], fill=style["fill"])
            
            y_position += draw.textbbox((0, 0), line, font=style["font"])[3] + line_spacing["title"] + extra_spacing["title"]
        elif line.startswith("[narrator]"):
            style = styles["narrator"]
            line = line.replace("[narrator]", "")
            words = line.split(' ')
            current_line = ""
            for word in words:
                test_line = current_line + word + " "
                if draw.textbbox((0, 0), test_line, font=style["font"])[2] <= max_width - 40:
                    current_line = test_line
                else:
                    draw.text((50, y_position), current_line.strip(), font=style["font"], fill=style["fill"])
                    y_position += draw.textbbox((0, 0), current_line.strip(), font=style["font"])[3] + line_spacing["narrator"]
                    current_line = word + " "
            draw.text((50, y_position), current_line.strip(), font=style["font"], fill=style["fill"])
            y_position += draw.textbbox((0, 0), current_line.strip(), font=style["font"])[3] + line_spacing["narrator"] + extra_spacing["narrator"]
        elif line.startswith("[dialogue]"):
            style = styles["dialogue"]
            line = line.replace("[dialogue]", "")
            words = line.split(' ')
            current_line = ""
            for word in words:
                if word == "+":
                    y_position += extra_spacing["dialogue"]
                elif word == "/":
                    draw.text((70, y_position), current_line.strip(), font=style["font"], fill=style["fill"])
                    y_position += draw.textbbox((0, 0), current_line.strip(), font=style["font"])[3] + line_spacing["dialogue"] + extra_spacing["dialogue"]
                    current_line = ""
                else:
                    test_line = current_line + word + " "
                    if draw.textbbox((0, 0), test_line, font=style["font"])[2] <= max_width - 40:
                        current_line = test_line
                    else:
                        draw.text((70, y_position), current_line.strip(), font=style["font"], fill=style["fill"])
                        y_position += draw.textbbox((0, 0), current_line.strip(), font=style["font"])[3] + line_spacing["dialogue"]
                        current_line = word + " "
            draw.text((70, y_position), current_line.strip(), font=style["font"], fill=style["fill"])
            y_position += draw.textbbox((0, 0), current_line.strip(), font=style["font"])[3] + line_spacing["dialogue"] + extra_spacing["dialogue"]
        elif line.startswith("[centered]"):
            y_position += extra_spacing["centered"]
            style = styles["centered"]
            line = line.replace("[centered]", "")
            position = (img.width // 2 - draw.textbbox((0, 0), line, font=style["font"])[2] // 2, y_position)
            draw.text(position, line, font=style["font"], fill=style["fill"])
            y_position += draw.textbbox((0, 0), line, font=style["font"])[3] + line_spacing["centered"] + extra_spacing["centered"]
        elif line.startswith("[narratorc]"):
            y_position += extra_spacing["narratorc"]
            style = styles["narratorc"]
            line = line.replace("[narratorc]", "")
            position = (img.width // 2 - draw.textbbox((0, 0), line, font=style["font"])[2] // 2, y_position)
            draw.text(position, line, font=style["font"], fill=style["fill"])
            y_position += draw.textbbox((0, 0), line, font=style["font"])[3] + line_spacing["narratorc"] + extra_spacing["narratorc"]
    
    # Add "Next" text and arrow
    next_text = ""  # Default value
    if show_next:
        next_text = "következő"
    next_position_text = (img.width - draw.textbbox((0, 0), next_text, font=styles["dialogue"]["font"])[2] - 70,
                          img.height - 36) # Move text down by 4 pixels
    next_position_arrow = (next_position_text[0] + draw.textbbox((0, 0), next_text,
                                                                 font=styles["dialogue"]["font"])[2] + 10,
                           img.height - 40) # Arrow position remains the same
    if show_next:
        draw.text(next_position_text, next_text, font=styles["dialogue"]["font"], fill=(255, 255, 255))

        # Check if right_arrow.png exists
        if os.path.exists("right_arrow.png"):
            right_arrow_img = Image.open("right_arrow.png")
            img.paste(right_arrow_img, next_position_arrow)
        else:
            print("right_arrow.png not found, skipping.")

    # Add "Previous" text and arrow
    prev_text = ""  # Default value
    if show_prev:
        prev_text = "előző"
    prev_position_text = (70, img.height - 36) # Move text down by 4 pixels
    prev_position_arrow = (prev_position_text[0] - 40, img.height - 40) # Arrow position remains the same
    if show_prev:
        draw.text(prev_position_text, prev_text, font=styles["dialogue"]["font"], fill=(255, 255, 255))

        # Check if left_arrow.png exists
        if os.path.exists("left_arrow.png"):
            left_arrow_img = Image.open("left_arrow.png")
            img.paste(left_arrow_img, prev_position_arrow)
        else:
            print("left_arrow.png not found, skipping.")

    # Add page number to the footer center
    page_number_text = "1"  # Default page number
    for line in text.split('\n'):
        if line.startswith("[pn]"):
            page_number_text = line.replace("[pn]", "").strip()
            break
    page_number_position = (img.width // 2 - draw.textbbox((0, 0), page_number_text, font=styles["dialogue"]["font"])[2] // 2, img.height - 40)
    draw.text(page_number_position, page_number_text, font=styles["dialogue"]["font"], fill=(255, 255, 255))

    # Embed text as metadata
    meta = PngImagePlugin.PngInfo()
    meta.add_text("Description", text)

    # Save the image
    img.save(output_path, pnginfo=meta)
def verify_image_text(image_path, original_text):
    # Open the image file
    img = Image.open(image_path)
    meta = img.info
    embedded_text = meta.get("Description", "")
    # Compare the original text with the embedded text
    return embedded_text == original_text

def process_all_tpng_files(directory):
    # Iterate through all files in the specified directory
    for filename in os.listdir(directory):
        if filename.endswith(".tpng"):
            text_file_path = os.path.join(directory, filename)
            with open(text_file_path, 'r', encoding='utf-8') as file:
                text = file.read()
            output_path = os.path.join(directory, filename.replace(".tpng", ".png"))
            if os.path.exists(output_path):
                if verify_image_text(output_path, text):
                    print(f"{output_path} already exists and the text matches, skipping.")
                    continue
                else:
                    print(f"{output_path} already exists, but the text differs, regenerating.")
            create_image(text, output_path)

# Specify the directory where the .tpng files are located
directory = "tpng/"

# Process text and output files
process_all_tpng_files(directory)

Attached Files

.py   GeneratedPNG.py (Size: 10.3 KB / Downloads: 87)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Parquet file generation woliveiras 1 654 Dec-07-2024, 02:52 AM
Last Post: deanhystad
  Print text with big font and style tomtom 6 20,605 Aug-13-2024, 07:26 AM
Last Post: yazistilleriio
  Allure Report Generation rotemz 0 1,393 Jan-24-2023, 08:30 PM
Last Post: rotemz
Question PDF generation / edit SpongeB0B 2 2,824 Jul-28-2021, 05:59 AM
Last Post: SpongeB0B
  Error when executing pytesseract to get the text from image bvdinesh 3 21,006 Oct-19-2019, 05:01 PM
Last Post: cwco00
  write image into string format into text file venkat18 2 5,397 Jun-01-2019, 06:46 AM
Last Post: venkat18
  New .txt file Generation in Python Nirmal 1 3,015 Sep-10-2018, 01:29 PM
Last Post: ichabod801
  Is there a way to detect the text font, size and color from an image in python? Maia07 2 10,349 Aug-23-2018, 01:16 PM
Last Post: Maia07

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020