File size: 8,596 Bytes
08bd837
779d534
08bd837
 
 
 
 
 
e78190e
08bd837
 
987b3cc
 
 
e78190e
 
 
 
 
 
 
779d534
 
 
 
 
 
 
 
 
 
 
08bd837
 
 
 
 
 
 
 
 
 
 
 
 
e78190e
08bd837
 
 
e78190e
779d534
 
 
e78190e
 
08bd837
 
e78190e
08bd837
e78190e
 
 
 
 
08bd837
 
 
e78190e
08bd837
 
 
 
 
 
 
 
 
 
 
 
 
 
779d534
 
e78190e
08bd837
e78190e
987b3cc
 
 
 
08bd837
 
 
 
 
 
 
e78190e
 
08bd837
 
 
 
e78190e
 
08bd837
987b3cc
 
 
 
 
08bd837
 
 
 
e78190e
 
 
 
08bd837
 
 
 
 
 
 
 
 
 
 
 
 
e78190e
08bd837
e78190e
08bd837
987b3cc
 
 
 
 
 
08bd837
 
5cedabe
08bd837
 
 
 
 
 
 
 
 
 
e78190e
 
779d534
e78190e
 
08bd837
 
779d534
 
 
e78190e
 
 
779d534
08bd837
 
e78190e
779d534
08bd837
779d534
08bd837
 
 
 
e78190e
 
779d534
e78190e
 
987b3cc
 
 
e78190e
 
 
779d534
08bd837
 
e78190e
 
08bd837
987b3cc
 
 
 
 
779d534
08bd837
 
 
 
 
 
 
 
 
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import gradio as gr
from gradio_imageslider import ImageSlider
from PIL import Image
import numpy as np
from aura_sr import AuraSR
import torch
import os
import time
import platform
import argparse

# Global variable to control batch processing cancellation.
stop_batch_flag = False

def open_folder():
    open_folder_path = os.path.abspath("outputs")
    if platform.system() == "Windows":
        os.startfile(open_folder_path)
    elif platform.system() == "Linux":
        os.system(f'xdg-open "{open_folder_path}"')

def get_placeholder_image():
    """
    Creates a placeholder image (if not already present) and returns its file path.
    This placeholder is a blank (white) image that will be used for progress updates.
    """
    placeholder_path = "placeholder.png"
    if not os.path.exists(placeholder_path):
        placeholder = Image.new("RGB", (256, 256), (255, 255, 255))
        placeholder.save(placeholder_path)
    return placeholder_path

# Force CPU usage
torch.set_default_tensor_type(torch.FloatTensor)

# Override torch.load to always use CPU
original_load = torch.load
torch.load = lambda *args, **kwargs: original_load(*args, **kwargs, map_location=torch.device('cpu'))

# Initialize the AuraSR model
aura_sr = AuraSR.from_pretrained("fal/AuraSR-v2")

# Restore original torch.load
torch.load = original_load

def process_single_image(input_image_path, reduce_seams):
    if input_image_path is None:
        raise gr.Error("Please provide an image to upscale.")

    # Send an initial progress update.
    # Instead of (None, None), we use the placeholder image file paths.
    placeholder = get_placeholder_image()
    yield [(placeholder, placeholder), "Starting upscaling..."]

    # Load the image.
    pil_image = Image.open(input_image_path)

    # Upscale using the chosen method.
    start_time = time.time()
    if reduce_seams:
        print("using reduce seams")
        upscaled_image = aura_sr.upscale_4x_overlapped(pil_image)
    else:
        upscaled_image = aura_sr.upscale_4x(pil_image)
    processing_time = time.time() - start_time
    print(f"Processing time: {processing_time:.2f} seconds")

    # Save the upscaled image.
    output_folder = "outputs"
    os.makedirs(output_folder, exist_ok=True)
    
    input_filename = os.path.basename(input_image_path)
    output_filename = os.path.splitext(input_filename)[0]
    output_path = os.path.join(output_folder, output_filename + ".png")
    
    counter = 1
    while os.path.exists(output_path):
        output_path = os.path.join(output_folder, f"{output_filename}_{counter:04d}.png")
        counter += 1
    
    upscaled_image.save(output_path)

    # Send the final progress update along with the before/after slider images.
    yield [(input_image_path, output_path),
           f"Upscaling complete in {processing_time:.2f} seconds"]

def process_batch(input_folder, output_folder=None, reduce_seams=False):
    global stop_batch_flag
    # Reset the stop flag for each new batch process.
    stop_batch_flag = False

    if not input_folder:
        raise gr.Error("Please provide an input folder path.")

    if not output_folder:
        output_folder = "outputs"

    os.makedirs(output_folder, exist_ok=True)
    input_files = [f for f in os.listdir(input_folder) if f.lower().endswith(
        ('.png', '.jpg', '.jpeg', '.bmp', '.tiff'))]
    total_files = len(input_files)
    processed_files = 0
    results = []

    yield [results, "Starting batch processing..."]

    for filename in input_files:
        # Check if the stop flag has been set.
        if stop_batch_flag:
            yield [results, "Batch processing cancelled by user."]
            return

        input_path = os.path.join(input_folder, filename)
        pil_image = Image.open(input_path)

        start_time = time.time()
        if reduce_seams:
            upscaled_image = aura_sr.upscale_4x_overlapped(pil_image)
        else:
            upscaled_image = aura_sr.upscale_4x(pil_image)
        processing_time = time.time() - start_time

        output_filename = os.path.splitext(filename)[0] + ".png"
        output_path = os.path.join(output_folder, output_filename)
        
        counter = 1
        while os.path.exists(output_path):
            output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}_{counter:04d}.png")
            counter += 1

        upscaled_image.save(output_path)
        processed_files += 1
        results.append(output_path)
        yield [results, f"Processed {processed_files}/{total_files}: {filename} in {processing_time:.2f} seconds"]

    yield [results, f"Batch processing complete. {processed_files} images processed."]

def stop_batch_process():
    global stop_batch_flag
    stop_batch_flag = True
    return "Stop button clicked. Cancelling batch processing..."

title = """<h1 align="center">AuraSR Giga Upscaler V4 by SECourses - Upscales to 4x</h1>
<p><center>AuraSR: new open source super-resolution upscaler based on GigaGAN. Works perfect on some images and fails on some images so give it a try</center></p>
<p><center>Works very fast and very VRAM friendly</center></p>
<h2 align="center">Latest version on : <a href="https://www.patreon.com/posts/121441873">https://www.patreon.com/posts/121441873</a></h2>
"""

def create_demo():
    with gr.Blocks() as demo:
        gr.HTML(title)
        
        with gr.Tab("Single Image"):
            with gr.Row():
                with gr.Column(scale=1):
                    input_image = gr.Image(label="Input Image", type="filepath")
                    reduce_seams = gr.Checkbox(
                        label="Reduce Seam Artifacts",
                        value=True,
                        info="upscale_4x upscales the image in tiles that do not overlap. This can result in seams. Use upscale_4x_overlapped to reduce seams. This will double the time upscaling by taking an additional pass and averaging the results."
                    )
                    process_btn = gr.Button(value="Upscale Image", variant="primary")
                with gr.Column(scale=1):
                    # Use the ImageSlider component for comparing before & after images.
                    # "filepath" type means the component expects image file paths.
                    output_slider = ImageSlider(label="Before / After", type="filepath", slider_color="blue")
                    progress_text = gr.Markdown("Progress messages will appear here.")
                    btn_open_outputs = gr.Button("Open Outputs Folder", variant="primary")
                    btn_open_outputs.click(fn=open_folder)
            
            process_btn.click(
                fn=process_single_image,
                inputs=[input_image, reduce_seams],
                outputs=[output_slider, progress_text]
            )
        
        with gr.Tab("Batch Processing"):
            with gr.Row():
                input_folder = gr.Textbox(label="Input Folder Path")
                output_folder = gr.Textbox(label="Output Folder Path (Optional)")
                reduce_seams_batch = gr.Checkbox(
                    label="Reduce Seam Artifacts",
                    value=True,
                    info="upscale_4x upscales the image in tiles that do not overlap. This can result in seams. Use upscale_4x_overlapped to reduce seams. This will double the time upscaling by taking an additional pass and averaging the results."
                )
            with gr.Row():
                batch_process_btn = gr.Button(value="Process Batch", variant="primary")
                stop_batch_btn = gr.Button(value="Stop Batch Processing", variant="secondary")
            with gr.Column():
                output_gallery_batch = gr.Gallery(label="Processed Images")
                progress_text_batch = gr.Markdown("Progress messages will appear here.")
            
            batch_process_btn.click(
                fn=process_batch,
                inputs=[input_folder, output_folder, reduce_seams_batch],
                outputs=[output_gallery_batch, progress_text_batch]
            )
            stop_batch_btn.click(
                fn=stop_batch_process,
                inputs=[],
                outputs=[progress_text_batch]
            )
    
    return demo

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="AuraSR Image Upscaling")
    parser.add_argument("--share", action="store_true", help="Create a publicly shareable link")
    args = parser.parse_args()

    demo = create_demo()
    demo.launch(debug=True, inbrowser=True, share=args.share)