feat: Add option to force PNG output for best quality
Browse files
README.md
CHANGED
|
@@ -4,7 +4,7 @@ emoji: 📈
|
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version: 5.
|
| 8 |
app_file: app.py
|
| 9 |
pinned: true
|
| 10 |
license: apache-2.0
|
|
|
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 5.39.0
|
| 8 |
app_file: app.py
|
| 9 |
pinned: true
|
| 10 |
license: apache-2.0
|
app.py
CHANGED
|
@@ -790,7 +790,7 @@ class Upscale:
|
|
| 790 |
self.face_enhancer = GFPGANer(model_path=model_path, upscale=self.scale, arch=arch, channel_multiplier=channel_multiplier, model_rootpath=model_rootpath, det_model=face_detection, resolution=resolution)
|
| 791 |
|
| 792 |
|
| 793 |
-
def inference(self, gallery, face_restoration, upscale_model, scale: float, face_detection, face_detection_threshold: any, face_detection_only_center: bool, outputWithModelName: bool, progress=gr.Progress()):
|
| 794 |
try:
|
| 795 |
if not gallery or (not face_restoration and not upscale_model):
|
| 796 |
raise ValueError("Invalid parameter setting")
|
|
@@ -905,9 +905,14 @@ class Upscale:
|
|
| 905 |
print(f"Warning: Processing resulted in no image for '{img_path}'. Skipping output.")
|
| 906 |
continue
|
| 907 |
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 911 |
self.imwriteUTF8(save_path, restored_img)
|
| 912 |
zipf_restore.write(save_path, arcname=os.path.basename(save_path))
|
| 913 |
|
|
@@ -1145,7 +1150,11 @@ def remove_image_from_gallery(gallery: list, selected_image: str):
|
|
| 1145 |
|
| 1146 |
def main():
|
| 1147 |
if torch.cuda.is_available():
|
| 1148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1149 |
# set torch options to avoid get black image for RTX16xx card
|
| 1150 |
# https://github.com/CompVis/stable-diffusion/issues/69#issuecomment-1260722801
|
| 1151 |
torch.backends.cudnn.enabled = True
|
|
@@ -1213,6 +1222,8 @@ def main():
|
|
| 1213 |
face_detection_threshold = gr.Number(label="Face eye dist threshold", value=10, info="A threshold to filter out faces with too small an eye distance (e.g., side faces).")
|
| 1214 |
face_detection_only_center = gr.Checkbox(value=False, label="Face detection only center", info="If set to True, only the face closest to the center of the image will be kept.")
|
| 1215 |
with_model_name = gr.Checkbox(label="Output image files name with model name", value=True)
|
|
|
|
|
|
|
| 1216 |
|
| 1217 |
# Define the event listener to add the uploaded image to the gallery
|
| 1218 |
input_image.change(append_gallery, inputs=[input_gallery, input_image], outputs=[input_gallery, input_image])
|
|
@@ -1237,6 +1248,7 @@ def main():
|
|
| 1237 |
face_detection_threshold,
|
| 1238 |
face_detection_only_center,
|
| 1239 |
with_model_name,
|
|
|
|
| 1240 |
], variant="secondary", size="lg",)
|
| 1241 |
with gr.Column(variant="panel"):
|
| 1242 |
gallerys = gr.Gallery(type="filepath", label="Output (The whole image)", format="png")
|
|
@@ -1272,6 +1284,7 @@ def main():
|
|
| 1272 |
face_detection_threshold,
|
| 1273 |
face_detection_only_center,
|
| 1274 |
with_model_name,
|
|
|
|
| 1275 |
],
|
| 1276 |
outputs=[gallerys, outputs],
|
| 1277 |
)
|
|
|
|
| 790 |
self.face_enhancer = GFPGANer(model_path=model_path, upscale=self.scale, arch=arch, channel_multiplier=channel_multiplier, model_rootpath=model_rootpath, det_model=face_detection, resolution=resolution)
|
| 791 |
|
| 792 |
|
| 793 |
+
def inference(self, gallery, face_restoration, upscale_model, scale: float, face_detection, face_detection_threshold: any, face_detection_only_center: bool, outputWithModelName: bool, save_as_png: bool, progress=gr.Progress()):
|
| 794 |
try:
|
| 795 |
if not gallery or (not face_restoration and not upscale_model):
|
| 796 |
raise ValueError("Invalid parameter setting")
|
|
|
|
| 905 |
print(f"Warning: Processing resulted in no image for '{img_path}'. Skipping output.")
|
| 906 |
continue
|
| 907 |
|
| 908 |
+
# Determine the file extension for the output image based on user preference and image properties.
|
| 909 |
+
if save_as_png:
|
| 910 |
+
# Force PNG output for the best quality, as requested by the user.
|
| 911 |
+
final_extension = ".png"
|
| 912 |
+
else:
|
| 913 |
+
# Use original logic: PNG for images with an alpha channel (RGBA), otherwise use the original extension or default to jpg.
|
| 914 |
+
final_extension = ".png" if img_mode == "RGBA" else (extension if extension else ".jpg")
|
| 915 |
+
save_path = f"output/{basename}{self.modelInUse}{final_extension}"
|
| 916 |
self.imwriteUTF8(save_path, restored_img)
|
| 917 |
zipf_restore.write(save_path, arcname=os.path.basename(save_path))
|
| 918 |
|
|
|
|
| 1150 |
|
| 1151 |
def main():
|
| 1152 |
if torch.cuda.is_available():
|
| 1153 |
+
# Sets the VRAM limit for the GPU. Fine-tune VRAM usage.
|
| 1154 |
+
# Higher values allow larger image tiles to be processed at once, which is faster. If you see the 'depth' in the console log increase frequently, try raising this value.
|
| 1155 |
+
# Lower it for complex models that need more memory overhead.
|
| 1156 |
+
# This setting is locked in once processing starts. To apply a new value, you must restart the entire application.
|
| 1157 |
+
torch.cuda.set_per_process_memory_fraction(0.900, device='cuda:0')
|
| 1158 |
# set torch options to avoid get black image for RTX16xx card
|
| 1159 |
# https://github.com/CompVis/stable-diffusion/issues/69#issuecomment-1260722801
|
| 1160 |
torch.backends.cudnn.enabled = True
|
|
|
|
| 1222 |
face_detection_threshold = gr.Number(label="Face eye dist threshold", value=10, info="A threshold to filter out faces with too small an eye distance (e.g., side faces).")
|
| 1223 |
face_detection_only_center = gr.Checkbox(value=False, label="Face detection only center", info="If set to True, only the face closest to the center of the image will be kept.")
|
| 1224 |
with_model_name = gr.Checkbox(label="Output image files name with model name", value=True)
|
| 1225 |
+
# Add a checkbox to always save the output as a PNG file for the best quality.
|
| 1226 |
+
save_as_png = gr.Checkbox(label="Always save output as PNG", value=True, info="If enabled, all output images will be saved in PNG format to ensure the best quality. If disabled, the format will be determined automatically (PNG for images with transparency, otherwise JPG).")
|
| 1227 |
|
| 1228 |
# Define the event listener to add the uploaded image to the gallery
|
| 1229 |
input_image.change(append_gallery, inputs=[input_gallery, input_image], outputs=[input_gallery, input_image])
|
|
|
|
| 1248 |
face_detection_threshold,
|
| 1249 |
face_detection_only_center,
|
| 1250 |
with_model_name,
|
| 1251 |
+
save_as_png,
|
| 1252 |
], variant="secondary", size="lg",)
|
| 1253 |
with gr.Column(variant="panel"):
|
| 1254 |
gallerys = gr.Gallery(type="filepath", label="Output (The whole image)", format="png")
|
|
|
|
| 1284 |
face_detection_threshold,
|
| 1285 |
face_detection_only_center,
|
| 1286 |
with_model_name,
|
| 1287 |
+
save_as_png,
|
| 1288 |
],
|
| 1289 |
outputs=[gallerys, outputs],
|
| 1290 |
)
|
requirements.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
--extra-index-url https://download.pytorch.org/whl/cu124
|
| 2 |
|
| 3 |
-
gradio==5.
|
| 4 |
|
| 5 |
basicsr @ git+https://github.com/avan06/BasicSR
|
| 6 |
facexlib @ git+https://github.com/avan06/facexlib
|
|
|
|
| 1 |
--extra-index-url https://download.pytorch.org/whl/cu124
|
| 2 |
|
| 3 |
+
gradio==5.39.0
|
| 4 |
|
| 5 |
basicsr @ git+https://github.com/avan06/BasicSR
|
| 6 |
facexlib @ git+https://github.com/avan06/facexlib
|
webui.bat
CHANGED
|
@@ -1,21 +1,37 @@
|
|
| 1 |
@echo off
|
| 2 |
|
| 3 |
-
:: The source of the webui.bat file is stable-diffusion-webui
|
|
|
|
|
|
|
|
|
|
| 4 |
set COMMANDLINE_ARGS=--input_images_limit -1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
|
|
|
| 6 |
if not defined PYTHON (set PYTHON=python)
|
| 7 |
-
if not defined
|
|
|
|
| 8 |
|
| 9 |
mkdir tmp 2>NUL
|
| 10 |
|
|
|
|
| 11 |
%PYTHON% -c "" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 12 |
if %ERRORLEVEL% == 0 goto :check_pip
|
| 13 |
echo Couldn't launch python
|
| 14 |
goto :show_stdout_stderr
|
| 15 |
|
| 16 |
:check_pip
|
|
|
|
| 17 |
%PYTHON% -mpip --help >tmp/stdout.txt 2>tmp/stderr.txt
|
| 18 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
|
|
| 19 |
if "%PIP_INSTALLER_LOCATION%" == "" goto :show_stdout_stderr
|
| 20 |
%PYTHON% "%PIP_INSTALLER_LOCATION%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 21 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
@@ -23,33 +39,106 @@ echo Couldn't install pip
|
|
| 23 |
goto :show_stdout_stderr
|
| 24 |
|
| 25 |
:start_venv
|
| 26 |
-
if
|
| 27 |
-
if ["%
|
|
|
|
|
|
|
| 28 |
|
|
|
|
| 29 |
dir "%VENV_DIR%\Scripts\Python.exe" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 30 |
-
if %ERRORLEVEL% == 0 goto :
|
| 31 |
|
|
|
|
|
|
|
| 32 |
for /f "delims=" %%i in ('CALL %PYTHON% -c "import sys; print(sys.executable)"') do set PYTHON_FULLNAME="%%i"
|
| 33 |
echo Creating venv in directory %VENV_DIR% using python %PYTHON_FULLNAME%
|
| 34 |
%PYTHON_FULLNAME% -m venv "%VENV_DIR%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 35 |
-
if %ERRORLEVEL%
|
| 36 |
-
echo Unable to create venv in directory "%VENV_DIR%"
|
| 37 |
-
goto :show_stdout_stderr
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
set PYTHON="%VENV_DIR%\Scripts\Python.exe"
|
| 41 |
-
echo venv %PYTHON%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
goto :launch
|
| 45 |
|
| 46 |
:launch
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
| 48 |
pause
|
| 49 |
exit /b
|
| 50 |
|
| 51 |
-
:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
|
|
|
|
|
|
|
|
|
| 53 |
echo.
|
| 54 |
echo exit code: %errorlevel%
|
| 55 |
|
|
@@ -61,13 +150,13 @@ type tmp\stdout.txt
|
|
| 61 |
|
| 62 |
:show_stderr
|
| 63 |
for /f %%i in ("tmp\stderr.txt") do set size=%%~zi
|
| 64 |
-
if %size% equ 0 goto :
|
| 65 |
echo.
|
| 66 |
echo stderr:
|
| 67 |
type tmp\stderr.txt
|
| 68 |
|
| 69 |
:endofscript
|
| 70 |
-
|
| 71 |
echo.
|
| 72 |
echo Launch unsuccessful. Exiting.
|
| 73 |
pause
|
|
|
|
|
|
| 1 |
@echo off
|
| 2 |
|
| 3 |
+
:: The original source of the webui.bat file is stable-diffusion-webui
|
| 4 |
+
:: Modified and enhanced by Gemini with features for venv management and requirements handling.
|
| 5 |
+
|
| 6 |
+
:: --------- Configuration ---------
|
| 7 |
set COMMANDLINE_ARGS=--input_images_limit -1
|
| 8 |
+
:: Define the name of the Launch application
|
| 9 |
+
set APPLICATION_NAME=app.py
|
| 10 |
+
:: Define the name of the virtual environment directory
|
| 11 |
+
set VENV_NAME=venv
|
| 12 |
+
:: Set to 1 to always attempt to update packages from requirements.txt on every launch
|
| 13 |
+
set ALWAYS_UPDATE_REQS=0
|
| 14 |
+
:: ---------------------------------
|
| 15 |
+
|
| 16 |
|
| 17 |
+
:: Set PYTHON executable if not already defined
|
| 18 |
if not defined PYTHON (set PYTHON=python)
|
| 19 |
+
:: Set VENV_DIR using VENV_NAME if not already defined
|
| 20 |
+
if not defined VENV_DIR (set "VENV_DIR=%~dp0%VENV_NAME%")
|
| 21 |
|
| 22 |
mkdir tmp 2>NUL
|
| 23 |
|
| 24 |
+
:: Check if Python is callable
|
| 25 |
%PYTHON% -c "" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 26 |
if %ERRORLEVEL% == 0 goto :check_pip
|
| 27 |
echo Couldn't launch python
|
| 28 |
goto :show_stdout_stderr
|
| 29 |
|
| 30 |
:check_pip
|
| 31 |
+
:: Check if pip is available
|
| 32 |
%PYTHON% -mpip --help >tmp/stdout.txt 2>tmp/stderr.txt
|
| 33 |
if %ERRORLEVEL% == 0 goto :start_venv
|
| 34 |
+
:: If pip is not available and PIP_INSTALLER_LOCATION is set, try to install pip
|
| 35 |
if "%PIP_INSTALLER_LOCATION%" == "" goto :show_stdout_stderr
|
| 36 |
%PYTHON% "%PIP_INSTALLER_LOCATION%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 37 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
|
|
| 39 |
goto :show_stdout_stderr
|
| 40 |
|
| 41 |
:start_venv
|
| 42 |
+
:: Skip venv creation/activation if VENV_DIR is explicitly set to "-"
|
| 43 |
+
if ["%VENV_DIR%"] == ["-"] goto :skip_venv_entirely
|
| 44 |
+
:: Skip venv creation/activation if SKIP_VENV is set to "1"
|
| 45 |
+
if ["%SKIP_VENV%"] == ["1"] goto :skip_venv_entirely
|
| 46 |
|
| 47 |
+
:: Check if the venv already exists by looking for Python.exe in its Scripts directory
|
| 48 |
dir "%VENV_DIR%\Scripts\Python.exe" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 49 |
+
if %ERRORLEVEL% == 0 goto :activate_venv_and_maybe_update
|
| 50 |
|
| 51 |
+
:: Venv does not exist, create it
|
| 52 |
+
echo Virtual environment not found in "%VENV_DIR%". Creating a new one.
|
| 53 |
for /f "delims=" %%i in ('CALL %PYTHON% -c "import sys; print(sys.executable)"') do set PYTHON_FULLNAME="%%i"
|
| 54 |
echo Creating venv in directory %VENV_DIR% using python %PYTHON_FULLNAME%
|
| 55 |
%PYTHON_FULLNAME% -m venv "%VENV_DIR%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 56 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 57 |
+
echo Unable to create venv in directory "%VENV_DIR%"
|
| 58 |
+
goto :show_stdout_stderr
|
| 59 |
+
)
|
| 60 |
+
echo Venv created.
|
| 61 |
+
|
| 62 |
+
:: Install requirements for the first time if venv was just created
|
| 63 |
+
:: This section handles the initial installation of packages from requirements.txt
|
| 64 |
+
:: immediately after a new virtual environment is created.
|
| 65 |
+
echo Checking for requirements.txt for initial setup in %~dp0
|
| 66 |
+
if exist "%~dp0requirements.txt" (
|
| 67 |
+
echo Found requirements.txt, attempting to install for initial setup...
|
| 68 |
+
call "%VENV_DIR%\Scripts\activate.bat"
|
| 69 |
+
echo Installing packages from requirements.txt ^(initial setup^)...
|
| 70 |
+
"%VENV_DIR%\Scripts\python.exe" -m pip install -r "%~dp0requirements.txt"
|
| 71 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 72 |
+
echo Failed to install requirements during initial setup. Please check the output above.
|
| 73 |
+
pause
|
| 74 |
+
goto :show_stdout_stderr_custom_pip_initial
|
| 75 |
+
)
|
| 76 |
+
echo Initial requirements installed successfully.
|
| 77 |
+
call "%VENV_DIR%\Scripts\deactivate.bat"
|
| 78 |
+
) else (
|
| 79 |
+
echo No requirements.txt found for initial setup, skipping package installation.
|
| 80 |
+
)
|
| 81 |
+
goto :activate_venv_and_maybe_update
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
:activate_venv_and_maybe_update
|
| 85 |
+
:: This label is reached if the venv exists or was just created.
|
| 86 |
+
:: Set PYTHON to point to the venv's Python interpreter.
|
| 87 |
set PYTHON="%VENV_DIR%\Scripts\Python.exe"
|
| 88 |
+
echo Activating venv: %PYTHON%
|
| 89 |
+
|
| 90 |
+
:: Always update requirements if ALWAYS_UPDATE_REQS is 1
|
| 91 |
+
:: This section allows for updating packages from requirements.txt on every launch
|
| 92 |
+
:: if the ALWAYS_UPDATE_REQS variable is set to 1.
|
| 93 |
+
if defined ALWAYS_UPDATE_REQS (
|
| 94 |
+
if "%ALWAYS_UPDATE_REQS%"=="1" (
|
| 95 |
+
echo ALWAYS_UPDATE_REQS is enabled.
|
| 96 |
+
if exist "%~dp0requirements.txt" (
|
| 97 |
+
echo Attempting to update packages from requirements.txt...
|
| 98 |
+
REM No need to call activate.bat here again, PYTHON is already set to the venv's python
|
| 99 |
+
%PYTHON% -m pip install -r "%~dp0requirements.txt"
|
| 100 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 101 |
+
echo Failed to update requirements. Please check the output above.
|
| 102 |
+
pause
|
| 103 |
+
goto :endofscript
|
| 104 |
+
)
|
| 105 |
+
echo Requirements updated successfully.
|
| 106 |
+
) else (
|
| 107 |
+
echo ALWAYS_UPDATE_REQS is enabled, but no requirements.txt found. Skipping update.
|
| 108 |
+
)
|
| 109 |
+
) else (
|
| 110 |
+
echo ALWAYS_UPDATE_REQS is not enabled or not set to 1. Skipping routine update.
|
| 111 |
+
)
|
| 112 |
+
)
|
| 113 |
|
| 114 |
+
goto :launch
|
| 115 |
+
|
| 116 |
+
:skip_venv_entirely
|
| 117 |
+
:: This label is reached if venv usage is explicitly skipped.
|
| 118 |
+
echo Skipping venv.
|
| 119 |
goto :launch
|
| 120 |
|
| 121 |
:launch
|
| 122 |
+
:: Launch the main application
|
| 123 |
+
echo Launching Web UI with arguments: %COMMANDLINE_ARGS% %*
|
| 124 |
+
%PYTHON% %APPLICATION_NAME% %COMMANDLINE_ARGS% %*
|
| 125 |
+
echo Launch finished.
|
| 126 |
pause
|
| 127 |
exit /b
|
| 128 |
|
| 129 |
+
:show_stdout_stderr_custom_pip_initial
|
| 130 |
+
:: Custom error handler for failures during the initial pip install process.
|
| 131 |
+
echo.
|
| 132 |
+
echo exit code ^(pip initial install^): %errorlevel%
|
| 133 |
+
echo Errors during initial pip install. See output above.
|
| 134 |
+
echo.
|
| 135 |
+
echo Launch unsuccessful. Exiting.
|
| 136 |
+
pause
|
| 137 |
+
exit /b
|
| 138 |
|
| 139 |
+
|
| 140 |
+
:show_stdout_stderr
|
| 141 |
+
:: General error handler: displays stdout and stderr from the tmp directory.
|
| 142 |
echo.
|
| 143 |
echo exit code: %errorlevel%
|
| 144 |
|
|
|
|
| 150 |
|
| 151 |
:show_stderr
|
| 152 |
for /f %%i in ("tmp\stderr.txt") do set size=%%~zi
|
| 153 |
+
if %size% equ 0 goto :endofscript
|
| 154 |
echo.
|
| 155 |
echo stderr:
|
| 156 |
type tmp\stderr.txt
|
| 157 |
|
| 158 |
:endofscript
|
|
|
|
| 159 |
echo.
|
| 160 |
echo Launch unsuccessful. Exiting.
|
| 161 |
pause
|
| 162 |
+
exit /b
|