File size: 6,460 Bytes
6b64a10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7496d06
6b64a10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7496d06
6b64a10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import gradio as gr
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import os
from PIL import Image
from gradio_client import Client, handle_file
import uuid

client = Client("ysharma/BiRefNet_for_text_writing")

def remove_background(image):
    # Convert NumPy array to PIL Image
    #image = Image.fromarray(image_array)
    # Save the image to a specific location
    filename = f"image_{uuid.uuid4()}.png"  # Generates a universally unique identifier (UUID) for the filename
    image.save(filename)

    result = client.predict(images=handle_file(filename), api_name="/image")
    return Image.open(result[0])

def superimpose(image_with_text, overlay_image):
    # Open both images as RGBA to handle transparency
    #background = image_with_text #Image.open("/content/out2.png").convert("RGBA")
    overlay_image = overlay_image.convert("RGBA")
    # Paste overlay on the background
    image_with_text.paste(overlay_image, (0, 0), overlay_image)

    # Display or save the final image
    #background.show()
    # background.save("output_image.png")
    return image_with_text


def add_text_to_image(
    input_image,
    text,
    font_size,
    color,
    opacity,
    x_position,
    y_position
):
    """
    Add text to an image with customizable properties
    """
    # Convert gradio image (numpy array) to PIL Image
    if input_image is None:
        return None
    
    image = Image.fromarray(input_image)
    # remove background 
    overlay_image = remove_background(image)

    # Create a transparent overlay for the text
    txt_overlay = Image.new('RGBA', image.size, (255, 255, 255, 0))
    draw = ImageDraw.Draw(txt_overlay)
    
    # Create a font with specified size
    try:
        font = ImageFont.truetype("DejaVuSans.ttf", int(font_size))
    except:
        # If DejaVu font is not found, try to use Arial or default
        try:
            font = ImageFont.truetype("arial.ttf", int(font_size))
        except:
            print("Using default font as system fonts not found")
            font = ImageFont.load_default()
    
    # Convert color name to RGB
    color_map = {
        'White': (255, 255, 255),
        'Black': (0, 0, 0),
        'Red': (255, 0, 0),
        'Green': (0, 255, 0),
        'Blue': (0, 0, 255),
        'Yellow': (255, 255, 0),
        'Purple': (128, 0, 128)
    }
    rgb_color = color_map.get(color, (255, 255, 255))
    
    # Get text size for positioning
    text_bbox = draw.textbbox((0, 0), text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]

    # Calculate actual x and y positions based on percentages
    actual_x = int((image.width - text_width) * (x_position / 100))
    actual_y = int((image.height - text_height) * (y_position / 100))

    # Draw the main text
    draw.text(
        (actual_x, actual_y),
        text,
        font=font,
        fill=(*rgb_color, int(opacity))
    )

    # Combine the original image with the text overlay
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    output_image = Image.alpha_composite(image, txt_overlay)
    
    # Convert back to RGB for display
    output_image = output_image.convert('RGB')

    # superimpose images
    output_image = superimpose(output_image, overlay_image)
    
    # Convert PIL image back to numpy array for Gradio
    return np.array(output_image)

# Create the Gradio interface
def create_interface():
    with gr.Blocks(title="Text on Image Editor",) as app:
        gr.Markdown("# Add Text to Image")
        gr.Markdown("Upload an image and customize text properties to add text overlay.")
        
        with gr.Row():
            with gr.Column():
                # Input components
                input_image = gr.Image(label="Upload Image", type="numpy")
                text_input = gr.Textbox(label="Enter Text", placeholder="Type your text here...")
                font_size = gr.Slider(minimum=10, maximum=800, value=400, step=10, 
                                    label="Font Size")
                color_dropdown = gr.Dropdown(
                    choices=["White", "Black", "Red", "Green", "Blue", "Yellow", "Purple"],
                    value="White",
                    label="Text Color"
                )
                opacity_slider = gr.Slider(minimum=0, maximum=255, value=255, step=1, 
                                         label="Opacity")
                x_position = gr.Slider(minimum=0, maximum=100, value=50, step=1, 
                                     label="X Position (%)")
                y_position = gr.Slider(minimum=0, maximum=100, value=50, step=1, 
                                     label="Y Position (%)")
                
            with gr.Column():
                # Output image
                output_image = gr.Image(label="Output Image")
        
        # Process button
        process_btn = gr.Button("Add Text to Image")
        
        # Connect the input components to the processing function
        process_btn.click(
            fn=add_text_to_image,
            inputs=[
                input_image,
                text_input,
                font_size,
                color_dropdown,
                opacity_slider,
                x_position,
                y_position
            ],
            outputs=output_image
        )
        
        # Add example inputs
        gr.Examples(
            examples=[
                [
                    "sample.jpg",  # Replace with actual example image path
                    "SAMPLE TEXT",
                    400,
                    "White",
                    255,
                    50,
                    50
                ]
            ],
            inputs=[
                input_image,
                text_input,
                font_size,
                color_dropdown,
                opacity_slider,
                x_position,
                y_position
            ]
        )

    return app

# Launch the app
if __name__ == "__main__":
    # Try to install required font
    try:
        import subprocess
        subprocess.run(['apt-get', 'update'])
        subprocess.run(['apt-get', 'install', '-y', 'fonts-dejavu'])
        print("Font installed successfully")
    except:
        print("Could not install font automatically. Please install DejaVu font manually.")
    
    # Create and launch the interface
    app = create_interface()
    app.launch()