Gertie01 commited on
Commit
e363c32
·
verified ·
1 Parent(s): 3f358c7

Deploy Gradio app with multiple files

Browse files
Files changed (3) hide show
  1. app.py +82 -0
  2. models.py +151 -0
  3. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image
3
+ from models import gemini_remix_image, gpt_remix_image
4
+
5
+ def remix_images_wrapper(image1_path: str | None, image2_path: str | None, image3_path: str | None, prompt: str) -> tuple[Image.Image, Image.Image]:
6
+ """
7
+ Wrapper function to process input paths, convert to PIL Images,
8
+ and call both mock remixing models.
9
+ """
10
+ pil_images = []
11
+ for path in [image1_path, image2_path, image3_path]:
12
+ if path is not None:
13
+ pil_images.append(Image.open(path))
14
+ else:
15
+ pil_images.append(None) # Maintain None for absent images
16
+
17
+ # Call the mock model functions
18
+ gemini_output = gemini_remix_image(pil_images[0], pil_images[1], pil_images[2], prompt)
19
+ gpt_output = gpt_remix_image(pil_images[0], pil_images[1], pil_images[2], prompt)
20
+
21
+ return gemini_output, gpt_output
22
+
23
+ with gr.Blocks(title="AI Image Remixer") as demo:
24
+ gr.Markdown(
25
+ "<div style='text-align: center; margin-bottom: 20px;'>"
26
+ "<h1>🎨 AI Image Remixer 🖼️</h1>"
27
+ "<p>Drag up to three images into the input boxes, add a text prompt, and see them remixed by different AI models!</p>"
28
+ "</div>"
29
+ )
30
+ gr.Markdown(
31
+ "<div style='text-align: center; margin-bottom: 20px;'>"
32
+ "<p>Built with <a href='https://huggingface.co/spaces/akhaliq/anycoder' target='_blank'>anycoder</a></p>"
33
+ "</div>"
34
+ )
35
+
36
+ with gr.Row():
37
+ with gr.Column(scale=1):
38
+ gr.Markdown("<h3>Input Images (Drag & Drop)</h3>")
39
+ with gr.Row():
40
+ input_image1 = gr.Image(
41
+ type="filepath", label="Image 1",
42
+ height=200, width=200,
43
+ sources=["upload", "clipboard"],
44
+ value="https://i.imgur.com/S9s4P2c.png" # Example image 1
45
+ )
46
+ input_image2 = gr.Image(
47
+ type="filepath", label="Image 2",
48
+ height=200, width=200,
49
+ sources=["upload", "clipboard"],
50
+ value="https://i.imgur.com/gK1545n.png" # Example image 2
51
+ )
52
+ input_image3 = gr.Image(
53
+ type="filepath", label="Image 3",
54
+ height=200, width=200,
55
+ sources=["upload", "clipboard"],
56
+ value="https://i.imgur.com/XqR7m0D.png" # Example image 3
57
+ )
58
+
59
+ prompt_textbox = gr.Textbox(
60
+ label="Text Prompt",
61
+ placeholder="Describe how to remix the images, e.g., 'futuristic city, vibrant colors'",
62
+ lines=2,
63
+ value="Create a magical forest scene with bioluminescent plants."
64
+ )
65
+ remix_button = gr.Button("Remix Images!")
66
+
67
+ with gr.Column(scale=2):
68
+ gr.Markdown("<h3>Remixed Outputs</h3>")
69
+ with gr.Row():
70
+ gemini_output_image = gr.Image(label="Gemini-2 Remix", height=400, show_share_button=True)
71
+ gpt_output_image = gr.Image(label="GPT Image-1 Remix", height=400, show_share_button=True)
72
+
73
+ remix_button.click(
74
+ fn=remix_images_wrapper,
75
+ inputs=[input_image1, input_image2, input_image3, prompt_textbox],
76
+ outputs=[gemini_output_image, gpt_output_image],
77
+ api_name="remix_images",
78
+ show_progress="minimal"
79
+ )
80
+
81
+ if __name__ == "__main__":
82
+ demo.launch()
models.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image, ImageDraw, ImageFont
2
+ import random
3
+ import io
4
+
5
+ # Note: These are MOCK implementations for 'gemini-2' and 'gpt image-1' image remixing.
6
+ # Direct multi-image remixing APIs for these specific model names that take three arbitrary
7
+ # input images are not publicly available or are not standard usage.
8
+ # These functions simulate the desired behavior using the Pillow library for demonstration.
9
+
10
+ def _get_font(size: int = 24) -> ImageFont.FreeTypeFont:
11
+ """Helper to get a font that is likely available on most systems or a default."""
12
+ try:
13
+ # Try a common system font
14
+ return ImageFont.truetype("arial.ttf", size)
15
+ except IOError:
16
+ # Fallback to default if Arial is not found
17
+ return ImageFont.load_default(size)
18
+
19
+ def gemini_remix_image(image1: Image.Image | None, image2: Image.Image | None, image3: Image.Image | None, prompt: str) -> Image.Image:
20
+ """
21
+ MOCK: Simulates image remixing with a "Gemini-2" style.
22
+ Combines up to three input images and adds prompt text dynamically.
23
+ """
24
+ canvas_width, canvas_height = 800, 600
25
+ output_image = Image.new("RGB", (canvas_width, canvas_height), color=(240, 240, 255)) # Light blueish background
26
+ draw = ImageDraw.Draw(output_image)
27
+
28
+ images = [img for img in [image1, image2, image3] if img is not None]
29
+
30
+ if not images and not prompt:
31
+ # Return a small blank image if no inputs are provided
32
+ return Image.new("RGB", (1, 1), color=(255, 255, 255))
33
+
34
+ # Define positions for images
35
+ positions = [
36
+ (canvas_width // 4 - 50, canvas_height // 4 - 50), # Top-left quadrant
37
+ (canvas_width // 2 + 50, canvas_height // 4 - 50), # Top-right quadrant
38
+ (canvas_width // 4, canvas_height // 2 + 50) # Bottom-center, overlapping
39
+ ]
40
+ img_target_size = (canvas_width // 3, canvas_height // 3)
41
+
42
+ for i, img in enumerate(images):
43
+ # Apply a subtle tint and transparency for overlap effect
44
+ tint_color = (random.randint(180,220), random.randint(180,220), random.randint(180,220))
45
+ img_with_tint = Image.composite(Image.new(img.mode, img.size, tint_color), img, Image.new("L", img.size, 128))
46
+
47
+ resized_img = img_with_tint.resize(img_target_size)
48
+
49
+ # Create a mask for semi-transparency
50
+ mask = Image.new("L", resized_img.size, int(255 * 0.8)) # 80% opaque
51
+
52
+ # Paste with alpha composite to handle potential transparency
53
+ try:
54
+ output_image.paste(resized_img, positions[i % len(positions)], resized_img)
55
+ except ValueError: # Fallback for images without alpha channel
56
+ output_image.paste(resized_img, positions[i % len(positions)])
57
+
58
+ # Add prompt text with artistic styling
59
+ font_size = 30
60
+ font = _get_font(font_size)
61
+ text_color = (70, 70, 70) # Darker grey
62
+
63
+ if prompt:
64
+ wrapped_prompt = ""
65
+ current_line = ""
66
+ words = prompt.split(" ")
67
+ for word in words:
68
+ if draw.textbbox((0, 0), current_line + " " + word, font=font)[2] < canvas_width * 0.9:
69
+ current_line += " " + word
70
+ else:
71
+ wrapped_prompt += current_line.strip() + "\n"
72
+ current_line = word
73
+ wrapped_prompt += current_line.strip()
74
+
75
+ text_bbox = draw.textbbox((0, 0), wrapped_prompt, font=font)
76
+ text_width = text_bbox[2] - text_bbox[0]
77
+ text_height = text_bbox[3] - text_bbox[1]
78
+ text_x = (canvas_width - text_width) // 2
79
+ text_y = canvas_height - text_height - 20
80
+
81
+ draw.multiline_text((text_x, text_y), wrapped_prompt, font=font, fill=text_color, align="center")
82
+ else:
83
+ draw.text((canvas_width // 2 - 80, canvas_height - 40), "Gemini-2 AI Magic ✨", font=_get_font(20), fill=(150, 150, 150))
84
+
85
+ return output_image
86
+
87
+ def gpt_remix_image(image1: Image.Image | None, image2: Image.Image | None, image3: Image.Image | None, prompt: str) -> Image.Image:
88
+ """
89
+ MOCK: Simulates image remixing with a "GPT Image-1" (DALL-E) style.
90
+ Combines up to three input images with a different arrangement and adds prompt text.
91
+ """
92
+ canvas_width, canvas_height = 800, 600
93
+ output_image = Image.new("RGB", (canvas_width, canvas_height), color=(220, 230, 245)) # Soft blue background
94
+ draw = ImageDraw.Draw(output_image)
95
+
96
+ images = [img for img in [image1, image2, image3] if img is not None]
97
+
98
+ if not images and not prompt:
99
+ return Image.new("RGB", (1, 1), color=(255, 255, 255))
100
+
101
+ # Different layout: Center large image, smaller images in corners
102
+ img_large_size = (canvas_width // 2, canvas_height // 2)
103
+ img_small_size = (canvas_width // 4, canvas_height // 4)
104
+
105
+ if len(images) > 0:
106
+ main_img = images[0].resize(img_large_size)
107
+ output_image.paste(main_img, (canvas_width // 2 - img_large_size[0] // 2, canvas_height // 2 - img_large_size[1] // 2))
108
+
109
+ if len(images) > 1:
110
+ top_left_img = images[1].resize(img_small_size)
111
+ output_image.paste(top_left_img, (20, 20))
112
+
113
+ if len(images) > 2:
114
+ bottom_right_img = images[2].resize(img_small_size)
115
+ output_image.paste(bottom_right_img, (canvas_width - img_small_size[0] - 20, canvas_height - img_small_size[1] - 20))
116
+
117
+ # Add artistic borders and effects
118
+ for i, img in enumerate(images):
119
+ if i < len(images): # Apply to images that were placed
120
+ pos = None
121
+ size = None
122
+ if i == 0 and len(images) > 0: # Main image
123
+ pos = (canvas_width // 2 - img_large_size[0] // 2, canvas_height // 2 - img_large_size[1] // 2)
124
+ size = img_large_size
125
+ elif i == 1 and len(images) > 1: # Top-left
126
+ pos = (20, 20)
127
+ size = img_small_size
128
+ elif i == 2 and len(images) > 2: # Bottom-right
129
+ pos = (canvas_width - img_small_size[0] - 20, canvas_height - img_small_size[1] - 20)
130
+ size = img_small_size
131
+
132
+ if pos and size:
133
+ # Draw a subtle border
134
+ border_color = (random.randint(100, 150), random.randint(100, 150), random.randint(100, 150))
135
+ draw.rectangle((pos[0]-2, pos[1]-2, pos[0]+size[0]+2, pos[1]+size[1]+2), outline=border_color, width=3)
136
+
137
+
138
+ # Add prompt text with a distinct style
139
+ font_size = 32
140
+ font = _get_font(font_size)
141
+ text_color = (25, 25, 25) # Very dark grey
142
+
143
+ if prompt:
144
+ text_bbox = draw.textbbox((0, 0), prompt, font=font)
145
+ text_width = text_bbox[2] - text_bbox[0]
146
+ text_x = (canvas_width - text_width) // 2
147
+ draw.text((text_x, 10), prompt, font=font, fill=text_color, stroke_width=1, stroke_fill=(150,150,150))
148
+ else:
149
+ draw.text((canvas_width // 2 - 90, 10), "GPT Image-1 Creativity", font=_get_font(22), fill=(100, 100, 100))
150
+
151
+ return output_image
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ Pillow