File size: 4,283 Bytes
07180e9
 
 
ed5e427
 
 
 
 
 
 
 
 
 
 
 
 
 
21c8827
44ba25a
ed5e427
21c8827
ed5e427
 
 
44ba25a
 
 
 
 
 
 
ed5e427
 
5d68b2f
44ba25a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5ed5e4c
21c8827
 
d3b1e9c
ed5e427
 
 
 
 
 
 
 
21c8827
ed5e427
 
 
 
 
21c8827
 
 
 
 
 
be430ca
 
 
ed5e427
 
 
07180e9
be430ca
ed5e427
 
2179a1d
21c8827
5551f75
21c8827
07180e9
ed5e427
21c8827
 
ed5e427
 
 
 
 
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
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()