Text_Blending / app.py
gaur3009's picture
Update app.py
a370ef5 verified
raw
history blame
4.28 kB
import cv2
import numpy as np
import gradio as gr
from PIL import Image, ImageDraw, ImageFont
def generate_text_image(text, style, width, height):
"""Generate an image of the input text with the selected style."""
font_path = {
"Bold": "arialbd.ttf",
"Italic": "ariali.ttf",
"Graffiti": "graffiti.ttf", # Provide custom font if needed
"Calligraphy": "calligraphy.ttf" # Provide custom font if needed
}
img = Image.new("RGBA", (width, height), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
# Dynamically calculate font size based on image dimensions
font_size = int(min(width, height) * 0.1) # Adjust text to be proportional
try:
font = ImageFont.truetype(font_path[style], size=font_size)
except:
font = ImageFont.load_default()
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]
position = ((width - text_width) // 2, (height - text_height) // 2)
draw.text(position, text, font=font, fill=(0, 0, 0, 255))
return img
def apply_displacement_map(text_img, clothing_img, strength=20):
"""Apply displacement map to blend text onto clothing."""
gray = cv2.cvtColor(clothing_img, cv2.COLOR_BGR2GRAY)
grad_x = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=5)
grad_y = cv2.Sobel(gray, cv2.CV_32F, 0, 1, ksize=5)
grad_x = cv2.normalize(grad_x, None, 0, 1, cv2.NORM_MINMAX)
grad_y = cv2.normalize(grad_y, None, 0, 1, cv2.NORM_MINMAX)
displacement_map = np.zeros_like(clothing_img, dtype=np.float32)
displacement_map[:, :, 0] = grad_x * strength
displacement_map[:, :, 1] = grad_y * strength
text_warped = cv2.remap(text_img,
displacement_map[:, :, 0].astype(np.float32),
displacement_map[:, :, 1].astype(np.float32),
interpolation=cv2.INTER_LINEAR)
return text_warped
def overlay_text_on_clothing(clothing_image, text_input, style, strength=20, alpha=0.7, photo=None, blend_alpha=0.5):
"""Blend generated text and optional photo onto the clothing image."""
clothing_img = cv2.imread(clothing_image) # Read image from file path
# Generate text image dynamically
text_img_pil = generate_text_image(text_input, style, clothing_img.shape[1], clothing_img.shape[0])
text_img = cv2.cvtColor(np.array(text_img_pil), cv2.COLOR_RGBA2BGRA)
alpha_channel = text_img[:, :, 3] / 255.0
text_img = text_img[:, :, :3]
# Apply displacement map
text_warped = apply_displacement_map(text_img, clothing_img, strength)
for c in range(3):
clothing_img[:, :, c] = (1 - alpha_channel) * clothing_img[:, :, c] + alpha_channel * text_warped[:, :, c]
# Blend optional photo if provided
if photo:
photo_img = Image.open(photo).resize((clothing_img.shape[1], clothing_img.shape[0]))
photo_img = cv2.cvtColor(np.array(photo_img), cv2.COLOR_RGBA2BGR)
clothing_img = cv2.addWeighted(clothing_img, 1 - blend_alpha, photo_img, blend_alpha, 0)
# Convert the final blended image back to a PIL Image and return
blended_img = Image.fromarray(cv2.cvtColor(clothing_img, cv2.COLOR_BGR2RGB))
return blended_img
interface = gr.Interface(
fn=overlay_text_on_clothing,
inputs=[
gr.Image(type="filepath", label="Upload Clothing Image", interactive=True),
gr.Textbox(label="Enter Text for Design"),
gr.Radio(["Bold", "Italic", "Graffiti", "Calligraphy"], label="Select Style", value="Bold"),
gr.Slider(10, 50, step=5, value=20, label="Displacement Strength"),
gr.Slider(0.1, 1.0, step=0.1, value=0.7, label="Alpha Blending"),
gr.Image(type="filepath", label="Optional Photo for Blending", interactive=True),
gr.Slider(0.0, 1.0, step=0.1, value=0.5, label="Photo Blend Alpha")
],
outputs=gr.Image(type="pil", label="Final Design"),
title="AI-Powered Clothing Text and Photo Overlay",
description="Upload a clothing image, enter a text design, and select a style to blend the text onto the clothing. Optionally blend a photo for enhanced designs.",
allow_flagging="never"
)
if __name__ == "__main__":
interface.launch()