Skip to content

Instantly share code, notes, and snippets.

@ThioJoe
Last active January 29, 2024 03:54
Show Gist options
  • Save ThioJoe/c5ebb3246a3cd9ec3c7609a2165d2371 to your computer and use it in GitHub Desktop.
Save ThioJoe/c5ebb3246a3cd9ec3c7609a2165d2371 to your computer and use it in GitHub Desktop.
Low-Res Icon Upscaler Batch Script
@echo off
setlocal enabledelayedexpansion
rem | Lines beginning with 'rem' are comments
rem -------------------------------------------------------------------------------------------
rem | "Icon Upscaler" Script by ThioJoe: https://github.com/ThioJoe
rem | I created this script specifically for upscaling very low res (such as 256x256) icons like those in Windows. It uses a combination of Image Magick (to first improve the transparency edges) and the RealCugan-ncnn-vulkan upscaler which seems to perform the best for this use case. Of course, the script can be used for all sorts of images, but I have found this to yield the best results of any other method, and better than just using an upscaler alone.
rem -------------------------------------------------------------------------------------------
rem | HOW TO USE: Run the script and enter a file path to an image. Or, drag an image file onto this batch file to also run it. The result will go into the "outputs" folder.
rem | Also because of the limiations of batch files, if you enter a file path that has a different drive letter than the script, there is a good chance you'll get errors. So make sure the image files are on the same drive.
rem | REQUIREMENT 1: Windows binaries for realcugan-ncnn-vulkan here https://github.com/nihui/realcugan-ncnn-vulkan
rem | REQUIREMENT 2: "Convert.exe" from the Image Magick suite. Go to the download page ( https://imagemagick.org/script/download.php ), go to the Windows Binary Release section, and get the portable version described as "Portable Win64 static at 16 bits-per-pixel component". From the zip file you only need "convert.exe", and copy that into the same folder as this script.
:START
rem | -------- COMMON SETTINGS --------
set SCALE=4
set UPSCALE_ROUNDS=1
set NOISE_LEVEL=0
set OUTPUT_FORMAT=png
set MODEL_PATH=models-se
set SKIP_TRANSPARENCY_FIX=FALSE
rem --- Descriptions for common settings -----
rem | MODEL_PATH: The folder containing model files. For example: models-pro, models-se, models-nose
rem | SCALE: The multiplicative upscale amount. models-se possible values: 2,3,4 | models-pro possible values: 2,3
rem | UPSCALE_ROUNDS: The total number of times in a row the image will be upscaled by the SCALE number. For example, with SCALE=4 and UPSCALE_ROUNDS=1, the total upscale will be 4x. With scale=2 and UPSCALE_ROUNDS=3, the total upscale will be 8x (because 2*2*2)
rem | NOISE_LEVEL: Denoise level (-1/0/1/2/3, default=-1)
rem | OUTPUT_FORMAT: Output image format (jpg/png/webp, default=ext/png)
rem | SKIP_TRANSPARENCY_FIX: (TRUE/FALSE) Skips the use of convert.exe for improving the transparency mask. You can disable this to experiment, or if you are upscaling an image with no transparency.
rem ---------- ADVANCED SETTINGS -----------
set TILE_SIZE=0
set SYNC_GAP_MODE=2
set GPU_ID=auto
set THREAD_COUNT=1:2:2
set TTA_MODE=FALSE
rem --- Descriptions for advanced settings -----
rem | TILE_SIZE (>=32/0=auto, default=0) can be 0,0,0 for multi-gpu
rem | SYNC_GAP_MODE: Default=3 | Reduces the impact of image blocking. It's a trade-off between speed and quality. | 0=without process for sync gap (fast), 1=accurate lossless (slow), 2=some loss for background, less loss for texture (middle), 3=more loss for background, less loss for texture (fast) |
rem | GPU_ID - GPU devices to use (-1=cpu, default=auto) can be 0,1,2 for multi-gpu
rem | THREAD_COUNT: Thread count for the three stages in the following format - loading:processing:saving | (default=1:2:2) | Can use a comma to specify for multiple GPUs like 3:3:3,3:3:3
rem | TTA_MODE: "Test-Time Augmentation" Mode - Averages the upscaling results of 8 versions of the image (that are flipped or rotated of the original). May yield better results but will also probably take 8x as long.
rem | For full details on all parameters, see: https://github.com/nihui/realcugan-ncnn-vulkan#full-usages
rem | This fork also has some more detailed info on the meaning of the parameters: https://github.com/Kiyamou/VapourSynth-RealCUGAN-ncnn-Vulkan
rem -------------------------------------------
set argPath=%1
set SE_MAX_SCALE=4
set PRO_MAX_SCALE=3
set NOSE_MAX_SCALE=2
rem Check for invalid upscale amounts per model
if "!MODEL_PATH!"=="models-se" (
if !SCALE! GTR !SE_MAX_SCALE! (
echo ERROR: Scale is higher than maximum for models-se, use UPSCALE_ROUNDS setting to scale higher.
goto ERROR_QUIT
)
) else if "!MODEL_PATH!"=="models-pro" (
if !SCALE! GTR !PRO_MAX_SCALE! (
echo ERROR: Scale is higher than maximum for models-pro, use UPSCALE_ROUNDS setting to scale higher.
goto ERROR_QUIT
)
) else if "!MODEL_PATH!"=="models-nose" (
if !SCALE! GTR !NOSE_MAX_SCALE! (
echo ERROR: Scale is higher than maximum for models-nose, use UPSCALE_ROUNDS setting to scale higher.
goto ERROR_QUIT
)
)
rem Check for invalid number of upscale rounds
if %UPSCALE_ROUNDS% LSS 1 (
echo ERROR: UPSCALE_ROUNDS setting must be at least 1. If UPSCALE_ROUNDS is 1, the final upcale will equal the SCALE value.
goto ERROR_QUIT
)
echo Note 1: Because of .bat file limitations, using a file path on a different drive letter than this script might not work.
echo Note 2: You can also run the script by dragging the image file onto the script file in file explorer.
echo -
if "!argPath!"=="" (
set /p INPUT_PATH="Enter Image Path > "
) else (
set INPUT_PATH=%argPath%
)
set INPUT_PATH=%INPUT_PATH:"=%
set OUTPUT_DIR=%~dp0outputs\
for %%A in ("%INPUT_PATH%") do set "BASE_FILENAME=%%~nA-upscaled"
set TEMP_DIR=%~dp0temp\
set COUNTER=1
set REPEAT_COUNTER=1
:LOOP
if %COUNTER%==1 (
set OUTPUT_FILENAME=%BASE_FILENAME%
) else (
set OUTPUT_FILENAME=%BASE_FILENAME%-%COUNTER%
)
set OUTPUT_PATH=%OUTPUT_DIR%%OUTPUT_FILENAME%.%OUTPUT_FORMAT%
if exist "!OUTPUT_PATH!" (
set /a COUNTER+=1
goto LOOP
)
if not exist "!OUTPUT_DIR!" mkdir "!OUTPUT_DIR!"
if not exist "!TEMP_DIR!" mkdir "!TEMP_DIR!"
set TEMP_MASK=%TEMP_DIR%%OUTPUT_FILENAME%-mask.png
set TEMP_UPSCALED_MASK=%TEMP_DIR%%OUTPUT_FILENAME%-upscaled-mask.png
convert.exe "!INPUT_PATH!" -alpha extract -quality 05 "!TEMP_MASK!"
:UPSCALE
rem --- Calculate total upscale amount for current round
rem calculate x^n
SET x=%SCALE%
SET n=!REPEAT_COUNTER!
SET CURRENT_UPSCALE=1
FOR /L %%i IN (1,1,%n%) DO SET /A CURRENT_UPSCALE*=x
echo -
echo Running Upscale Round !REPEAT_COUNTER! (To !CURRENT_UPSCALE!x)
realcugan-ncnn-vulkan.exe -i "!INPUT_PATH!" -o "!OUTPUT_PATH!" -n %NOISE_LEVEL% -s %SCALE% -t %TILE_SIZE% -c %SYNC_GAP_MODE% -m %MODEL_PATH% -g %GPU_ID% -j %THREAD_COUNT% -x %TTA_MODE% -f %OUTPUT_FORMAT%
if "!SKIP_TRANSPARENCY_FIX!"=="FALSE" (
realcugan-ncnn-vulkan.exe -i "!TEMP_MASK!" -o "!TEMP_UPSCALED_MASK!" -n %NOISE_LEVEL% -s %SCALE% -t %TILE_SIZE% -c %SYNC_GAP_MODE% -m %MODEL_PATH% -g %GPU_ID% -j %THREAD_COUNT% -x %TTA_MODE% -f %OUTPUT_FORMAT%
)
if "!SKIP_TRANSPARENCY_FIX!"=="FALSE" (
convert.exe "!OUTPUT_PATH!" "!TEMP_UPSCALED_MASK!" -compose copyopacity -composite -quality 05 "!OUTPUT_PATH!"
)
if !REPEAT_COUNTER! LSS !UPSCALE_ROUNDS! (
set INPUT_PATH=!OUTPUT_PATH!
set TEMP_MASK=!TEMP_UPSCALED_MASK!
set TEMP_UPSCALED_MASK=%TEMP_DIR%%OUTPUT_FILENAME%-upscaled-!REPEAT_COUNTER!-mask.png
set /a REPEAT_COUNTER+=1
goto UPSCALE
)
echo -
echo Done - Output File: "!OUTPUT_PATH!"
echo ------------------------------------
rem | If the script was run by clicking on it, it will start over and prompt for a new image
if "!argPath!"=="" (
goto START
)
rem | Delete the temp directory
rd /s /q "!TEMP_DIR!"
rem | Wait for user input before closing and open output directory
set /p EXIT_INPUT="Done^! Close this window, or press Enter to open the Output folder and exit..."
start "" "explorer.exe" "!OUTPUT_DIR!"
exit /b
:ERROR_QUIT
set /p EXIT_INPUT="Press Enter to Exit..."
exit /b
@bfffggh
Copy link

bfffggh commented Jan 8, 2024

what even is this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment