Spaces:
Running
Running
File size: 7,596 Bytes
6b64a10 69751c5 2764dca 6b64a10 bd9441c 6b64a10 bd9441c 6b64a10 7496d06 bd9441c 6b64a10 2764dca 69751c5 6b64a10 2764dca 69751c5 2764dca 69751c5 6b64a10 38e901b 6b64a10 2764dca 6b64a10 2764dca 69751c5 6b64a10 bd9441c 6b64a10 2764dca 69751c5 3db52e5 2764dca 69751c5 3db52e5 2764dca 69751c5 3db52e5 6b64a10 2764dca 69751c5 f9b4b79 6b64a10 144ab4f |
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 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
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 add_text_with_stroke(draw, text, x, y, font, text_color, stroke_width):
"""Helper function to draw text with stroke"""
# Draw the stroke/outline
for adj_x in range(-stroke_width, stroke_width + 1):
for adj_y in range(-stroke_width, stroke_width + 1):
draw.text((x + adj_x, y + adj_y), text, font=font, fill=text_color)
def remove_background(image):
# 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)
# Call gradio client for background removal
result = client.predict(images=handle_file(filename), api_name="/image")
return Image.open(result[0])
def superimpose(image_with_text, overlay_image):
# Open image as RGBA to handle transparency
overlay_image = overlay_image.convert("RGBA")
# Paste overlay on the background
image_with_text.paste(overlay_image, (0, 0), overlay_image)
# Save the final image
# image_with_text.save("output_image.png")
return image_with_text
def add_text_to_image(
input_image,
text,
font_size,
color,
opacity,
x_position,
y_position,
thickness
):
"""
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))
# Create final color with opacity
text_color = (*rgb_color, int(opacity))
# Draw the text with stroke for thickness
add_text_with_stroke(
draw,
text,
actual_x,
actual_y,
font,
text_color,
int(thickness)
)
# 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() as app:
gr.Markdown("# Add Text Behind 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")
thickness = gr.Slider(minimum=0, maximum=20, value=0, step=1,
label="Text Thickness")
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,
thickness
],
outputs=output_image
)
# Add example inputs
gr.Examples(
examples=[
[
"pink_convertible.webp",
"EPIC",
420,
"Purple",
150,
50,
21,
9
],
[
"pear.jpg",
"PEAR",
350,
"Black",
100,
50,
2,
5
],
[
"sample_text_image.jpeg",
"LIFE",
400,
"Black",
150,
50,
2,
8
],
],
inputs=[
input_image,
text_input,
font_size,
color_dropdown,
opacity_slider,
x_position,
y_position,
thickness
],
outputs=output_image,
fn=add_text_to_image,
cache_examples=True,
)
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(ssr_mode = False) |