Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05d77ae5b8 | |||
| 9795034d74 | |||
| c01948dc3f | |||
| 73661fae19 | |||
| 739f17283f | |||
| a3d1362d50 | |||
| 573450dee9 | |||
|
|
ad64287a8a | ||
|
|
9569e46b75 | ||
|
|
506baf2cd3 | ||
| f0346465fd | |||
| 600fbc8cc7 | |||
| 30c6e353c9 | |||
| ecd654abd9 | |||
| 04e77906a7 | |||
| 3091b4baca | |||
| 4e902360b7 | |||
| 8669ff0ee2 | |||
| bb44362a3e | |||
| d19435277f | |||
| 98f2ec28ce | |||
| b79e206f0d | |||
| 7377625812 | |||
|
|
7299250437 | ||
|
|
ce284540a6 | ||
|
|
d187a70452 | ||
| 7ef00cee24 | |||
| 9bad807528 | |||
| 9f29990faf | |||
| 842db05488 | |||
| bf30e40759 | |||
|
|
c977c9e754 | ||
| 8f7f6d71b7 | |||
| b28d2dd68e | |||
| f199fbded3 | |||
| de096496c7 | |||
| ab6d07d4bd | |||
| 0ea2d1d375 | |||
| 69205a1d8a | |||
| 60ffb862dc | |||
| 9fabb64161 | |||
| e247d7a524 | |||
| 430c271f62 | |||
| 41b8dd6d03 | |||
| e3d1ff1228 | |||
| bf2931085f | |||
|
|
58e114e368 | ||
|
|
9eee7a9878 | ||
|
|
5099959082 | ||
| bf4e85f6c1 | |||
|
|
619e24d332 | ||
| efc15a45cd | |||
|
|
fcddfd6292 | ||
|
|
72bcaa3131 | ||
|
|
d2a4ddc5ec | ||
|
|
d9ea3774c9 | ||
|
|
942c234931 | ||
|
|
ccd50e2cf4 | ||
|
|
bcf8c0be3d | ||
|
|
f5edfa8109 |
7
.desktop
@@ -1,7 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Image & Video Upscaler
|
||||
Comment=Upscale your videos and images with different upscalers
|
||||
Path=/opt/imagevideoupscaler
|
||||
Exec=/opt/imagevideoupscaler/imagevideoupscaler
|
||||
Icon=imagevideoupscaler
|
||||
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# FSRImageVideoUpscalerFrontend - .gitignore
|
||||
# SimpleMediaUpscalerLite - .gitignore
|
||||
#
|
||||
# Created by Janis Hutz 05/24/2023, Licensed under the GPL V3 License
|
||||
# https://janishutz.com, development@janishutz.com
|
||||
|
||||
5
LICENSE
@@ -631,7 +631,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
A simple PyQT5 frontend to upscale both videos and images
|
||||
A simple Electron GUI and Python CLI to upscale your videos using different
|
||||
upscaling engines.
|
||||
Copyright (C) 2023 Janis Hutz
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -652,7 +653,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
ImageVideoUpscalerFrontend Copyright (C) 2023 Janis Hutz
|
||||
SimpleMediaUpscalerLite Copyright (C) 2023 Janis Hutz
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
85
README.md
@@ -1,19 +1,28 @@
|
||||
<div id="title" align="center">
|
||||
<img src="./logo.png" width="300">
|
||||
<h1>ImageVideoUpscalerFrontend</h1>
|
||||
<h1>SimpleMediaUpscalerLite</h1>
|
||||
</div>
|
||||
|
||||
<div id="badges" align="center">
|
||||
<img src="https://img.shields.io/github/release/simplePCBuilding/FSRImageVideoUpscalerFrontend.svg">
|
||||
<img src="https://img.shields.io/github/license/simplePCBuilding/FSRImageVideoUpscalerFrontend.svg">
|
||||
<img src="https://img.shields.io/github/repo-size/simplePCBuilding/FSRImageVideoUpscalerFrontend.svg">
|
||||
<img src="https://img.shields.io/tokei/lines/github/simplePCBuilding/FSRImageVideoUpscalerFrontend">
|
||||
<img src="https://img.shields.io/github/issues-pr-raw/simplePCBuilding/FSRImageVideoUpscalerFrontend">
|
||||
<img src="https://img.shields.io/github/languages/top/simplePCBuilding/FSRImageVideoUpscalerFrontend">
|
||||
<img src="https://img.shields.io/github/directory-file-count/simplePCBuilding/FSRImageVideoUpscalerFrontend.svg">
|
||||
<img src="https://img.shields.io/github/package-json/v/simplePCBuilding/FSRImageVideoUpscalerFrontend.svg">
|
||||
<img src="https://img.shields.io/github/license/simplePCBuilding/SimpleMediaUpscalerLite.svg">
|
||||
<img src="https://img.shields.io/github/repo-size/simplePCBuilding/SimpleMediaUpscalerLite.svg">
|
||||
<img alt="Lines of code" src="https://img.shields.io/tokei/lines/github/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img src="https://img.shields.io/github/languages/top/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img src="https://img.shields.io/github/directory-file-count/simplePCBuilding/SimpleMediaUpscalerLite.svg">
|
||||
<br>
|
||||
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img alt="GitHub watchers" src="https://img.shields.io/github/watchers/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img src="https://img.shields.io/github/issues-pr-raw/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img alt="GitHub forks" src="https://img.shields.io/github/forks/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/simplePCBuilding/SimpleMediaUpscalerLite">
|
||||
<br>
|
||||
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/simplePCBuilding/SimpleMediaUpscalerLite/total?label=Downloads (total)">
|
||||
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/downloads/simplePCBuilding/SimpleMediaUpscalerLite/latest/total?label=Downloads (latest)">
|
||||
<img src="https://img.shields.io/github/release/simplePCBuilding/SimpleMediaUpscalerLite.svg">
|
||||
<img src="https://img.shields.io/github/package-json/v/simplePCBuilding/SimpleMediaUpscalerLite.svg?label=Development Version">
|
||||
|
||||
</div>
|
||||
An Electron App with Python CLI to upscale images and videos using multiple different upscaling engines.
|
||||
smuL (pronounced like "small") is an Electron App with Python CLI to upscale images and videos using multiple different upscaling engines.
|
||||
|
||||
# Functionality
|
||||
This app allows you to fully automatically upscale a single file or a full on folder with one of many different engines.
|
||||
@@ -31,13 +40,33 @@ This app allows you to fully automatically upscale a single file or a full on fo
|
||||
- more to come!
|
||||
|
||||
This App also features a CLI interface.
|
||||
- Options:
|
||||
```
|
||||
-s SCALEFACTOR --scalefactor SCALEFACTOR Factor of form 2x, maximum 4x
|
||||
-S SHARPENING --sharpening SHARPENING Value (0 - 1)
|
||||
-T THREADCOUNT --threads THREADCOUNT Choose how many threads in parallel. Maximum is max threads of your CPU
|
||||
-F FILETYPE --filetype FILETYPE Choose file type of temporary image files when upscaling videos (required)
|
||||
-N --noscaling No upscaling, requires -S option (Sharpening option)
|
||||
usage: SimpleMediaUpscalerLite-cli.py [-h] [-i INPUTFILE] [-o OUTPUTFILE] [-s SCALEFACTOR] [-S SHARPENING] [-T THREADS] [-E ENGINE] [-M MODE] [-F FILETYPE] [-d DETAILS] [-p] [-v]
|
||||
|
||||
SimpleMediaUpscalerLite - CLI, a CLI application to upscale videos and images using different upscaling engines.
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i INPUTFILE, --inputfile INPUTFILE
|
||||
File path for the video / image to be upscaled
|
||||
-o OUTPUTFILE, --outputfile OUTPUTFILE
|
||||
Output file path for the video / image that was upscaled
|
||||
-s SCALEFACTOR, --scalefactor SCALEFACTOR
|
||||
Scale factor for the video / image. Can be a integer from -4 to 4
|
||||
-S SHARPENING, --sharpening SHARPENING
|
||||
Sharpening factor (between 0 and 1 whereas 0 means no sharpening, 1 the most sharpening. Recommendation: Do not exceed 0.25, as it often looks bad)
|
||||
-T THREADS, --threads THREADS
|
||||
Thread count to use. Cannot exceed CPU thread count. Scaling non-linear (using 2 threads is not exactly 2x the speed of 1 thread). Scales well with FSR, barely with
|
||||
Real-ESRGAN, as it uses mostly the GPU to upscale
|
||||
-E ENGINE, --engine ENGINE
|
||||
Upscaling engine. By default can be fsr or ss. Use the -p option to see all installed engines
|
||||
-M MODE, --mode MODE Specify a special mode for a specific engine. Might not be available in every engine. Use the -d option to find out more
|
||||
-F FILETYPE, --filetype FILETYPE
|
||||
Change the file type of the temporary image files. Supports png, jpg. Video quality: png > jpg. PNG is default, if not specified.
|
||||
-d DETAILS, --details DETAILS
|
||||
Get details on usage of a particular engine and exit. Reads the config.json file of that engine and displays it in a HR manner
|
||||
-p, --printengines Print all engines and exit
|
||||
-v, --version Print version and exit
|
||||
```
|
||||
|
||||
# Supported OS
|
||||
@@ -47,25 +76,26 @@ This App also features a CLI interface.
|
||||
|
||||
# Contributing
|
||||
If you have any suggestions or features you'd like to have implemented, you may either implement the feature yourself and open a pull request, or open an issue on this GitHub page. Both things are appreciated!
|
||||
*I am looking for somebody willing to maintain the Windows version (including installer) as I am running Linux*
|
||||
|
||||
--> Follow the rules layed out in CONTRIBUTING.md
|
||||
--> We will add a linter that will then run on circleci to ensure code quality is high
|
||||
|
||||
### Current Contributers
|
||||
- simplePCBuilding (Maintainer) [Core (CLI), Docs, Website, Frontend, Linux packages]
|
||||
- ThatPlasma (Testing, Packager) [Testing, Windows Package]
|
||||
- ThatPlasma (Testing, Packager) [Testing]
|
||||
|
||||
|
||||
# Roadmap
|
||||
V1.1.0:
|
||||
- Migrate to PyQt5 (or create Electron app and make python app CLI only)
|
||||
- Create Windows & Mac Version
|
||||
- Refactor backend to add plugin support
|
||||
- Add more scaling engines
|
||||
- Expand Wiki to feature documentation on how to create a plugin (and maybe add a project website)
|
||||
V2.0.0:
|
||||
- Migrate to Electron app -- ✅
|
||||
- Package Windows & Linux Version -- ✅
|
||||
- Add packaging script for Linux & Windows version -- ✅
|
||||
- Make python app CLI only -- ✅
|
||||
- Refactor backend to add plugin support -- ✅
|
||||
|
||||
V1.2.0:
|
||||
V2.1.0:
|
||||
- Add more scaling engines
|
||||
- Expand Wiki to feature documentation on how to create a plugin (and maybe add a project website)
|
||||
- Show progress of scaling
|
||||
|
||||
# Issues
|
||||
@@ -73,6 +103,7 @@ If you encounter any problems with this app, please don't hesitate to open an is
|
||||
|
||||
## Known issues
|
||||
- Electron App is not available yet
|
||||
- Electron App shows that it is out of date if running in the development version
|
||||
- GTK version only runs on Linux
|
||||
|
||||
# FAQ
|
||||
@@ -88,7 +119,7 @@ If the OS is not officially supported, we may not be able to help you, since we
|
||||
|
||||
**Q: Why no worky on MacOS? / Can you port to MacOS?**
|
||||
|
||||
A: MacOS cannot run some of the upscalers included by default so we cannot support it. If you find a way to run all upscalers on Mac, feel free to open a PR to add that functionality
|
||||
A: Wine support on MacOS is still mediocre and most likely cannot run some of the upscalers included by default so we cannot support it. I will be testing it at some point in a VM, but that won't necesarily speak for full functionality. If you find a way to run all upscalers on Mac, feel free to open a PR to add that functionality or just let us know what you did in an issue.
|
||||
|
||||
**Q: Upscaled XXX looks not as great as I want**
|
||||
|
||||
@@ -96,4 +127,4 @@ A: Try out different engines (that's why we support so many) and try to use shar
|
||||
|
||||
**Q: How can I support you?**
|
||||
|
||||
A: You may contribute to this project by writing documentation, improving the website, adding plugins, fixing bugs, testing or by donating.
|
||||
A: You may contribute to this project by writing documentation, improving the website, adding plugins, fixing bugs, testing or by donating.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"abbr":"FSR",
|
||||
"abbr":"ffc",
|
||||
"displayName":"FidelityFX_CLI",
|
||||
"lastUsedFilePath":"sc",
|
||||
"fileNameBeginning":"ig",
|
||||
@@ -11,5 +11,7 @@
|
||||
"pluginCreator": "Janis Hutz",
|
||||
"pluginCreatorLink": "https://janishutz.com",
|
||||
"engineLink": "",
|
||||
"supports": [ "upscaling", "sharpening" ]
|
||||
"supports": [ "upscaling", "sharpening" ],
|
||||
"engineDownloadLink":"",
|
||||
"filesToInclude": [ "ffc.py" ]
|
||||
}
|
||||
@@ -11,30 +11,60 @@ class Scaler:
|
||||
self.tmppath = ''
|
||||
self.videometa = {}
|
||||
|
||||
def singleScaler ( self, input_path, output_path, scalefactor, threads, mode ):
|
||||
if self.os_type == 'linux':
|
||||
self.command = f'wine ./bin/lib/FidelityFX_CLI.exe -Mode { mode } -Scale {scalefactor} {scalefactor} {input_path} {output_path}'
|
||||
elif self.os_type == 'win32':
|
||||
self.command = f'FidelityFX_CLI -Mode { mode } -Scale {scalefactor} {scalefactor} {input_path} {output_path}'
|
||||
def singleScaler ( self, input_path, output_path, scalefactor, sharpening, threads, mode, tmppath ):
|
||||
scaler = 'FSR'
|
||||
if ( mode.upper() == 'HQC' ):
|
||||
scaler = 'HighQualityCubic'
|
||||
elif ( mode.upper() == 'C' ):
|
||||
scaler = 'Cubic'
|
||||
if ( sharpening == 0 ):
|
||||
output = output_path
|
||||
elif ( scalefactor != 0 and sharpening != 0 ):
|
||||
output = tmppath + 'tmpImage.' + output_path.split( '.' )[ 1 ]
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
output = input_path
|
||||
|
||||
if ( scalefactor != 0 ):
|
||||
if self.os_type == 'linux':
|
||||
self.command = f'wine ./bin/lib/FidelityFX_CLI.exe -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {input_path} {output}'
|
||||
elif self.os_type == 'win32':
|
||||
self.command = f'bin\\lib\\FidelityFX_CLI.exe -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {input_path} {output}'
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
|
||||
os.system( self.command )
|
||||
|
||||
if ( sharpening != 0 ):
|
||||
if self.os_type == 'linux':
|
||||
self.command = f'wine ./bin/lib/FidelityFX_CLI.exe -Mode CAS -Sharpness {sharpening} {output} {output_path}'
|
||||
elif self.os_type == 'win32':
|
||||
self.command = f'bin\\lib\\FidelityFX_CLI.exe -Mode CAS -Sharpness {sharpening} {output} {output_path}'
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
|
||||
os.system( self.command )
|
||||
|
||||
os.system( self.command )
|
||||
print( '\n\n==>Photo upscaled' );
|
||||
print( '\n\n==> Photo upscaled' );
|
||||
return True
|
||||
|
||||
def videoScaler ( self, tmppath, threads, scalefactor, sharpening, filetype, mode ):
|
||||
self.isScaling = True
|
||||
if ( scalefactor == 0 or scalefactor == None ):
|
||||
self.isScaling = False
|
||||
|
||||
self.isSharpening = True
|
||||
if sharpening != 0 and sharpening != None:
|
||||
self.isSharpening = False
|
||||
|
||||
# Locate Images and assemble FSR-Command
|
||||
self.file_list = []
|
||||
self.filelist = os.listdir( tmppath )
|
||||
self.filelist.pop(0)
|
||||
self.filelist.sort()
|
||||
self.number = 0
|
||||
if sharpening != 0 and sharpening != None:
|
||||
if self.isSharpening:
|
||||
for self.file in self.filelist:
|
||||
self.number += 1
|
||||
if ( self.os_type == 'win32' ):
|
||||
@@ -90,14 +120,14 @@ class Scaler:
|
||||
if ( i == self.threads - 1 ):
|
||||
for element in self.file_list:
|
||||
self.files += element;
|
||||
self.command_list.append( ( self.files, scalefactor, i, self.maxlength, self.os_type, mode ) )
|
||||
self.command_list.append( ( self.files, scalefactor, i, self.maxlength, self.os_type, mode, self.isSharpening ) )
|
||||
|
||||
self.pool = multiprocessing.Pool( self.threads )
|
||||
self.pool.starmap( upscalerEngine, self.command_list );
|
||||
self.pool.close();
|
||||
self.pool.join();
|
||||
|
||||
if sharpening != 0 and sharpening != None:
|
||||
if self.isSharpening:
|
||||
print( f'\n\n\n==> Sharpening using { self.threads } threads <==\n\n' );
|
||||
time.sleep( 2 );
|
||||
|
||||
@@ -153,7 +183,10 @@ class Scaler:
|
||||
|
||||
# Add return values
|
||||
|
||||
def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version ):
|
||||
def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version, isSharpening ):
|
||||
comparison = 'sc'
|
||||
if ( isSharpening ):
|
||||
comparison = 'up'
|
||||
scaler = 'FSR'
|
||||
if ( version.upper() == 'HQC' ):
|
||||
scaler = 'HighQualityCubic'
|
||||
@@ -167,7 +200,7 @@ def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version ):
|
||||
while files[maxlength - pos:maxlength - pos + 1] != ' ':
|
||||
pos += 1
|
||||
file_processing = files[:maxlength - pos]
|
||||
if file_processing[len(file_processing) - 14:len(file_processing) - 12] == 'ig':
|
||||
if file_processing[len(file_processing) - 17:len(file_processing) - 15] != comparison:
|
||||
pos += 5
|
||||
else:
|
||||
pass
|
||||
@@ -187,7 +220,7 @@ def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version ):
|
||||
while files[posy - pos:posy - pos + 1] != ' ':
|
||||
pos += 1
|
||||
file_processing = files[posx:posy - pos]
|
||||
if file_processing[len(file_processing) - 14:len(file_processing) - 12] == 'ig':
|
||||
if file_processing[len(file_processing) - 17:len(file_processing) - 15] != comparison:
|
||||
pos += 5
|
||||
while files[posy - pos:posy - pos + 1] != ' ':
|
||||
pos += 1
|
||||
@@ -209,7 +242,7 @@ def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version ):
|
||||
if os_type == 'linux':
|
||||
command_us = f'wine ./bin/lib/FidelityFX_CLI.exe -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {files_handle}'
|
||||
elif os_type == 'win32':
|
||||
command_us = f'FidelityFX_CLI -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {files_handle}'
|
||||
command_us = f'bin\\lib\\FidelityFX_CLI.exe -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {files_handle}'
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
@@ -235,7 +268,7 @@ def sharpeningEngine ( files, number, maxlength, os_type, sharpening, didUpscale
|
||||
pos += 1
|
||||
file_processing = files[:maxlength - pos]
|
||||
if ( didUpscale ):
|
||||
if file_processing[len(file_processing) - 14:len(file_processing) - 12] == 'up':
|
||||
if file_processing[len(file_processing) - 17:len(file_processing) - 15] == 'up':
|
||||
pos += 5
|
||||
else:
|
||||
if file_processing[len(file_processing) - 17:len(file_processing) - 15] == 'ru':
|
||||
@@ -283,7 +316,7 @@ def sharpeningEngine ( files, number, maxlength, os_type, sharpening, didUpscale
|
||||
if os_type == 'linux':
|
||||
command_sharpening = f'wine ./bin/lib/FidelityFX_CLI.exe -Mode CAS -Sharpness {sharpening} {files_handle}'
|
||||
elif os_type == 'win32':
|
||||
command_sharpening = f'FidelityFX_CLI -Mode CAS -Sharpness {sharpening} {files_handle}'
|
||||
command_sharpening = f'bin\\lib\\FidelityFX_CLI.exe -Mode CAS -Sharpness {sharpening} {files_handle}'
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
@@ -10,5 +10,7 @@
|
||||
"pluginCreator": "Janis Hutz",
|
||||
"pluginCreatorLink": "https://janishutz.com",
|
||||
"engineLink": "",
|
||||
"supports": [ "upscaling" ]
|
||||
"supports": [ "upscaling" ],
|
||||
"engineDownloadLink":"",
|
||||
"filesToInclude": [ "fsr.py" ]
|
||||
}
|
||||
@@ -11,17 +11,19 @@ class Scaler:
|
||||
self.tmppath = ""
|
||||
self.videometa = {}
|
||||
|
||||
def singleScaler ( self, input_path, output_path, scalefactor, threads, mode ):
|
||||
def singleScaler ( self, input_path, output_path, scalefactor, sharpening, threads, mode, tmppath ):
|
||||
modes = { 'av3':'realesr-animevideov3', 'x4plus': 'realesrgan-x4plus-anime' }
|
||||
if self.os_type == 'linux':
|
||||
self.command = f'wine ./bin/lib/FidelityFX_CLI.exe -Scale {scalefactor} {scalefactor} {input_path} {output_path} -n { mode }'
|
||||
self.command = f'wine ./bin/lib/realesrgan-ncnn-vulkan.exe -i {input_path} -o {output_path} -s {scalefactor} -j {threads}:{threads}:{threads} -n { modes[ mode ] }'
|
||||
elif self.os_type == 'win32':
|
||||
self.command = f'realesrgan-ncnn-vulkan -i {input_path} -o {output_path} -s {scalefactor} -j {threads}:{threads}:{threads} -n { mode }'
|
||||
self.command = f'bin\\lib\\realesrgan-ncnn-vulkan.exe -i {input_path} -o {output_path} -s {scalefactor} -j {threads}:{threads}:{threads} -n { modes[ mode ] }'
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||
return False
|
||||
|
||||
os.system( self.command )
|
||||
print( '\n\n==>Photo upscaled' );
|
||||
return True;
|
||||
|
||||
def videoScaler ( self, tmppath, threads, scalefactor, sharpening, filetype, mode ):
|
||||
modes = { 'av3':'realesr-animevideov3', 'x4plus': 'realesrgan-x4plus-anime' }
|
||||
@@ -33,7 +35,7 @@ class Scaler:
|
||||
except FileExistsError:
|
||||
pass
|
||||
if ( self.os_type == 'win32' ):
|
||||
self.command = f'realesrgan-ncnn-vulkan -i {tmppath} -o {tmppath}sc -s {scalefactor} -j {threads}:{threads}:{threads} -n {modes[ mode ]}'
|
||||
self.command = f'bin\\lib\\realesrgan-ncnn-vulkan.exe -i {tmppath} -o {tmppath}sc -s {scalefactor} -j {threads}:{threads}:{threads} -n {modes[ mode ]}'
|
||||
elif ( self.os_type == 'linux' ):
|
||||
self.command = f'wine ./bin/lib/realesrgan-ncnn-vulkan.exe -i {tmppath} -o {tmppath}sc -s {scalefactor} -j {threads}:{threads}:{threads} -n {modes[ mode ]}'
|
||||
os.system( self.command );
|
||||
@@ -1,5 +1,5 @@
|
||||
'''
|
||||
* FSRImageVideoUpscalerFrontend - handler.py
|
||||
* SimpleMediaUpscalerLite - handler.py
|
||||
*
|
||||
* Created by Janis Hutz 03/14/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
@@ -17,11 +17,16 @@ import json
|
||||
import importlib
|
||||
import shutil
|
||||
import time
|
||||
import tempfile
|
||||
|
||||
importedModules = {}
|
||||
|
||||
engineList = os.listdir( 'bin/engines' );
|
||||
engineList.pop( 0 )
|
||||
counter = 0;
|
||||
for element in engineList:
|
||||
if ( element == '__pycache__' ):
|
||||
engineList.pop( counter );
|
||||
counter += 1;
|
||||
|
||||
for element in engineList:
|
||||
importedModules[ element ] = importlib.import_module( 'bin.engines.' + element + '.' + element ).Scaler()
|
||||
@@ -43,12 +48,12 @@ class Handler:
|
||||
|
||||
def handler( self, filepath, scalefactor, output_path, sharpening, filetype, engine, mode, threads=4 ):
|
||||
# Function to be called when using this class as this function automatically determines if file is video or image
|
||||
print( '\n\n ImageVideoUpscaler - V1.1.0\n\n(c) 2023 ImageVideoUpscaler contributors\n\n\n\n' );
|
||||
print( '\n\n SimpleMediaUpscalerLite - V1.1.0\n\n(c) 2023 SimpleMediaUpscalerLite contributors\n\n\n\n' );
|
||||
|
||||
if self.os_type == 'linux':
|
||||
self.tmppath = config['PathSettings']['tmpPathLinux']
|
||||
self.tmppath = tempfile.gettempdir()
|
||||
elif self.os_type == 'win32':
|
||||
self.tmppath = config['PathSettings']['tmpPathWindows']
|
||||
self.tmppath = tempfile.gettempdir()
|
||||
else:
|
||||
print('OS CURRENTLY UNSUPPORTED!')
|
||||
return False
|
||||
@@ -67,27 +72,7 @@ class Handler:
|
||||
self.filepath += '\ '
|
||||
else:
|
||||
self.filepath += self.letter
|
||||
|
||||
# Determining filetype
|
||||
if str(filepath)[len(filepath) - 4:] == '.mp4' or str(filepath)[len(filepath) - 4:] == '.mkv' or str(filepath)[len(filepath) - 4:] == '.MP4':
|
||||
print( '\n\n==> Upscaling video' )
|
||||
self.video_scaling( filepath, output_path, scalefactor, threads, sharpening, filetype, mode, engine )
|
||||
elif str(filepath)[len(filepath) - 4:] == '.JPG' or str(filepath)[len(filepath) - 4:] == '.png' or str(filepath)[len(filepath) - 4:] == '.jpg' or str(filepath)[len(filepath) - 5:] == '.jpeg':
|
||||
print( '\n==>upscaling image' )
|
||||
self.photo_scaling( scalefactor, output_path, engine )
|
||||
else:
|
||||
print('not supported')
|
||||
return False
|
||||
|
||||
def photo_scaling(self, scalefactor, output_path, engine, mode):
|
||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
||||
pass
|
||||
|
||||
def video_scaling( self, input_path, output_path, scalefactor, threads, sharpening, filetype, mode, engine ):
|
||||
self.engineSetting = json.load( open( 'bin/engines/' + engine + '/config.json' ) )
|
||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
||||
|
||||
# Splitting video into frames
|
||||
|
||||
try:
|
||||
shutil.rmtree(self.tmppath)
|
||||
except FileNotFoundError:
|
||||
@@ -97,6 +82,27 @@ class Handler:
|
||||
except FileExistsError:
|
||||
print( '==> ERROR: Temp path does not exist! <==' )
|
||||
return False
|
||||
|
||||
# Determining filetype
|
||||
if str(filepath)[len(filepath) - 4:] == '.mp4' or str(filepath)[len(filepath) - 4:] == '.mkv' or str(filepath)[len(filepath) - 4:] == '.MP4':
|
||||
print( '\n\n==> Upscaling video' )
|
||||
return self.video_scaling( filepath, output_path, scalefactor, threads, sharpening, filetype, mode, engine )
|
||||
elif str(filepath)[len(filepath) - 4:] == '.JPG' or str(filepath)[len(filepath) - 4:] == '.png' or str(filepath)[len(filepath) - 4:] == '.jpg' or str(filepath)[len(filepath) - 5:] == '.jpeg':
|
||||
print( '\n==> Upscaling Image' )
|
||||
return self.photo_scaling( filepath, output_path, scalefactor, sharpening, threads, engine, mode )
|
||||
else:
|
||||
print('not supported')
|
||||
return False
|
||||
|
||||
def photo_scaling(self, input_path, output_path, scalefactor, sharpening, threads, engine, mode ):
|
||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
||||
return importedModules[ engine ].singleScaler( input_path, output_path, scalefactor, sharpening, threads, mode, self.tmppath );
|
||||
|
||||
def video_scaling( self, input_path, output_path, scalefactor, threads, sharpening, filetype, mode, engine ):
|
||||
self.engineSetting = json.load( open( 'bin/engines/' + engine + '/config.json' ) )
|
||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
||||
|
||||
# Splitting video into frames
|
||||
|
||||
print( '\n==> Created directory' )
|
||||
|
||||
@@ -113,7 +119,11 @@ class Handler:
|
||||
|
||||
# Retrieving Video metadata
|
||||
self.filelist = os.listdir(self.tmppath)
|
||||
self.videometa = ffmpeg.probe(str(input_path))['streams'].pop(0)
|
||||
try:
|
||||
self.videometa = ffmpeg.probe(str(input_path))['streams'].pop(0)
|
||||
except Exception:
|
||||
print( '\n\n==> Failed to execute ffprobe. Please ensure that you have a valid ffmpeg & ffprobe installation.\n --> Refer to our wiki for a guide on a proper installation\n\n')
|
||||
return False;
|
||||
|
||||
self.duration = self.videometa.get( 'duration' )
|
||||
self.frames = len( self.filelist )
|
||||
@@ -162,6 +172,9 @@ class Handler:
|
||||
|
||||
# reassemble Video
|
||||
print( '\n\n==> Reassembling Video... with framerate @', self.framerate, '\n\n' )
|
||||
|
||||
time.wait( 2 )
|
||||
|
||||
if self.os_type == 'linux':
|
||||
self.command = f'ffmpeg -framerate {self.framerate} -i {self.tmppath}{self.engineSetting[ "lastUsedFilePath" ]}/{self.engineSetting[ "fileNameBeginning" ]}%08d.{filetype} {output_path} -i {self.tmppath}audio.aac'
|
||||
elif self.os_type == 'win32':
|
||||
@@ -169,4 +182,6 @@ class Handler:
|
||||
else:
|
||||
print( 'OS CURRENTLY UNSUPPORTED!' );
|
||||
return False
|
||||
os.system( self.command )
|
||||
os.system( self.command )
|
||||
|
||||
return True;
|
||||
9
bin/pluginDownloader.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
* SimpleMediaUpscalerLite - pluginDownloader.py
|
||||
*
|
||||
* Created by Janis Hutz 05/31/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
[PathSettings]
|
||||
defaultOutputPath = $HOME/FSRImageVideoUpscaler/
|
||||
tmpPathLinux = /tmp/
|
||||
tmpPathWindows = C:\temp
|
||||
defaultOutputPath = $HOME/FSRSimpleMediaUpscalerLite/
|
||||
|
||||
[DevSettings]
|
||||
loggerReqLevel = DEBUG
|
||||
@@ -1,4 +1,4 @@
|
||||
# imagevideoupscaler
|
||||
# SimpleMediaUpscalerLite
|
||||
|
||||
## Project setup
|
||||
```
|
||||
|
||||
BIN
frontend/logo.png
Executable file
|
After Width: | Height: | Size: 592 KiB |
372
frontend/package-lock.json
generated
@@ -1,6 +1,20 @@
|
||||
{
|
||||
"name": "imagevideoupscaler",
|
||||
"version": "0.1.0",
|
||||
"name": "SimpleMediaUpscalerLite",
|
||||
"version": "2.0.0",
|
||||
"maintainers": [
|
||||
"Janis Hutz <development@janishutz.com>"
|
||||
],
|
||||
"description": "An Electron frontend to the SimpleMediaUpscalerLite-CLI",
|
||||
"homepage": "https://janishutz.com/scaler.html",
|
||||
"author": {
|
||||
"name": "Janis Hutz",
|
||||
"email": "development@janishutz.com",
|
||||
"url": "https://janishutz.com"
|
||||
},
|
||||
"license": "GPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/simplePCBuilding/SimpleMediaUpscalerLite/issues"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
@@ -13,8 +27,9 @@
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"child_process": "^1.0.2",
|
||||
"core-js": "^3.8.3",
|
||||
"electron": "^24.3.1",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3"
|
||||
},
|
||||
@@ -25,6 +40,7 @@
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"electron": "^24.4.1",
|
||||
"electron-devtools-installer": "^3.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
|
||||
0
frontend/public/lang/about/en.json
Normal file
0
frontend/public/lang/home/en.json
Normal file
0
frontend/public/lang/settings/en.json
Normal file
@@ -2,6 +2,8 @@
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
<!-- |
|
||||
<router-link to="/settings">Settings</router-link> -->
|
||||
</nav>
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition :name="route.meta.transition || 'scale'" mode="out-in">
|
||||
@@ -49,13 +51,17 @@ export default {
|
||||
<style>
|
||||
:root, :root.light {
|
||||
--background-color: rgb(224, 222, 222);
|
||||
--dialog-color: rgb(243, 241, 241);
|
||||
--foreground-color: #2c3e50;
|
||||
--highlight-color: rgb(221, 0, 0);
|
||||
--input-color: rgb(150, 150, 150);
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--background-color: rgb(34, 34, 34);
|
||||
--foreground-color: white;
|
||||
--dialog-color: rgb(51, 51, 51);
|
||||
--input-color: rgb(121, 121, 121);
|
||||
}
|
||||
|
||||
body, html {
|
||||
|
||||
40
frontend/src/app.js
Normal file
@@ -0,0 +1,40 @@
|
||||
module.exports = function ( win ) {
|
||||
const dialog = require( 'electron' ).dialog;
|
||||
const upscaling = require( './upscalingHandler.js' );
|
||||
const upscalingHandler = new upscaling();
|
||||
const ipcMain = require( 'electron' ).ipcMain;
|
||||
|
||||
ipcMain.on( 'selectInputFile', ( event, data ) => {
|
||||
event.reply( 'selectInputFile', { 'data': dialog.showOpenDialogSync( {
|
||||
properties: [ 'openFile' ],
|
||||
title: 'Select an input file to upscale',
|
||||
filters: [
|
||||
{ name: 'Images (.jpg, .png)', extensions: ['jpg', 'png'] },
|
||||
{ name: 'Movies (.mkv, .mp4)', extensions: ['mkv', 'mp4'] },
|
||||
{ name: 'All Files', extensions: ['*'] }
|
||||
]
|
||||
} ) } );
|
||||
} );
|
||||
|
||||
ipcMain.on( 'selectOutputFile', ( event, data ) => {
|
||||
event.reply( 'selectOutputFile', { 'data': dialog.showSaveDialogSync( {
|
||||
properties: [ 'promptToCreate' ],
|
||||
title: 'Select an output file',
|
||||
filters: [
|
||||
{ name: 'Images (.jpg, .png)', extensions: ['jpg', 'png'] },
|
||||
{ name: 'Movies (.mkv, .mp4)', extensions: ['mkv', 'mp4'] },
|
||||
{ name: 'All Files', extensions: ['*'] }
|
||||
]
|
||||
} ) } );
|
||||
} );
|
||||
|
||||
ipcMain.on( 'startUpscaling', ( event, data ) => {
|
||||
let checks = upscalingHandler.verifyDataIntegrity( JSON.parse( data ), ipcMain );
|
||||
if ( checks[ 0 ] ) {
|
||||
event.reply( 'startUpscaling', { 'data': checks[ 1 ] } );
|
||||
upscalingHandler.upscale( JSON.parse( data ), win );
|
||||
} else {
|
||||
event.reply( 'startUpscaling', { 'data': checks[ 1 ] } );
|
||||
}
|
||||
} );
|
||||
}
|
||||
BIN
frontend/src/assets/logo.png
Normal file → Executable file
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 592 KiB |
@@ -1,9 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
import { app, protocol, BrowserWindow } from 'electron'
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
|
||||
import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
import { app, protocol, BrowserWindow } from 'electron';
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
|
||||
import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer';
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
const path = require( 'path' );
|
||||
|
||||
|
||||
// Scheme must be registered before the app is ready
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
@@ -20,10 +22,10 @@ async function createWindow() {
|
||||
// Use pluginOptions.nodeIntegration, leave this alone
|
||||
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
|
||||
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
// Load the url of the dev server if in development mode
|
||||
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
|
||||
@@ -33,6 +35,7 @@ async function createWindow() {
|
||||
// Load the index.html when not in development
|
||||
win.loadURL('app://./index.html')
|
||||
}
|
||||
require( './app.js' )( win );
|
||||
}
|
||||
|
||||
// Quit when all windows are closed.
|
||||
|
||||
@@ -10,10 +10,12 @@ const routes = [
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
|
||||
component: () => import( '../views/AboutView.vue' )
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'settings',
|
||||
component: () => import( '../views/SettingsView.vue' )
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
92
frontend/src/upscalingHandler.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SimpleMediaUpscalerLite - upscalingHandler.js
|
||||
*
|
||||
* Created by Janis Hutz 06/03/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
const child_process = require( 'child_process' );
|
||||
const process = require( 'process' );
|
||||
const Notification = require( 'electron' ).Notification;
|
||||
|
||||
|
||||
class UpscalingHandler {
|
||||
constructor () {
|
||||
this.os = process.platform
|
||||
}
|
||||
|
||||
upscale( options, win ) {
|
||||
// required options: engine, algorithm, scale, sharpening, InputFile & OutputFile
|
||||
// Options is an object!
|
||||
|
||||
let baseCommand = '';
|
||||
// Create cli command to upscale
|
||||
if ( this.os === 'linux' ) {
|
||||
baseCommand = './smuL-cli';
|
||||
} else if ( this.os === 'win32' ) {
|
||||
baseCommand = 'smuL-cli.exe';
|
||||
}
|
||||
|
||||
|
||||
let args = []
|
||||
args.push( '-i' + options.InputFile );
|
||||
args.push( '-o' + options.OutputFile );
|
||||
|
||||
if ( options.scale != 0 ) {
|
||||
args.push( '-s' + options.scale );
|
||||
}
|
||||
|
||||
if ( options.sharpening != 0 ) {
|
||||
args.push( '-S' + options.sharpening );
|
||||
}
|
||||
|
||||
args.push( '-M' + options.algorithm );
|
||||
args.push( '-E' + options.engine );
|
||||
// add additional options
|
||||
// baseCommand += + ' -S ' + options.sharpening
|
||||
// baseCommand += ' -E ' + options.engine + ' -M ' + options.algorithm
|
||||
|
||||
console.log( 'upscaling' );
|
||||
|
||||
console.log( args );
|
||||
|
||||
let child = child_process.spawn( baseCommand, args );
|
||||
|
||||
child.stdout.on( 'data', data => {
|
||||
console.log( '' + data );
|
||||
win.send( 'progress', '\n' + data );
|
||||
} );
|
||||
|
||||
child.stderr.on( 'data', ( data ) => {
|
||||
console.error(`stderr: ${ data }`);
|
||||
win.send( 'progress', '\n' + data );
|
||||
} );
|
||||
|
||||
child.on( 'error', ( error ) => {
|
||||
console.log( 'An error occurred' + error );
|
||||
win.send( 'error', 'An error occurred during upscaling. (Error message: ' + error.message + ')' );
|
||||
new Notification( { title: `SimpleMediaUpscalerLite - Error whilst upscaling', body: 'Your upscaling Job encountered an error whilst upscaling. (Error message: ${ error.message }).`} ).show();
|
||||
} );
|
||||
|
||||
child.on( 'close', ( code ) => {
|
||||
win.send( 'finish', 'Your upscaling job finished with exit code ' + code + '. You may find its output here: ' + options.OutputFile );
|
||||
new Notification( { title: `SimpleMediaUpscalerLite - Job complete', body: 'Your Upscaling job has completed successfully (Code ${ code }). You may find its output here: ` + options.OutputFile } ).show();
|
||||
} );
|
||||
}
|
||||
|
||||
verifyDataIntegrity ( data ) {
|
||||
if ( data[ 'InputFile' ] && data[ 'OutputFile' ] && data[ 'engine' ] && data[ 'algorithm' ] && 1 < data[ 'scale' ] <= 4 && 0 <= data[ 'sharpening' ] <= 1 ) {
|
||||
if ( data[ 'InputFile' ][ 0 ].substring( data[ 'InputFile' ][ 0 ].length - 4 ) == data[ 'OutputFile' ].substring( data[ 'OutputFile' ].length - 4 ) ) {
|
||||
return [ true, 'upscaling' ];
|
||||
} else {
|
||||
return [ false, 'differentFileExtensions' ];
|
||||
}
|
||||
} else {
|
||||
return [ false, 'dataMissing' ];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UpscalingHandler;
|
||||
@@ -1,22 +1,10 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<img src="@/assets/logo.png">
|
||||
<h1>About ImageVideoUpscaler</h1>
|
||||
<p>ImageVideoUpscaler is an application that allows you to upscale your videos and / or images. It uses an Electron GUI (Graphical User Interface) and a Python CLI (Command Line Interface).</p>
|
||||
<h3>Contributors</h3>
|
||||
<ul>
|
||||
<li>Janis Hutz (simplePCBuilding): Maintainer, CLI & GUI development, Packaging</li>
|
||||
<li>ThatPlasma: App name, Logo, testing, Windows installer</li>
|
||||
</ul>
|
||||
<img src="@/assets/logo.png" style="height: 30vh;">
|
||||
<h1>About SimpleMediaUpscalerLite</h1>
|
||||
<p>SimpleMediaUpscalerLite is an application that allows you to upscale your videos and / or images. It uses an Electron GUI (Graphical User Interface) and a Python CLI (Command Line Interface).</p>
|
||||
<div class="version-info">
|
||||
<h3>You are currently running version 1.1.0</h3>
|
||||
<h3>Changelog</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Version 1.0
|
||||
<ul></ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>You are currently running version {{ appVersion }}. {{ versionNotice[ isUpToDate ] }}.</h3>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -25,14 +13,21 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
version: '',
|
||||
versionNotice: { true: '==> up to date', false: '==> New version available' },
|
||||
appVersion: 'V2.0.0',
|
||||
latestVersion: '',
|
||||
isUpToDate: true,
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
fetch( 'https://github.com/simplePCBuilding/ImageVideoUpscaler/blob/master/package.json' ).then( res => {
|
||||
console.log( res );
|
||||
})
|
||||
fetch( 'https://api.github.com/repos/simplePCBuilding/SimpleMediaUpscalerLite/releases/latest' ).then( res => {
|
||||
res.json().then( data => {
|
||||
this.latestVersion = data.tag_name;
|
||||
if ( data.tag_name != this.appVersion ) {
|
||||
this.isUpToDate = false;
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,308 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<h1>ImageVideoUpscaler</h1>
|
||||
<h1>SimpleMediaUpscalerLite</h1>
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<tr id="group1" class="group">
|
||||
<td>
|
||||
<label for="algorithm">Upscaler engine</label><br>
|
||||
<select name="engine" id="engine" v-model="upscaleSettings.engine">
|
||||
<option v-for="engine in engines" :key="engine.id" :value="engine.id">{{ engine.displayName }}</option>
|
||||
</select><br>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<label for="algorithm">Upscaling algorithm</label><br>
|
||||
<select name="algorithm" id="algorithm" v-model="upscaleSettings.algorithm">
|
||||
<option v-for="engine in engines[ upscaleSettings.engine ][ 'modes' ]" :key="engine.id" :value="engine.id">{{ engine.displayName }}</option>
|
||||
</select><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="group2" class="group">
|
||||
<td v-if="engines[ upscaleSettings.engine ][ 'supports' ].includes( 'upscaling' )">
|
||||
<label for="scale">Scale factor</label><br>
|
||||
<input type="number" name="scale" id="scale" v-model="upscaleSettings.scale" min="2" max="4" onkeydown="return false">x<br>
|
||||
</td>
|
||||
|
||||
<td v-if="engines[ upscaleSettings.engine ][ 'supports' ].includes( 'sharpening' )">
|
||||
<label for="sharpening">Sharpening factor</label><br>
|
||||
<input type="number" step="0.01" name="scale" id="scale" v-model="upscaleSettings.sharpening" min="0" max="1"><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="group3" class="group">
|
||||
<td>
|
||||
<button @click="runCommand( 'InputFile' )">Input file</button><br>
|
||||
<div v-if="upscaleSettings.InputFile[ 0 ]" id="inputCheck" @mouseenter="showElement( 'inputfile' )" @mouseleave="hideElement( 'inputfile' )">✔</div>
|
||||
<div class="info-container">
|
||||
<div class="info" id="inputfile">
|
||||
{{ upscaleSettings.InputFile[ 0 ] }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button @click="runCommand( 'OutputFile' )">Output file</button><br>
|
||||
<div v-if="upscaleSettings.OutputFile" id="outputCheck" @mouseenter="showElement( 'outputfile' )" @mouseleave="hideElement( 'outputfile' )">✔</div>
|
||||
<div class="info-container">
|
||||
<div class="info" id="outputfile">
|
||||
{{ upscaleSettings.OutputFile }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button @click="start()" id="start">Start upscaling</button>
|
||||
</div>
|
||||
|
||||
<div class="output-box-wrapper">
|
||||
<p id="cmd" @click="showCmdOutput()">Command output</p>
|
||||
<div class="output-box" id="output" v-html="output">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog id="processing">
|
||||
<div class="dialog-container">
|
||||
Your file is being processed. You will be notified when the upscaling process has finished.
|
||||
<form method="dialog">
|
||||
<button>OK</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="wrong">
|
||||
<div class="dialog-container">
|
||||
Some entries are missing. Please ensure that you have specified an input file!
|
||||
<form method="dialog">
|
||||
<button>OK</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="completed">
|
||||
<div class="dialog-container">
|
||||
<p style="width: 90%; word-wrap: break-word;">{{ finishMessage }}</p>
|
||||
<form method="dialog">
|
||||
<button>OK</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="error">
|
||||
<div class="dialog-container">
|
||||
<p style="width: 90%; word-wrap: break-word;">{{ errorMessage }}</p>
|
||||
<form method="dialog">
|
||||
<button>OK</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="fileExtension">
|
||||
<div class="dialog-container">
|
||||
File extension of input and output file don't match! Please ensure that they are the same.
|
||||
Click the button below to fix it.
|
||||
<button @click="fixFileExtension();">Fix</button>
|
||||
<p v-if="fixed">Fixed!</p>
|
||||
<form method="dialog">
|
||||
<button @click="this.fixed = false;">OK</button>
|
||||
</form>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
export default {
|
||||
name: 'HomeView',
|
||||
data() {
|
||||
return {
|
||||
upscaleSettings: { 'engine': 'ffc', 'algorithm': 'fsr', 'scale': 2, 'sharpening': 0, 'InputFile': [], 'OutputFile': '' },
|
||||
engines: { 'ffc':{ 'displayName': 'FidelityFX CLI', 'id': 'ffc', 'modes': { 'fsr': { 'displayName': 'FidelityFX Super Resolution', 'id': 'fsr' }, 'c': { 'displayName': 'Cubic', 'id': 'c' }, 'hqc': { 'displayName': 'High Quality Cubic', 'id': 'hqc' } }, 'supports': [ 'upscaling', 'sharpening' ] }, 'ss':{ 'displayName': 'REAL-ESRGAN', 'id': 'ss', 'modes': { 'av3': { 'displayName': 'realesr-animevideov3', 'id': 'av3' }, 'x4plus': { 'displayName': 'realesrgan-x4plus-anime', 'id': 'x4plus' } }, 'supports': [ 'upscaling' ] } },
|
||||
fixed: false,
|
||||
output: '',
|
||||
finishMessage: '',
|
||||
errorMessage: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
runCommand ( command ) {
|
||||
ipcRenderer.send( 'select' + command );
|
||||
ipcRenderer.on( 'select' + command, ( event, data ) => {
|
||||
if ( command == 'InputFile' ) {
|
||||
this.upscaleSettings[ 'OutputFile' ] = data[ 'data' ][ 0 ].substring( 0, data[ 'data' ][ 0 ].length - 4 ) + '_upscaled' + data[ 'data' ][ 0 ].substring( data[ 'data' ][ 0 ].length - 4 );
|
||||
}
|
||||
this.upscaleSettings[ command ] = data[ 'data' ];
|
||||
} );
|
||||
},
|
||||
start() {
|
||||
this.output = '';
|
||||
ipcRenderer.send( 'startUpscaling', JSON.stringify ( this.upscaleSettings ) );
|
||||
ipcRenderer.on( 'startUpscaling', ( event, data ) => {
|
||||
if ( data.data == 'upscaling' ) {
|
||||
try {
|
||||
document.getElementById( 'processing' ).showModal();
|
||||
} catch ( error ) {
|
||||
console.log( error );
|
||||
}
|
||||
} else if ( data.data == 'dataMissing' ) {
|
||||
document.getElementById( 'wrong' ).showModal();
|
||||
} else {
|
||||
document.getElementById( 'fileExtension' ).showModal();
|
||||
}
|
||||
} );
|
||||
|
||||
let self = this;
|
||||
|
||||
ipcRenderer.on( 'progress', function ( evt, message ) {
|
||||
self.output = message + self.output;
|
||||
});
|
||||
|
||||
ipcRenderer.on( 'finish', function ( evt, message ) {
|
||||
if ( self.errorMessage == '' ) {
|
||||
self.finishMessage = message;
|
||||
try {
|
||||
document.getElementById( 'processing' ).close();
|
||||
document.getElementById( 'completed' ).showModal();
|
||||
} catch ( error ) {
|
||||
console.log( error );
|
||||
}
|
||||
}
|
||||
} )
|
||||
|
||||
ipcRenderer.on( 'error', function ( evt, message ) {
|
||||
self.errorMessage = message;
|
||||
try {
|
||||
document.getElementById( 'processing' ).close();
|
||||
document.getElementById( 'error' ).showModal();
|
||||
} catch ( error ) {
|
||||
console.log( error );
|
||||
}
|
||||
} )
|
||||
},
|
||||
showCmdOutput () {
|
||||
document.getElementById( 'output' ).classList.toggle( 'shown' );
|
||||
},
|
||||
fixFileExtension () {
|
||||
let fileExtension = this.upscaleSettings.InputFile[ 0 ].substring( this.upscaleSettings.InputFile[ 0 ].length - 4 );
|
||||
this.upscaleSettings.OutputFile = this.upscaleSettings.OutputFile.slice( 0, this.upscaleSettings.OutputFile[ 0 ].length - 5 ) + fileExtension;
|
||||
this.fixed = true;
|
||||
},
|
||||
showElement( element ) {
|
||||
document.getElementById( element ).classList.add( 'shown' );
|
||||
},
|
||||
hideElement( element ) {
|
||||
document.getElementById( element ).classList.remove( 'shown' );
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.info-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: var( --dialog-color );
|
||||
padding: 2vw;
|
||||
width: 20vw;
|
||||
height: 20vh;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.shown {
|
||||
display: block;
|
||||
}
|
||||
.table-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 3vw 0;
|
||||
}
|
||||
|
||||
#start {
|
||||
margin-top: 5vh;
|
||||
padding: 1vw 2vw;
|
||||
margin-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var( --input-color );
|
||||
margin-top: 1vw;
|
||||
padding: 0.5vw 1vw;
|
||||
border-radius: 20px;
|
||||
border-style: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #42b983;
|
||||
}
|
||||
|
||||
input, select {
|
||||
background-color: var( --input-color );
|
||||
margin-bottom: 1vw;
|
||||
margin-top: 0.3vw;
|
||||
padding: 0.5vw 1vw;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.output-box-wrapper {
|
||||
margin-top: 3%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.output-box {
|
||||
display: none;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
word-wrap: normal;
|
||||
height: 20vh;
|
||||
width: 60%;
|
||||
text-align: justify;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dialog {
|
||||
border-radius: 10px;
|
||||
height: 30vh;
|
||||
width: 30vw;
|
||||
background-color: var( --background-color );
|
||||
border-style: none;
|
||||
color: var( --primary-color );
|
||||
}
|
||||
|
||||
.dialog-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#cmd {
|
||||
text-align: justify;
|
||||
width: 60%;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
30
frontend/src/views/SettingsView.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>Settings</h1>
|
||||
<p>WIP!</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
engines: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
run() {
|
||||
fetch( 'http://127.0.0.1:49369/api/getEngines' ).then( res => {
|
||||
console.log( res );
|
||||
res.json().then( data => {
|
||||
this.engines = data.body;
|
||||
} );
|
||||
} ).catch( error => {
|
||||
console.log( error );
|
||||
} );
|
||||
}
|
||||
},
|
||||
created() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,4 +1,27 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true
|
||||
})
|
||||
module.exports = {
|
||||
pluginOptions: {
|
||||
electronBuilder: {
|
||||
nodeIntegration: true,
|
||||
"appId": "com.janishutz.smuL",
|
||||
"copyright": "Copyright (c) 2023 SimpleMediaUpscalerLite contributors",
|
||||
"buildVersion": "V2.0.0-dev2",
|
||||
builderOptions: {
|
||||
files: [
|
||||
"**/*",
|
||||
{
|
||||
from: "./*",
|
||||
to: "./*",
|
||||
filter: [ "**/*" ]
|
||||
}
|
||||
],
|
||||
extraFiles: [
|
||||
{
|
||||
from: "./lib",
|
||||
to: "./",
|
||||
filter: [ "**/*" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
logo.png
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 592 KiB |
11
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "imagevideoupscaler",
|
||||
"version": "1.0.0",
|
||||
"name": "SimpleMediaUpscalerLite",
|
||||
"version": "2.0.0",
|
||||
"description": "A frontend to upscale your videos and images using different upscale engines",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend.git"
|
||||
"url": "git+https://github.com/simplePCBuilding/SimpleMediaUpscalerLite.git"
|
||||
},
|
||||
"keywords": [
|
||||
"upscaler",
|
||||
@@ -21,7 +21,8 @@
|
||||
"author": "Janis Hutz",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend/issues"
|
||||
"url": "https://github.com/simplePCBuilding/SimpleMediaUpscalerLite/issues",
|
||||
"email": "development@janishutz.com"
|
||||
},
|
||||
"homepage": "https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend#readme"
|
||||
"homepage": "https://github.com/simplePCBuilding/SimpleMediaUpscalerLite#readme"
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=FSR Image & Video Upscaler
|
||||
Comment=Upscale your videos and images with FSR
|
||||
Path=/opt/fsrimageupscaler
|
||||
Exec=/opt/fsrimageupscaler/FSR\ Image\ \&\ Video\ Upscaler
|
||||
Icon=fsrimageupscaler
|
||||
|
Before Width: | Height: | Size: 43 KiB |
60
packaging/package.sh
Normal file → Executable file
@@ -2,17 +2,53 @@
|
||||
|
||||
cd ..
|
||||
|
||||
# Make linux executable
|
||||
pyinstaller imagevideoupscaler-cli.spec
|
||||
mv -r ./dist/imagevideupscaler ./dist/imagevideupscaler-linux
|
||||
cp -r ./bin ./dist/imagevideupscaler-linux
|
||||
cp -r ./config ./dist/imagevideupscaler-linux
|
||||
cp ./imagevideupscaler-cli.py ./dist/imagevideupscaler-linux
|
||||
cp ./LICENSE ./dist/imagevideupscaler-linux
|
||||
cp ./logo.png ./dist/imagevideupscaler-linux
|
||||
# Compile for Linux
|
||||
python -m PyInstaller smuL-cli.spec
|
||||
|
||||
# package rpm & deb
|
||||
# TODO: create packager
|
||||
mkdir ./frontend/lib/
|
||||
cp -rv ./dist/smuL-cli/* ./frontend/lib/
|
||||
|
||||
# Make windows executable
|
||||
# TODO: create compiler
|
||||
|
||||
# Copy python files
|
||||
cp -rv ./bin ./frontend/lib/
|
||||
cp -rv ./config ./frontend/lib/
|
||||
cp -v ./smuL-cli.py ./frontend/lib/
|
||||
cp -v ./LICENSE ./frontend/lib/
|
||||
cp -v ./logo.png ./frontend/lib/
|
||||
|
||||
|
||||
# package for Linux (includes GUI & CLI)
|
||||
cd frontend
|
||||
rm -rf ./dist_electron
|
||||
npm run electron:build -- --linux deb rpm
|
||||
|
||||
rm -rf ./lib/libdynload
|
||||
rm ./lib/smuL*
|
||||
rm ./lib/lib*
|
||||
rm ./lib/ld*
|
||||
rm ./lib/base_library.zip
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
|
||||
printf '\n\n==> Finished Linux packaging, preparing Windows\n\n'
|
||||
|
||||
# Compile for Windows
|
||||
wine python -m PyInstaller smuL-cli.spec
|
||||
cp -rv ./dist/smuL-cli/* ./frontend/lib/
|
||||
cp -v ./smuL-cli.py ./frontend/lib/
|
||||
|
||||
# package for Windows (includes GUI & CLI)
|
||||
cd frontend
|
||||
npm run electron:build -- --win nsis
|
||||
|
||||
rm -rf ./lib
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
|
||||
printf '\n\n==> DONE\n\n'
|
||||
30
packaging/packageLinux.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#! /bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
# Compile for Linux
|
||||
python -m PyInstaller smuL-cli.spec
|
||||
cp -r ./dist/smuL-cli/* ./frontend/lib/
|
||||
|
||||
|
||||
# Copy python files
|
||||
cp -r ./bin ./frontend/lib/
|
||||
cp -r ./config ./frontend/lib/
|
||||
cp ./smuL-cli.py ./frontend/lib/
|
||||
cp ./LICENSE ./frontend/lib/
|
||||
cp ./logo.png ./frontend/lib/
|
||||
|
||||
|
||||
# package for Linux (includes GUI & CLI)
|
||||
cd frontend
|
||||
rm -rf ./dist_electron
|
||||
npm run electron:build -- --linux deb rpm
|
||||
|
||||
rm -rf ./lib
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
|
||||
printf '\n\n==> DONE\n\n'
|
||||
31
packaging/packageTesting.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#! /bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
# Compile for Linux
|
||||
python -m PyInstaller smuL-cli.spec
|
||||
mkdir ./frontend/lib
|
||||
cp -r ./dist/smuL-cli/* ./frontend/lib/
|
||||
|
||||
|
||||
# Copy python files
|
||||
cp -r ./bin ./frontend/lib/
|
||||
cp -r ./config ./frontend/lib/
|
||||
cp ./smuL-cli.py ./frontend/lib/
|
||||
cp ./LICENSE ./frontend/lib/
|
||||
cp ./logo.png ./frontend/lib/
|
||||
|
||||
|
||||
# package for Linux (includes GUI & CLI)
|
||||
cd frontend
|
||||
rm -rf ./dist_electron
|
||||
npm run electron:build -- --linux zip
|
||||
|
||||
rm -rf ./lib
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
|
||||
printf '\n\n==> DONE\n\n'
|
||||
31
packaging/packageWindows.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#! /bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
# Compile for Windows
|
||||
wine python -m PyInstaller smuL-cli.spec
|
||||
|
||||
mkdir ./frontend/lib
|
||||
|
||||
cp -r ./dist/smuL-cli/* ./frontend/lib/
|
||||
|
||||
# Copy python files
|
||||
cp -rv ./bin ./frontend/lib/
|
||||
cp -rv ./config ./frontend/lib/
|
||||
cp -v ./smuL-cli.py ./frontend/lib/
|
||||
cp -v ./LICENSE ./frontend/lib/
|
||||
cp -v ./logo.png ./frontend/lib/
|
||||
|
||||
# package for Windows (includes GUI & CLI)
|
||||
cd frontend
|
||||
rm -rf ./dist_electron
|
||||
npm run electron:build -- --win nsis
|
||||
|
||||
rm -rf ./lib
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
|
||||
printf '\n\n==> DONE\n\n'
|
||||
6
packaging/prepareWindowsPackaging.sh
Normal file → Executable file
@@ -1,5 +1,7 @@
|
||||
curl -o ./pythonInstaller.exe https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe
|
||||
curl -o ./pythonInstaller.exe https://www.python.org/ftp/python/3.11.3/python-3.11.3-amd64.exe
|
||||
|
||||
wine pythonInstaller.exe
|
||||
|
||||
currentPath = pwd
|
||||
wine python -m pip install pyinstaller
|
||||
|
||||
printf '\n\n==> Done installing python for windows\n\n'
|
||||
15
packaging/startTesting.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#! /bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
# Compile for Linux
|
||||
python -m PyInstaller smuL-cli.spec
|
||||
cp -r ./dist/smuL-cli/* ./frontend/
|
||||
|
||||
|
||||
# Copy python files
|
||||
cp -r ./bin ./frontend/
|
||||
cp -r ./config ./frontend/
|
||||
cp ./smuL-cli.py ./frontend/
|
||||
cp ./LICENSE ./frontend/
|
||||
cp ./logo.png ./frontend/
|
||||
21
packaging/stopTesting.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#! /bin/bash
|
||||
|
||||
cd ../frontend
|
||||
|
||||
rm -rf ./bin
|
||||
rm -rf ./config
|
||||
rm -rf ./lib-dynload
|
||||
rm -rf ./libdynload
|
||||
rm ./smuL*
|
||||
rm ./lib*
|
||||
rm ./ld*
|
||||
rm ./base_library.zip
|
||||
rm ./LICENSE
|
||||
rm ./_*
|
||||
rm ./*.dll
|
||||
rm ./*.pyd
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./dist
|
||||
3
plugins/plugins.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"fsr": { "displayName":"AMD FidelityFX Super Resolution" }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
* FSRImageVideoUpscalerFrontend - fsrimagevideoupscaler-cli.py
|
||||
* SimpleMediaUpscalerLite - fsrSimpleMediaUpscalerLite-cli.py
|
||||
*
|
||||
* Created by Janis Hutz 03/15/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
@@ -14,7 +14,11 @@ import multiprocessing
|
||||
import json
|
||||
|
||||
engineList = os.listdir( 'bin/engines' );
|
||||
engineList.pop( 0 )
|
||||
counter = 0;
|
||||
for element in engineList:
|
||||
if ( element == '__pycache__' ):
|
||||
engineList.pop( counter );
|
||||
counter += 1;
|
||||
|
||||
engineInfo = {}
|
||||
|
||||
@@ -28,16 +32,20 @@ def performChecks ( args, ap ):
|
||||
if ( not args.printengines ):
|
||||
if ( not args.version ):
|
||||
# Check if input and output file arguments are available
|
||||
if ( args.inputfile == None or args.inputfile == '' or args.outputfile == None or args.outputfile == '' ):
|
||||
print( '\n\n ==> ERROR: Input and output file required! <==\n\n' )
|
||||
if ( args.inputfile == None or args.inputfile == '' ):
|
||||
print( '\n\n ==> ERROR: Input file required! <==\n\n' )
|
||||
ap.print_usage();
|
||||
return False
|
||||
|
||||
output = args.outputfile;
|
||||
if ( args.outputfile == None or args.outputfile == '' ):
|
||||
output = args.inputfile[ :len( args.inputfile ) - 4 ] + '_upscaled' + args.inputfile[ len( args.inputfile ) - 4: ]
|
||||
|
||||
# check if output file exists and if, prompt user if it should be overwritten and remove if, if yes
|
||||
if ( os.path.exists( args.outputfile ) ):
|
||||
if ( os.path.exists( output ) and ( args.overwrite == None or args.overwrite == '' ) ):
|
||||
doReplace = input( '--> File already exists. Do you want to replace it? (Y/n) ' ).lower()
|
||||
if ( doReplace == 'y' or doReplace == '' ):
|
||||
os.remove( args.outputfile );
|
||||
os.remove( output );
|
||||
else:
|
||||
print( '\n==> Refusing to Upscale video. Please delete the file or specify another filepath! <==' )
|
||||
return False
|
||||
@@ -46,7 +54,9 @@ def performChecks ( args, ap ):
|
||||
try:
|
||||
engineInfo[ args.engine.lower() ]
|
||||
except KeyError:
|
||||
print( '\n==> ERROR: Engine not available. Ensure you have specified a valid engine' )
|
||||
print( '\n==> ERROR: Engine ' + args.engine.lower() + ' not available. Ensure you have specified a valid engine. Possible engines: ' )
|
||||
for entry in engineList:
|
||||
print( ' --> ' + entry )
|
||||
return False
|
||||
|
||||
# Check scalefactor argument and also verify that engine supports upscaling
|
||||
@@ -60,9 +70,9 @@ def performChecks ( args, ap ):
|
||||
return False
|
||||
|
||||
# Check sharpening argument and also verify that engine supports it
|
||||
if ( args.sharpening != None and args.sharpening != 0 ):
|
||||
if ( float( args.sharpening ) >= 1 and float( args.sharpening ) <= 0 ):
|
||||
print( '\n==> ERROR: Invalid value for sharpening. Value has to be between 0 and 1' )
|
||||
if ( args.sharpening != None and args.sharpening != 0 ):
|
||||
if ( float( args.sharpening ) >= 1.0 or float( args.sharpening ) <= 0.0 ):
|
||||
print( '\n==> ERROR: Invalid value (' + args.sharpening + ') for sharpening. Value has to be between 0 and 1' )
|
||||
return False
|
||||
else:
|
||||
if ( not 'sharpening' in engineInfo[ args.engine ][ 'supports' ] ):
|
||||
@@ -95,9 +105,14 @@ def performChecks ( args, ap ):
|
||||
else:
|
||||
print( '\n\n==> Available engines <==\n' )
|
||||
for entry in engineList:
|
||||
print( '--> ' + entry )
|
||||
print( ' --> ' + entry )
|
||||
print( '\n\n' )
|
||||
else:
|
||||
try:
|
||||
engineInfo[ args.details.lower() ]
|
||||
except KeyError:
|
||||
print( '\n\n ==> That engine does not exist. Please use the -p option to check for available engines!\n\n' )
|
||||
return False
|
||||
print( '\n\n ==> INFOS about ' + engineInfo[ args.details.lower() ][ 'displayName' ] + '\n' )
|
||||
print( ' --> Engine cli option is: ' + engineInfo[ args.details ][ 'abbr' ].lower() )
|
||||
print( ' --> CLI mode options are: ' )
|
||||
@@ -108,7 +123,7 @@ def performChecks ( args, ap ):
|
||||
print( '\n\n' )
|
||||
|
||||
if __name__ == '__main__':
|
||||
ap = argparse.ArgumentParser( description='ImageVideoUpscaler - CLI, a CLI application to upscale videos and images using different upscaling engines.' )
|
||||
ap = argparse.ArgumentParser( description='SimpleMediaUpscalerLite - CLI, a CLI application to upscale videos and images using different upscaling engines.' )
|
||||
ap.add_argument( '-i', '--inputfile', help='File path for the video / image to be upscaled' )
|
||||
ap.add_argument( '-o', '--outputfile', help='Output file path for the video / image that was upscaled' )
|
||||
ap.add_argument( '-s', '--scalefactor', help='Scale factor for the video / image. Can be a integer from -4 to 4' )
|
||||
@@ -118,9 +133,10 @@ if __name__ == '__main__':
|
||||
ap.add_argument( '-M', '--mode', help='Specify a special mode for a specific engine. Might not be available in every engine. Use the -d option to find out more' )
|
||||
ap.add_argument( '-F', '--filetype', help='Change the file type of the temporary image files. Supports png, jpg. Video quality: png > jpg. PNG is default, if not specified.' )
|
||||
ap.add_argument( '-d', '--details', help='Get details on usage of a particular engine and exit. Reads the config.json file of that engine and displays it in a HR manner' )
|
||||
ap.add_argument( '-y', '--overwrite', help='Always overwrite output path and do not ask', action='store_true' )
|
||||
ap.add_argument( '-p', '--printengines', help='Print all engines and exit', action='store_true' )
|
||||
ap.add_argument( '-v', '--version', help='Print version and exit', action='store_true' )
|
||||
ap.set_defaults( scaling = 0, sharpening = 0, threads = 4, engine = 'fsr', filetype = 'png' )
|
||||
ap.set_defaults( scalefactor = 0, sharpening = 0, threads = 4, engine = 'ffc', filetype = 'png' )
|
||||
args = ap.parse_args()
|
||||
|
||||
handler = bin.handler.Handler()
|
||||
@@ -128,6 +144,10 @@ if __name__ == '__main__':
|
||||
multiprocessing.freeze_support();
|
||||
|
||||
if ( performChecks( args, ap ) ):
|
||||
output = args.outputfile;
|
||||
if ( args.outputfile == None or args.outputfile == '' ):
|
||||
output = args.inputfile[ :len( args.inputfile ) - 4 ] + '_upscaled' + args.inputfile[ len( args.inputfile ) - 4: ]
|
||||
|
||||
mode = 'fsr'
|
||||
if ( args.mode != None ):
|
||||
mode = args.mode
|
||||
@@ -136,7 +156,8 @@ if __name__ == '__main__':
|
||||
if ( engineInfo[ args.engine ][ 'cliModeOptions' ][ option ][ 'default' ] ):
|
||||
mode = option
|
||||
break
|
||||
handler.handler( args.inputfile, args.scalefactor, args.outputfile, args.sharpening, args.filetype, args.engine, mode, args.threads )
|
||||
print( '\n\n---------------------------------------------------------------------------------\n\nDONE \n\n\n\nImageVideoUpscalerFrontend V1.1.0\n\nCopyright 2023 FSRImageVideoUpscalerFrontend contributors\nThis application comes with absolutely no warranty to the extent permitted by applicable law\n\n\n\nOutput was written to ' + args.outputfile + '\n\n\n' )
|
||||
|
||||
|
||||
if ( handler.handler( args.inputfile, args.scalefactor, output, args.sharpening, args.filetype, args.engine, mode, args.threads ) ):
|
||||
print( '\n\n---------------------------------------------------------------------------------\n\nDONE \n\n\n\nSimpleMediaUpscalerLite V1.1.0\n\nCopyright 2023 SimpleMediaUpscalerLite contributors\nThis application comes with absolutely no warranty to the extent permitted by applicable law\n\n\n\nOutput was written to ' + output + '\n\n\n' )
|
||||
else:
|
||||
raise Exception( 'ERRORS in arguments' );
|
||||
@@ -5,7 +5,7 @@ block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['imagevideoupscaler-cli.py'],
|
||||
['smuL-cli.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
@@ -26,7 +26,7 @@ exe = EXE(
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name='imagevideoupscaler',
|
||||
name='smuL-cli',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
@@ -46,5 +46,5 @@ coll = COLLECT(
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='imagevideoupscaler',
|
||||
name='smuL-cli',
|
||||
)
|
||||
1
website/cropSymbol.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path fill="#FFFFFF" d="M695-40v-165H265q-24 0-42-18t-18-42v-430H40v-60h165v-165h60v655h655v60H755v165h-60Zm0-285v-370H325v-60h370q24 0 42 18t18 42v370h-60Z"/></svg>
|
||||
|
After Width: | Height: | Size: 254 B |
BIN
website/logo.xcf
Normal file
@@ -1,4 +1,4 @@
|
||||
# Writing plugins for ImageVideoUpscaler
|
||||
# Writing plugins for SimpleMediaUpscalerLite
|
||||
|
||||
Your plugin has to fulfill the following requirements:
|
||||
- Name of class it exposes has to be [name of engine]Scaler. The name of the file should be just the name of the engine in all lower case.
|
||||
|
||||