Spaces:
Build error
Build error
File size: 6,023 Bytes
70fb032 7bb0e7b 70fb032 7bb0e7b 70fb032 0f221db 7bb0e7b 0f221db 7bb0e7b 0f221db 70fb032 0f221db 70fb032 7bb0e7b 2023379 70fb032 7bb0e7b 70fb032 ab55629 7bb0e7b ab55629 7bb0e7b ab55629 70fb032 7bb0e7b 70fb032 2023379 70fb032 0f221db 70fb032 7bb0e7b 70fb032 7bb0e7b 70fb032 ab55629 |
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 |
import gradio as gr
import numpy as np
import PIL.Image as Image
from rembg import remove
from PIL import ImageDraw, ImageFont
import textwrap
# Function to remove background and place text behind person
def text_behind_image(input_image, text, text_color, font_size, text_opacity):
if input_image is None or text.strip() == "":
return input_image
# Convert color hex to RGB
try:
r = int(text_color[1:3], 16)
g = int(text_color[3:5], 16)
b = int(text_color[5:7], 16)
text_color_rgb = (r, g, b)
except:
text_color_rgb = (0, 0, 0) # Default to black
try:
# Open the image
img = Image.fromarray(input_image)
# Get dimensions
width, height = img.size
# Step 1: Extract the person from the image
try:
# Try to use the human segmentation model first
person_only = remove(img, model_name="u2net_human_seg")
except:
# Fallback to default model if human_seg not available
person_only = remove(img)
# Step 2: Create a mask from the person cutout
person_mask = Image.new('RGBA', (width, height), (0, 0, 0, 0))
person_mask.paste(person_only, (0, 0), person_only)
# Step 3: Extract the background (original image without the person)
# Create inverted mask (where the person is black, background is white)
inverted_mask = Image.new('L', (width, height), 255)
inverted_mask.paste(0, (0, 0), person_only)
# Extract just the background
background = img.copy()
background.putalpha(inverted_mask)
# Step 4: Create the text layer
text_layer = Image.new('RGBA', (width, height), (0, 0, 0, 0))
draw = ImageDraw.Draw(text_layer)
# Prepare the text
text = text.strip().upper()
if not text:
text = "SAMPLE TEXT"
# Set up the font size - make it larger since we're just placing it once
font_size = max(20, int(min(width, height) * (font_size / 100)))
# Try several fonts
font = None
try:
font_paths = [
"arial.ttf",
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
"/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
"/usr/share/fonts/truetype/freefont/FreeSansBold.ttf"
]
for font_path in font_paths:
try:
font = ImageFont.truetype(font_path, font_size)
break
except:
continue
except:
pass
if font is None:
font = ImageFont.load_default()
# Get text dimensions
# Try to use getbbox first for newer PIL versions
try:
text_width = font.getbbox(text)[2] - font.getbbox(text)[0]
text_height = font.getbbox(text)[3] - font.getbbox(text)[1]
except:
# Fallback for older PIL versions
try:
text_width = font.getsize(text)[0]
text_height = font.getsize(text)[1]
except:
# Second fallback - estimate size
text_width = len(text) * (font_size * 0.6)
text_height = font_size * 1.2
# Position in the upper middle section
# Divide the image into a 3x3 grid and put the text in the top-center cell
grid_width = width // 3
grid_height = height // 3
# Center horizontally in the middle third
x_center = width // 2 - text_width // 2
# Position vertically in the top third
y_top = grid_height // 2 - text_height // 2
# Draw the text with specified opacity and color
draw.text((x_center, y_top), text, font=font, fill=text_color_rgb + (int(text_opacity * 255),))
# Step 5: Composite all layers together
# First, composite the text on top of the background
background_with_text = Image.alpha_composite(background, text_layer)
# Then, composite the person on top
final_image = Image.alpha_composite(background_with_text, person_mask)
# Convert to RGB for display
return np.array(final_image.convert('RGB'))
except Exception as e:
print(f"Error processing image: {e}")
return input_image # Return original image on error
# Create Gradio interface
with gr.Blocks(title="Text Behind Image") as demo:
gr.Markdown("# Text Behind Image")
gr.Markdown("Upload an image with a person and add text behind them")
with gr.Row():
with gr.Column():
input_image = gr.Image(label="Upload Image", type="numpy")
text_input = gr.Textbox(label="Text to place behind", placeholder="Enter text here...")
with gr.Row():
text_color = gr.ColorPicker(label="Text Color", value="#000000")
font_size = gr.Slider(label="Font Size (%)", minimum=1, maximum=30, value=10, step=1)
text_opacity = gr.Slider(label="Text Opacity", minimum=0.1, maximum=1.0, value=0.8, step=0.1)
submit_btn = gr.Button("Generate", variant="primary")
with gr.Column():
output_image = gr.Image(label="Result", type="numpy")
submit_btn.click(
fn=text_behind_image,
inputs=[input_image, text_input, text_color, font_size, text_opacity],
outputs=output_image
)
gr.Markdown("## How it works")
gr.Markdown("1. Upload an image with a person")
gr.Markdown("2. Enter the text you want to place behind the person")
gr.Markdown("3. Customize text color, size, and opacity")
gr.Markdown("4. Click 'Generate' to create your image")
# Launch the app
demo.launch() |