File size: 4,189 Bytes
ad22797
d7106ba
ad22797
 
 
 
949d787
 
 
 
 
 
 
 
 
ad22797
 
949d787
 
 
ad22797
 
 
 
 
 
 
 
 
 
785cdf8
ad22797
d7106ba
ad22797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
785cdf8
ad22797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a6feb6
ad22797
 
7a6feb6
0d68b46
7a6feb6
 
0d68b46
7a6feb6
0d68b46
 
f66f6d4
0d68b46
 
 
6e11687
 
0d68b46
 
 
7a6feb6
 
6e11687
7a6feb6
0d68b46
 
6e11687
 
 
0d68b46
 
7a6feb6
 
 
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
import gradio as gr
from PIL import Image
import os
import shutil
import random

def process_transparent_image(image, padding_color):
    """Handle images with transparency by converting transparent areas to a solid color."""
    if image.mode in ("RGBA", "LA") or (image.mode == "P" and "transparency" in image.info):
        alpha = image.convert("RGBA").getchannel("A")  # Extract the alpha channel
        background = Image.new("RGBA", image.size, padding_color + (255,))
        background.paste(image, mask=alpha)  # Paste with transparency mask
        return background.convert("RGB")  # Convert back to RGB
    return image.convert("RGB")  # For non-transparent images

def resize_and_pad(image, target_size):
    """Resize the image and pad it to match target size."""
    padding_color = (255, 255, 255) if random.choice([True, False]) else (0, 0, 0)
    img = process_transparent_image(image, padding_color)

    aspect_ratio = img.width / img.height
    target_aspect_ratio = target_size[0] / target_size[1]

    if aspect_ratio > target_aspect_ratio:
        new_width = target_size[0]
        new_height = int(new_width / aspect_ratio)
    else:
        new_height = target_size[1]
        new_width = int(new_height * aspect_ratio)

    img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)

    new_img = Image.new("RGB", target_size, padding_color)
    offset = ((target_size[0] - new_width) // 2, (target_size[1] - new_height) // 2)
    new_img.paste(img, offset)
    return new_img

def combine_images(images, target_size=(2048, 2048)):
    """Combine four images into a single one."""
    num_images = len(images)
    output_images = []

    for i in range(0, num_images, 4):
        group = images[i:i+4]
        if len(group) < 4:
            continue

        resized_images = [resize_and_pad(img, (512, 512)) for img in group]
        combined_img = Image.new("RGB", (1024, 1024), (0, 0, 0))
        combined_img.paste(resized_images[0], (0, 0))
        combined_img.paste(resized_images[1], (512, 0))
        combined_img.paste(resized_images[2], (0, 512))
        combined_img.paste(resized_images[3], (512, 512))

        if combined_img.width > target_size[0] or combined_img.height > target_size[1]:
            combined_img = combined_img.resize(target_size, Image.Resampling.LANCZOS)

        output_images.append(combined_img)

    return output_images

def process_images(uploaded_images):
    """Main processing function."""
    images = [Image.open(img) for img in uploaded_images]
    combined_images = combine_images(images)

    # Save combined images
    output_dir = "output_images"
    os.makedirs(output_dir, exist_ok=True)
    for idx, img in enumerate(combined_images):
        output_path = os.path.join(output_dir, f"combined_{idx + 1}.png")
        img.save(output_path)

    zip_path = "combined_images.zip"
    shutil.make_archive("combined_images", 'zip', output_dir)
    return combined_images, zip_path

# Gradio UI
def main_interface():
    with gr.Blocks(css=".gradio-container { height: 100vh; }") as interface:
        with gr.Row():
            gr.Markdown("### Image Resizer and Combiner")

        with gr.Row():
            with gr.Column(scale=1, elem_id="left-panel"):
                uploaded_files = gr.Files(file_types=["image"], label="Upload Images", interactive=True)
                combine_button = gr.Button("Combine and Process", elem_id="combine-button")

            with gr.Column(scale=2, elem_id="right-panel"):
                preview_gallery = gr.Gallery(label="Preview Combined Images", columns=3, elem_id="preview-gallery")
                download_zip_button = gr.Button("Download ZIP", elem_id="download-zip", visible=False)
                output_zip = gr.File(label="Download Combined ZIP", visible=False)

        # Button actions
        combine_button.click(
            process_images,
            inputs=[uploaded_files],
            outputs=[preview_gallery, output_zip],
        )

        download_zip_button.click(
            lambda zip_path: zip_path,
            inputs=[output_zip],
            outputs=[output_zip],
        )

    return interface

main_interface().launch()