PSNbst commited on
Commit
af3dd3e
·
verified ·
1 Parent(s): 731992f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -108
app.py CHANGED
@@ -1,109 +1,98 @@
1
  import gradio as gr
2
- from PIL import Image
3
- import os
4
- import shutil
5
- import random
6
-
7
- def process_transparent_image(image, padding_color):
8
- """Handle images with transparency by converting transparent areas to a solid color."""
9
- if image.mode in ("RGBA", "LA") or (image.mode == "P" and "transparency" in image.info):
10
- alpha = image.convert("RGBA").getchannel("A") # Extract the alpha channel
11
- background = Image.new("RGBA", image.size, padding_color + (255,))
12
- background.paste(image, mask=alpha) # Paste with transparency mask
13
- return background.convert("RGB") # Convert back to RGB
14
- return image.convert("RGB") # For non-transparent images
15
-
16
- def resize_and_pad(image, target_size):
17
- """Resize the image and pad it to match target size."""
18
- padding_color = (255, 255, 255) if random.choice([True, False]) else (0, 0, 0)
19
- img = process_transparent_image(image, padding_color)
20
-
21
- aspect_ratio = img.width / img.height
22
- target_aspect_ratio = target_size[0] / target_size[1]
23
-
24
- if aspect_ratio > target_aspect_ratio:
25
- new_width = target_size[0]
26
- new_height = int(new_width / aspect_ratio)
27
- else:
28
- new_height = target_size[1]
29
- new_width = int(new_height * aspect_ratio)
30
-
31
- img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
32
-
33
- new_img = Image.new("RGB", target_size, padding_color)
34
- offset = ((target_size[0] - new_width) // 2, (target_size[1] - new_height) // 2)
35
- new_img.paste(img, offset)
36
- return new_img
37
-
38
- def combine_images(images, target_size=(2048, 2048)):
39
- """Combine four images into a single one."""
40
- num_images = len(images)
41
- output_images = []
42
-
43
- for i in range(0, num_images, 4):
44
- group = images[i:i+4]
45
- if len(group) < 4:
46
- continue
47
-
48
- resized_images = [resize_and_pad(img, (512, 512)) for img in group]
49
- combined_img = Image.new("RGB", (1024, 1024), (0, 0, 0))
50
- combined_img.paste(resized_images[0], (0, 0))
51
- combined_img.paste(resized_images[1], (512, 0))
52
- combined_img.paste(resized_images[2], (0, 512))
53
- combined_img.paste(resized_images[3], (512, 512))
54
-
55
- if combined_img.width > target_size[0] or combined_img.height > target_size[1]:
56
- combined_img = combined_img.resize(target_size, Image.Resampling.LANCZOS)
57
-
58
- output_images.append(combined_img)
59
-
60
- return output_images
61
-
62
- def process_images(uploaded_images):
63
- """Main processing function."""
64
- images = [Image.open(img) for img in uploaded_images]
65
- combined_images = combine_images(images)
66
-
67
- # Save combined images
68
- output_dir = "output_images"
69
- os.makedirs(output_dir, exist_ok=True)
70
- for idx, img in enumerate(combined_images):
71
- output_path = os.path.join(output_dir, f"combined_{idx + 1}.png")
72
- img.save(output_path)
73
-
74
- zip_path = "combined_images.zip"
75
- shutil.make_archive("combined_images", 'zip', output_dir)
76
- return combined_images, zip_path
77
-
78
- # Gradio UI
79
- def main_interface():
80
- with gr.Blocks(css=".gradio-container { height: 100vh; }") as interface:
81
- with gr.Row():
82
- gr.Markdown("### Image Resizer and Combiner")
83
-
84
- with gr.Row():
85
- with gr.Column(scale=1, elem_id="left-panel"):
86
- uploaded_files = gr.Files(file_types=["image"], label="Upload Images", interactive=True)
87
- combine_button = gr.Button("Combine and Process", elem_id="combine-button")
88
-
89
- with gr.Column(scale=2, elem_id="right-panel"):
90
- preview_gallery = gr.Gallery(label="Preview Combined Images", columns=3, elem_id="preview-gallery")
91
- download_zip_button = gr.Button("Download ZIP", elem_id="download-zip", visible=False)
92
- output_zip = gr.File(label="Download Combined ZIP", visible=False)
93
-
94
- # Button actions
95
- combine_button.click(
96
- process_images,
97
- inputs=[uploaded_files],
98
- outputs=[preview_gallery, output_zip],
99
- )
100
-
101
- download_zip_button.click(
102
- lambda zip_path: zip_path,
103
- inputs=[output_zip],
104
- outputs=[output_zip],
105
- )
106
-
107
- return interface
108
-
109
- main_interface().launch()
 
1
  import gradio as gr
2
+ import io
3
+ import zipfile
4
+
5
+ # 自定义CSS,固定左右面板的大小 & 按钮样式
6
+ CUSTOM_CSS = """
7
+ /* 左侧面板 */
8
+ #left-panel {
9
+ width: 300px;
10
+ height: 400px; /* 固定高度,你可根据需求调整 */
11
+ overflow-y: auto; /* 超出时滚动 */
12
+ border-right: 1px solid #ccc;
13
+ padding: 10px;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ /* 右侧面板 */
18
+ #right-panel {
19
+ width: 300px;
20
+ height: 400px; /* 固定高度 */
21
+ overflow-y: auto;
22
+ border-left: 1px solid #ccc;
23
+ padding: 10px;
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ /* 合并按钮 */
28
+ #combine-button {
29
+ background-color: orange;
30
+ color: white;
31
+ font-size: 16px;
32
+ border-radius: 5px;
33
+ border: none;
34
+ padding: 10px 20px;
35
+ cursor: pointer;
36
+ }
37
+
38
+ /* 下载ZIP按钮 */
39
+ #download-zip {
40
+ background-color: blue;
41
+ color: white;
42
+ font-size: 16px;
43
+ border-radius: 5px;
44
+ border: none;
45
+ padding: 10px 20px;
46
+ cursor: pointer;
47
+ }
48
+ """
49
+
50
+ def combine_action():
51
+ """
52
+ 合并按钮点击后,你可以在这里执行实际逻辑。
53
+ 下面仅示例返回一个字符串或做一个简单处理。
54
+ """
55
+ print("合并逻辑被触发!")
56
+ return "已合并(此处可替换为实际处理逻辑)"
57
+
58
+ def create_zip():
59
+ """
60
+ 动态生成并返回一个 zip 文件(内存中)。
61
+ Gradio 会将返回的 BytesIO 作为 File 下载。
62
+ """
63
+ buf = io.BytesIO()
64
+ with zipfile.ZipFile(buf, 'w') as zf:
65
+ # zip 中写一个示例文件
66
+ zf.writestr("test.txt", "这是一个测试文件!\nHello World!")
67
+ buf.seek(0)
68
+ return buf # 返回内存中的 zip
69
+
70
+ with gr.Blocks(css=CUSTOM_CSS) as demo:
71
+ # 主布局
72
+ with gr.Row():
73
+ # 左侧面板
74
+ with gr.Box(elem_id="left-panel"):
75
+ gr.Markdown("**上传区域**")
76
+ uploader = gr.File(label="在此处上传文件")
77
+
78
+ # 右侧面板
79
+ with gr.Box(elem_id="right-panel"):
80
+ gr.Markdown("**结果缩略图**")
81
+ gr.Markdown("这里可以放置处理后的缩略图或任何输出")
82
+
83
+ # 底部按钮
84
+ with gr.Row():
85
+ combine_btn = gr.Button("合并", elem_id="combine-button")
86
+ download_btn = gr.Button("下载 Zip", elem_id="download-zip")
87
+
88
+ # 点击“合并”时(这里仅做一个演示)
89
+ combine_btn.click(fn=combine_action, inputs=[], outputs=[])
90
+
91
+ # 准备一个隐藏的 File 组件,用来承载生成的 zip 文件
92
+ # 一旦函数返回文件,该组件就会显示“下载链接”
93
+ zip_file = gr.File(label="点此下载生成的 ZIP", visible=False)
94
+
95
+ # 点击“下载 Zip”时,调用 create_zip,输出到 zip_file
96
+ download_btn.click(fn=create_zip, inputs=[], outputs=zip_file)
97
+
98
+ demo.launch()