File size: 8,331 Bytes
b37a7a8
 
 
 
63d332a
428baa9
 
 
 
 
5859711
 
63d332a
 
 
 
 
 
428baa9
 
 
 
 
 
 
 
 
 
 
 
 
 
5859711
 
 
 
 
 
 
63d332a
5859711
 
63d332a
5859711
 
 
63d332a
5859711
 
 
 
 
b37a7a8
5859711
b37a7a8
5859711
 
b37a7a8
 
 
428baa9
 
 
 
 
 
 
 
 
 
 
 
5859711
 
 
 
 
 
 
 
 
 
b37a7a8
 
 
428baa9
 
 
5859711
 
 
 
428baa9
5859711
13ccdc7
5859711
 
 
13ccdc7
 
 
428baa9
 
 
63d332a
428baa9
 
 
63d332a
428baa9
 
 
5859711
409a8a4
b37a7a8
 
6a657a3
 
 
 
 
b37a7a8
 
 
5859711
 
13ccdc7
5859711
 
13ccdc7
 
8d2e08a
5859711
 
 
63d332a
b37a7a8
 
5859711
b37a7a8
32fba57
63d332a
 
 
 
 
 
 
 
 
 
 
 
 
5859711
63d332a
5859711
 
 
b37a7a8
5859711
 
63d332a
 
 
 
 
 
 
5859711
63d332a
5859711
63d332a
 
 
 
 
 
 
 
 
 
5859711
13ccdc7
5859711
13ccdc7
63d332a
13ccdc7
5859711
 
 
 
b37a7a8
 
 
 
 
31dc87e
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import gradio as gr
from pathlib import Path
from PIL import Image

def get_supported_formats():
    """
    A function that retrieves the supported formats of images.
    Returns:
        The supported image formats as a list.
    """
    supported_formats = Image.registered_extensions()  # Get all registered image extensions and their formats
    print("Supported formats retrieved:", supported_formats)
    return supported_formats


SUPPORTED_FORMATS = get_supported_formats()


def convert_format(
    input_image: str = None, ext: str = ".webp", quality: int = 80
):
    """
    A function that converts an input image to a specified format with a given quality.

    Parameters:
        input_image (str): The path to the input image file.
        ext (str, optional): The extension for the output format. Defaults to ".webp".
        quality (int, optional): The quality of the output image. Defaults to 80.

    Returns:
        tuple: A tuple containing the reopened image in RGBA format and the path to the saved image file.
    """
    print("Converting image:", input_image, "to format:", ext, "with quality:", quality)
    file_path = Path("caches") / "{}{}".format(Path(input_image).stem, ext)  # Generate output file path
    print("Output file path generated:", file_path)
    file_path.parent.mkdir(parents=True, exist_ok=True)  # Create directories if they don't exist
    img = Image.open(input_image)  # Open the input image
    print("Image opened successfully.")

    format = None
    print("Checking if extension is supported:", ext)  # Log the extension being checked
    if ext in SUPPORTED_FORMATS:  # Check if the specified extension is supported
        format = SUPPORTED_FORMATS[ext]
    if format is None:  # If format is not supported, raise an error
        error_message = "Unsupported image format. Supported formats: {}".format(
            ", ".join(SUPPORTED_FORMATS)
        )
        print(error_message)
        gr.Error(error_message)

    img.save(file_path, format, quality=quality)  # Save the image in the specified format and quality
    print("Image saved to:", file_path)

    # Reopen the saved image to verify its integrity
    img_reopen = Image.open(file_path)
    img_reopen = img_reopen.convert("RGBA")  # Ensure the image is in RGBA format
    print("Image reopened and converted to RGBA format.")
    return img_reopen, str(file_path)


def process(input_list: list[tuple], ext: str = ".webp", quality: int = 80):
    """
    A function that processes a list of images by converting them to a specified format with a given quality.

    Parameters:
        input_list (list[tuple]): A list of tuples containing the paths to the input image files.
        ext (str, optional): The extension for the output format. Defaults to ".webp".
        quality (int, optional): The quality of the output images. Defaults to 80.

    Returns:
        tuple: A tuple containing lists of file paths and reopened images in RGBA format.
    """
    print("Processing images with extension:", ext, "and quality:", quality)
    out_files = []  # List to store paths of converted images
    out_images = []  # List to store reopened images
    for index, path in enumerate(input_list):
        print(f"Processing image {index + 1}/{len(input_list)}: {path[0]}")  # Include index for debugging batches
        img_reopen, file_path = convert_format(path[0], ext, quality)  # Convert each image
        out_files.append(file_path)  # Append the file path to the output list
        out_images.append(img_reopen)  # Append the reopened image to the output list
        print("Image processed successfully.")
    print("All images processed. Output files:", out_files)
    return out_files, out_images


def swap_to_gallery(images: list):
    """
    A function that swaps to a gallery, taking a list of images as input.
    Parameters:
        images (list): List of images to display in the gallery.
    Returns:
        Updated gallery state.
    """
    print("Swapping to gallery with images:", images)
    return (
        gr.update(value=images, visible=True),  # Update the gallery with new images
        gr.update(visible=True),  # Make the gallery visible
        gr.update(visible=False),  # Hide the file upload button
    )


def run(server_name: str = "127.0.0.1", server_port: int = 7860):
    """
    A function that runs the WebP Converter app, allowing users to upload images, set quality, and convert them to WebP format.

    Parameters:
        server_name (str, optional): The server name where the app is hosted. Defaults to "127.0.0.1".
        server_port (int, optional): The port number for the server. Defaults to 7860.

    Returns:
        None
    """
    print("Starting the WebP Converter app on {}:{}".format(server_name, server_port))
    with gr.Blocks(theme="Nymbo/Nymbo_Theme") as app:  # Define the Gradio app layout
        gr.Markdown(
            """
            <div style="text-align: center;">
                <h1>Image Format Converter</h1>
                <p>Upload one or more image files and convert it to specified format with adjustable quality.</p>
                <img src='F:/gradio-apps/image_to_webp/caches/1.webp' alt='Example Image' />
            </div>
            """
        )

        with gr.Row(equal_height=False):  # Define a row layout with unequal column heights
            with gr.Column():  # First column for user inputs
                files = gr.Files(
                    label="Drag 1 or more images",  # Upload button for images
                    file_types=["image"],  # Restrict file types to images
                )
                uploaded_files = gr.Gallery(
                    label="Your images", visible=False, columns=4, height="auto"
                )  # Gallery to display uploaded images

                with gr.Row():  # Row for quality slider and format dropdown
                    quality_slider = gr.Slider(
                        minimum=1,
                        maximum=100,
                        value=80,  # Default quality
                        step=1,
                        label="Image Quality",
                    )
                    extension_dropdown = gr.Dropdown(
                        label="Output Format",
                        choices=[
                            ".webp",
                            ".png",
                            ".jpg",
                            ".jpeg",
                            ".gif",
                            ".bmp",
                            ".tiff",
                            ".tif",
                        ],
                        value=".webp",  # Default format
                    )
                with gr.Row():  # Row for buttons
                    reset_btn = gr.Button("Clear Images", variant="secondary")  # Clear button
                    proc_btn = gr.Button("Run Convert", variant="primary")  # Convert button

            with gr.Column():  # Second column for outputs
                output_file = gr.File(label="Converted WebP")  # Downloadable converted file
                output_gallery = gr.Gallery(
                    label="Re-check converted images",
                    show_label=False,
                    elem_id="gallery",
                    object_fit="contain",
                    height="auto",
                    columns=4,
                )  # Gallery to display converted images

        # Collect inputs and outputs for processing
        inputs = [
            uploaded_files,
            extension_dropdown,
            quality_slider,
        ]
        outputs = [
            output_file,
            output_gallery,
        ]

        # Define actions for user interactions
        files.upload(
            fn=swap_to_gallery,  # Action when files are uploaded
            inputs=files,
            outputs=[uploaded_files, proc_btn, files],
        )
        proc_btn.click(process, inputs=inputs, outputs=outputs)  # Action when convert button is clicked
        reset_btn.click(lambda: None, None, uploaded_files, queue=False)  # Action when clear button is clicked

    app.queue().launch(  # Launch the app
        server_name=server_name, server_port=server_port, share=False
    )


if __name__ == "__main__":
    run(server_name="0.0.0.0", server_port=7860)