Compare commits
152 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 | ||
|
|
1510eb0fd5 | ||
|
|
f5edfa8109 | ||
| df9269597d | |||
|
|
35adcb0148 | ||
| 7f801ce59f | |||
| cb35b3b9ff | |||
| a0e7b459e1 | |||
|
|
54838c7d94 | ||
| 4c2900b6b3 | |||
| fc8f027a1c | |||
| db32279e6c | |||
|
|
10fc385730 | ||
|
|
d9ca80c529 | ||
|
|
ea49db45f0 | ||
|
|
61d6c13624 | ||
| e59e7f5101 | |||
|
|
1fa50afd01 | ||
|
|
5e65f3b52c | ||
|
|
9d485c2b73 | ||
|
|
d378018896 | ||
|
|
f9e14a58b4 | ||
|
|
c4d5ef8064 | ||
|
|
b5c4ae8485 | ||
|
|
fc635526f3 | ||
|
|
90e00530fd | ||
|
|
d54e3efb5e | ||
|
|
2f0249a89a | ||
|
|
b194c73963 | ||
|
|
37ac0f1ece | ||
| 7043cad015 | |||
| 254e0cf669 | |||
| 50d8ea1a9b | |||
| 2f7200022e | |||
|
|
01105d33e6 | ||
| b752e65878 | |||
| b01cdcbdd6 | |||
|
|
69c08778fc | ||
|
|
00988c524e | ||
|
|
0b9a1e43d8 | ||
| bdbfc9a8ce | |||
|
|
4b4dc46ebb | ||
|
|
f61b59955b | ||
| a0460a8113 | |||
| 182e3698b7 | |||
| d4605924cb | |||
| 955ae46e4f | |||
| e43a4f6546 | |||
| be74be1bf7 | |||
| 3ed9781d27 | |||
|
|
c93d866dd4 | ||
|
|
7b3da81682 | ||
|
|
0f05d650f0 | ||
| b3a83fdbad | |||
| 282691a8e6 | |||
|
|
c1dc26ff6b | ||
|
|
d8521321b2 | ||
|
|
51816e82e3 | ||
|
|
d3142988bf | ||
|
|
8962839e94 | ||
|
|
0b0b2da00f | ||
|
|
fa7dafc411 | ||
|
|
ca85822530 | ||
|
|
0917911998 | ||
|
|
77fee5f5da | ||
|
|
b84d318b08 | ||
|
|
3937571114 | ||
|
|
701ab6f7d1 | ||
| e1a6181edc | |||
| 147a6b5f38 | |||
| 125cd089d1 | |||
| f88ff03e57 | |||
| d12182e8c6 | |||
| 459963faff | |||
| 0466c9db9d | |||
|
|
35328dcb54 | ||
|
|
403d2b4521 | ||
|
|
6ead007d82 | ||
|
|
decc7f58d6 | ||
|
|
f88a0ef44f | ||
|
|
3d93b49ca4 | ||
|
|
5f6b09c523 | ||
|
|
42f4b9f4e5 | ||
|
|
70080953d0 | ||
|
|
0e15c2a31b | ||
|
|
945e3edfb0 | ||
|
|
e7ad56b62a | ||
| 029c70356f | |||
| 2e73026a8d | |||
| fef59ed86e | |||
|
|
5d4202e1a9 | ||
|
|
67ab7254a3 | ||
|
|
cfea0e2593 | ||
|
|
04509e4d9a |
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# SimpleMediaUpscalerLite - .gitignore
|
||||||
|
#
|
||||||
|
# Created by Janis Hutz 05/24/2023, Licensed under the GPL V3 License
|
||||||
|
# https://janishutz.com, development@janishutz.com
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
# remove pycache
|
||||||
|
__pycache__
|
||||||
|
|
||||||
|
# remove node_modules from repo
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# ignore build & dist folders
|
||||||
|
build
|
||||||
|
dist
|
||||||
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
8
.idea/FSRImageVideoUpscalerFrontend.iml
generated
8
.idea/FSRImageVideoUpscalerFrontend.iml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
8
.idea/FSRImageVideoUpscalerFrontendNew.iml
generated
8
.idea/FSRImageVideoUpscalerFrontendNew.iml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
||||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
|
|
||||||
</project>
|
|
||||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/FSRImageVideoUpscalerFrontendNew.iml" filepath="$PROJECT_DIR$/.idea/FSRImageVideoUpscalerFrontendNew.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
7
LICENSE
Normal file → Executable file
7
LICENSE
Normal file → Executable file
@@ -631,8 +631,9 @@ 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
|
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.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
A simple Electron GUI and Python CLI to upscale your videos using different
|
||||||
Copyright (C) <year> <name of author>
|
upscaling engines.
|
||||||
|
Copyright (C) 2023 Janis Hutz
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -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
|
If the program does terminal interaction, make it output a short
|
||||||
notice like this when it starts in an interactive mode:
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
SimpleMediaUpscalerLite Copyright (C) 2023 Janis Hutz
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|||||||
144
README.md
Normal file → Executable file
144
README.md
Normal file → Executable file
@@ -1,46 +1,130 @@
|
|||||||
# FSRImageVideoUpscalerFrontend
|
<div id="title" align="center">
|
||||||
A GTK frontend to upscale images / videos using AMD's FidelityFX Super Resolution.
|
<img src="./logo.png" width="300">
|
||||||
*NOTE: THIS PROJECT IS STILL IN DEVELOPMENT AND MAY STILL CONTAIN SOME FUNDEMENTAL BUGS!*
|
<h1>SimpleMediaUpscalerLite</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="badges" align="center">
|
||||||
|
<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>
|
||||||
|
smuL (pronounced like "small") is an Electron App with Python CLI to upscale images and videos using multiple different upscaling engines.
|
||||||
|
|
||||||
# Functionality
|
# Functionality
|
||||||
This App is a GTK frontend to AMD's FidelityFX Super Resolution codebase, which allows you to upscale basically anything that is some kind of an image.
|
This app allows you to fully automatically upscale a single file or a full on folder with one of many different engines.
|
||||||
- Choose an input & output file from a GUI filemanager.
|
- Choose an input & output file from a GUI filemanager.
|
||||||
- Choose from different quality presets or set your own multiplier
|
- Choose from different quality presets or set your own multiplier
|
||||||
- You may upscale Images (currently .png, .jpg and .jpeg) or Videos (currently .mp4 and .mkv)
|
- You may upscale Images (currently .png, .jpg and .jpeg) or Videos (currently .mp4 and .mkv)
|
||||||
- Output file will be written to a specified folder.
|
- Choose from one of many different upscaling algorithms.
|
||||||
|
- Add plugins to add even more upscaling engines to it
|
||||||
|
|
||||||
|
## Engines
|
||||||
|
- AMD Fidelity FX Super Resolution
|
||||||
|
- Cubic scaling
|
||||||
|
- High Quality Cubic
|
||||||
|
- Real-ESGRAN
|
||||||
|
- more to come!
|
||||||
|
|
||||||
|
This App also features a CLI interface.
|
||||||
|
```
|
||||||
|
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
|
||||||
|
- Windows 10, 11 (officially)
|
||||||
|
- Windows XP, Vista, 7, 8 (unofficially through python directly, may cause problems)
|
||||||
|
- Any modern Linux distro with wine installed
|
||||||
|
|
||||||
# Contributing
|
# 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!
|
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]
|
||||||
|
|
||||||
|
|
||||||
# Roadmap
|
# Roadmap
|
||||||
V1.0.0:
|
V2.0.0:
|
||||||
- Get the app working -- :white_check_mark:
|
- Migrate to Electron app -- ✅
|
||||||
- Create installer
|
- Package Windows & Linux Version -- ✅
|
||||||
- Quality selector (presets and custom multiplier) -- :white_check_mark:
|
- Add packaging script for Linux & Windows version -- ✅
|
||||||
- Filechoosers -- :white_check_mark:
|
- Make python app CLI only -- ✅
|
||||||
- Imageformats: .png, .jpg, .jpeg; Videoformats: .mp4, .mkv -- :white_check_mark:
|
- Refactor backend to add plugin support -- ✅
|
||||||
- Working UI -- :white_check_mark:
|
|
||||||
- Basic Wiki
|
|
||||||
- Add all compiling infos to the repo
|
|
||||||
- Add about section inside app
|
|
||||||
|
|
||||||
V1.1.0:
|
V2.1.0:
|
||||||
- Custom Quality target resolution
|
- Add more scaling engines
|
||||||
- support more file formats (Which ones not decided yet)
|
- Expand Wiki to feature documentation on how to create a plugin (and maybe add a project website)
|
||||||
|
|
||||||
V1.2.0:
|
|
||||||
- Show progress of scaling
|
- Show progress of scaling
|
||||||
|
|
||||||
V1.3.0:
|
|
||||||
- Expand Wiki
|
|
||||||
- ...
|
|
||||||
|
|
||||||
# Issues
|
# Issues
|
||||||
The app is technically functional, but there may still be some big bugs. If you run into any of them, please open an issue on this Github page under "issues". I will attempt to fix them as fast as possible, but a fully compiled version might still take a couple of days to arrive.
|
If you encounter any problems with this app, please don't hesitate to open an issue on GitHub.
|
||||||
|
|
||||||
# Supported OS
|
## Known issues
|
||||||
Supported technically is every OS that can run python, but tested so far only Linux is. I will create a Windows exe, a rpm and deb package and maybe a dmg.
|
- 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
|
||||||
|
|
||||||
# INFO
|
# FAQ
|
||||||
I will not be pushing the code to the main branch until there is a somewhat stable version in the dev-V1 branch. If you want to see the code, check it out there!
|
**Q: Can you add upscaling engine [upscaling engine here]?**
|
||||||
|
|
||||||
|
A: We can add it most likely, please open an issue that contains a link to the library and please try and upscale an image using it yourself and copy-paste the command into a comment.
|
||||||
|
Just remember that it might take time to implement it and this is all developed in our free time and we have no obligation to implement it.
|
||||||
|
|
||||||
|
**Q: App no worky on OS XXXX**
|
||||||
|
|
||||||
|
A: Please check [Supported OS](#supported-os) that your OS is actually supported officially. If so, please open an issue and provide command used (if CLI) and error message that the app spat out when running.
|
||||||
|
If the OS is not officially supported, we may not be able to help you, since we intentionally don't support it officially
|
||||||
|
|
||||||
|
**Q: Why no worky on MacOS? / Can you port to MacOS?**
|
||||||
|
|
||||||
|
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**
|
||||||
|
|
||||||
|
A: Try out different engines (that's why we support so many) and try to use sharpening to improve quality. If it doesn't help, you might want to suggest another engine.
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|||||||
BIN
bin/__pycache__/arg_assembly.cpython-310.pyc
Normal file
BIN
bin/__pycache__/arg_assembly.cpython-310.pyc
Normal file
Binary file not shown.
BIN
bin/__pycache__/checks.cpython-310.pyc
Normal file
BIN
bin/__pycache__/checks.cpython-310.pyc
Normal file
Binary file not shown.
BIN
bin/__pycache__/handler.cpython-310.pyc
Normal file
BIN
bin/__pycache__/handler.cpython-310.pyc
Normal file
Binary file not shown.
BIN
bin/__pycache__/handler.cpython-311.pyc
Normal file
BIN
bin/__pycache__/handler.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bin/__pycache__/probe.cpython-310.pyc
Normal file
BIN
bin/__pycache__/probe.cpython-310.pyc
Normal file
Binary file not shown.
BIN
bin/__pycache__/probe.cpython-311.pyc
Normal file
BIN
bin/__pycache__/probe.cpython-311.pyc
Normal file
Binary file not shown.
@@ -1,15 +0,0 @@
|
|||||||
class ArgAssembly:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get(self, quality):
|
|
||||||
if quality == "2x":
|
|
||||||
return "Performance"
|
|
||||||
elif quality == "1.7x":
|
|
||||||
return "Balanced"
|
|
||||||
elif quality == "1.5x":
|
|
||||||
return "Quality"
|
|
||||||
elif quality == "1.3x":
|
|
||||||
return "UltraQuality"
|
|
||||||
else:
|
|
||||||
raise Exception
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
class Checks:
|
|
||||||
def __init__(self):
|
|
||||||
self.custom_quality = 0.0
|
|
||||||
self.i_file_extension = ""
|
|
||||||
|
|
||||||
def perform(self, quality_selection, custom_quality, input_filepath, output_filepath):
|
|
||||||
# Call this function to perform entry checks.
|
|
||||||
# Returns True if all checks passed, False if one or more not passed.
|
|
||||||
if self.quality_checks(quality_selection, custom_quality) and self.file_checks(input_filepath, output_filepath):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def quality_checks(self, quality_sel, custom_q):
|
|
||||||
if quality_sel != "Custom (will respect value below)":
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
self.custom_quality = float(custom_q)
|
|
||||||
except ValueError:
|
|
||||||
if str(custom_q)[len(custom_q) - 1:] == "x":
|
|
||||||
print("x found")
|
|
||||||
try:
|
|
||||||
self.custom_quality = float(str(custom_q)[:len(custom_q) - 1])
|
|
||||||
except ValueError:
|
|
||||||
print("invalid custom quality multiplier")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("invalid letter in custom quality multiplier!")
|
|
||||||
return False
|
|
||||||
if 4 >= self.custom_quality >= 1:
|
|
||||||
print("quality selction ok")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print("invalid range for multiplier!")
|
|
||||||
|
|
||||||
def file_checks(self, i_fp, o_fp):
|
|
||||||
self.i_file_extension = str(i_fp)[len(i_fp) - 4:]
|
|
||||||
if self.i_file_extension == ".png" or self.i_file_extension == ".jpg":
|
|
||||||
print("file extensions ok (image)")
|
|
||||||
elif self.i_file_extension == "jpeg":
|
|
||||||
if str(i_fp)[len(i_fp) - 5:] == ".jpeg":
|
|
||||||
print("file extensions ok (image)")
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
elif self.i_file_extension == ".mp4" or self.i_file_extension == ".mkv":
|
|
||||||
print("file extensions ok (video)")
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if str(i_fp)[len(i_fp) - 4:] == str(o_fp)[len(o_fp) - 4:]:
|
|
||||||
print("file extensions are the same in output and input")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print("files don't have same extension!")
|
|
||||||
return False
|
|
||||||
17
bin/engines/ffc/config.json
Normal file
17
bin/engines/ffc/config.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"abbr":"ffc",
|
||||||
|
"displayName":"FidelityFX_CLI",
|
||||||
|
"lastUsedFilePath":"sc",
|
||||||
|
"fileNameBeginning":"ig",
|
||||||
|
"cliModeOptions": {
|
||||||
|
"fsr":{ "displayName": "FidelityFX Super Resolution", "default": true },
|
||||||
|
"c":{ "displayName": "Cubic", "default": false },
|
||||||
|
"hqc":{ "displayName": "High Quality Cubic", "default": false }
|
||||||
|
},
|
||||||
|
"pluginCreator": "Janis Hutz",
|
||||||
|
"pluginCreatorLink": "https://janishutz.com",
|
||||||
|
"engineLink": "",
|
||||||
|
"supports": [ "upscaling", "sharpening" ],
|
||||||
|
"engineDownloadLink":"",
|
||||||
|
"filesToInclude": [ "ffc.py" ]
|
||||||
|
}
|
||||||
327
bin/engines/ffc/ffc.py
Normal file
327
bin/engines/ffc/ffc.py
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
import os
|
||||||
|
import multiprocessing
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Scaler:
|
||||||
|
def __init__( self ):
|
||||||
|
self.os_type = sys.platform
|
||||||
|
self.command = ''
|
||||||
|
self.tmppath = ''
|
||||||
|
self.videometa = {}
|
||||||
|
|
||||||
|
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:
|
||||||
|
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 )
|
||||||
|
|
||||||
|
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 self.isSharpening:
|
||||||
|
for self.file in self.filelist:
|
||||||
|
self.number += 1
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.file_list.append( f"{tmppath}{self.file} {tmppath}up\\up{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
else:
|
||||||
|
self.file_list.append( f"{tmppath}{self.file} {tmppath}up/up{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
try:
|
||||||
|
os.mkdir( f'{tmppath}up' )
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for self.file in self.filelist:
|
||||||
|
self.number += 1
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.file_list.append( f"{tmppath}{self.file} {tmppath}sc\\ig{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
else:
|
||||||
|
self.file_list.append( f"{tmppath}{self.file} {tmppath}sc/ig{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir( f'{tmppath}sc' )
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.maxlength = 8000
|
||||||
|
else:
|
||||||
|
self.maxlength = 31900
|
||||||
|
self.pos = 1
|
||||||
|
|
||||||
|
############################################
|
||||||
|
#
|
||||||
|
# Thread optimisation: Divide workload up into different threads & upscale using helper function
|
||||||
|
#
|
||||||
|
############################################
|
||||||
|
self.threads = threads
|
||||||
|
if ( threads > multiprocessing.cpu_count() ):
|
||||||
|
self.threads = multiprocessing.cpu_count();
|
||||||
|
|
||||||
|
if ( self.isScaling ):
|
||||||
|
engines = { 'c': 'Cubic', 'hqc': 'High Quality Cubic', 'fsr':'FidelityFX Super Resolution' }
|
||||||
|
print( f'\n\n==> Upscaling using { self.threads } threads <==\n\n' );
|
||||||
|
print( f'\n\n==> Upscaling Engine is FidelityFX_CLI with algorithm { engines[ mode.lower() ] } <==\n\n' );
|
||||||
|
|
||||||
|
time.sleep( 2 );
|
||||||
|
|
||||||
|
self.command_list = [];
|
||||||
|
self.file_list_length = len( self.file_list );
|
||||||
|
for i in range( self.threads ):
|
||||||
|
self.files = '';
|
||||||
|
for _ in range( int( self.file_list_length // self.threads ) ):
|
||||||
|
self.files += self.file_list.pop( 0 );
|
||||||
|
|
||||||
|
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.isSharpening ) )
|
||||||
|
|
||||||
|
self.pool = multiprocessing.Pool( self.threads )
|
||||||
|
self.pool.starmap( upscalerEngine, self.command_list );
|
||||||
|
self.pool.close();
|
||||||
|
self.pool.join();
|
||||||
|
|
||||||
|
if self.isSharpening:
|
||||||
|
print( f'\n\n\n==> Sharpening using { self.threads } threads <==\n\n' );
|
||||||
|
time.sleep( 2 );
|
||||||
|
|
||||||
|
self.pathSharpening = tmppath
|
||||||
|
|
||||||
|
if ( self.isScaling ):
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.pathSharpening += 'up\\'
|
||||||
|
elif ( self.os_type == 'linux' ):
|
||||||
|
self.pathSharpening += 'up/'
|
||||||
|
|
||||||
|
time.sleep( 2 );
|
||||||
|
try:
|
||||||
|
os.mkdir( f'{tmppath}sc' )
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
# Locate Images and assemble FSR-Command
|
||||||
|
self.file_list = []
|
||||||
|
self.filelist = os.listdir( self.pathSharpening )
|
||||||
|
self.filelist.pop(0)
|
||||||
|
self.filelist.sort()
|
||||||
|
self.number = 0
|
||||||
|
for self.file in self.filelist:
|
||||||
|
self.number += 1
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.file_list.append( f"{self.pathSharpening}{self.file} {tmppath}sc\\ig{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
else:
|
||||||
|
self.file_list.append( f"{self.pathSharpening}{self.file} {tmppath}sc/ig{str(self.number).zfill(8)}.{ filetype } " );
|
||||||
|
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
self.maxlength = 8000
|
||||||
|
else:
|
||||||
|
self.maxlength = 31900
|
||||||
|
self.pos = 1
|
||||||
|
|
||||||
|
# assemble command list
|
||||||
|
self.command_list = [];
|
||||||
|
self.file_list_length = len( self.file_list );
|
||||||
|
for i in range( self.threads ):
|
||||||
|
self.files = '';
|
||||||
|
for _ in range( int( self.file_list_length // self.threads ) ):
|
||||||
|
self.files += self.file_list.pop( 0 );
|
||||||
|
|
||||||
|
if ( i == self.threads - 1 ):
|
||||||
|
for element in self.file_list:
|
||||||
|
self.files += element;
|
||||||
|
self.command_list.append( ( self.files, i, self.maxlength, self.os_type, sharpening, not sharpening ) )
|
||||||
|
|
||||||
|
self.pool = multiprocessing.Pool( self.threads )
|
||||||
|
self.pool.starmap( sharpeningEngine, self.command_list );
|
||||||
|
self.pool.close();
|
||||||
|
self.pool.join();
|
||||||
|
|
||||||
|
# Add return values
|
||||||
|
|
||||||
|
def upscalerEngine ( files, scalefactor, number, maxlength, os_type, version, isSharpening ):
|
||||||
|
comparison = 'sc'
|
||||||
|
if ( isSharpening ):
|
||||||
|
comparison = 'up'
|
||||||
|
scaler = 'FSR'
|
||||||
|
if ( version.upper() == 'HQC' ):
|
||||||
|
scaler = 'HighQualityCubic'
|
||||||
|
elif ( version.upper() == 'C' ):
|
||||||
|
scaler = 'Cubic'
|
||||||
|
files = files;
|
||||||
|
# Refactoring of commands that are longer than 32K characters
|
||||||
|
fileout = [];
|
||||||
|
pos = 0;
|
||||||
|
if len( files ) > maxlength:
|
||||||
|
while files[maxlength - pos:maxlength - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
file_processing = files[:maxlength - pos]
|
||||||
|
if file_processing[len(file_processing) - 17:len(file_processing) - 15] != comparison:
|
||||||
|
pos += 5
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
while files[maxlength - pos:maxlength - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
fileout.append(files[:maxlength - pos])
|
||||||
|
filesopt = files[maxlength - pos:]
|
||||||
|
posx = 0
|
||||||
|
posy = maxlength
|
||||||
|
|
||||||
|
# Command refactoring for commands that are longer than 64K characters
|
||||||
|
if len(filesopt) > maxlength:
|
||||||
|
while len(filesopt) > maxlength:
|
||||||
|
posx += maxlength - pos
|
||||||
|
posy += maxlength - pos
|
||||||
|
pos = 1
|
||||||
|
while files[posy - pos:posy - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
file_processing = files[posx:posy - pos]
|
||||||
|
if file_processing[len(file_processing) - 17:len(file_processing) - 15] != comparison:
|
||||||
|
pos += 5
|
||||||
|
while files[posy - pos:posy - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
file_processing = files[posx:posy - pos]
|
||||||
|
fileout.append(file_processing)
|
||||||
|
filesopt = files[posy - pos:]
|
||||||
|
fileout.append(filesopt)
|
||||||
|
else:
|
||||||
|
fileout.append(files[maxlength - pos:])
|
||||||
|
else:
|
||||||
|
fileout.append(files)
|
||||||
|
|
||||||
|
# Upscaling images
|
||||||
|
print( '\n\n\nUpscaling images... \n\n\n\n\n\n PROCESS: ', number, '\n\n\n' )
|
||||||
|
|
||||||
|
while len( fileout ) > 0:
|
||||||
|
files_handle = fileout.pop(0)
|
||||||
|
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'bin\\lib\\FidelityFX_CLI.exe -Mode { scaler } -Scale {scalefactor}x {scalefactor}x {files_handle}'
|
||||||
|
else:
|
||||||
|
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||||
|
return False
|
||||||
|
sub = subprocess.Popen( command_us, shell=True );
|
||||||
|
sub.wait();
|
||||||
|
time.sleep(3)
|
||||||
|
print( '\n\nCompleted executing Job\n\n\n PROCESS: ', number, '\n\n\n' );
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
#
|
||||||
|
# Sharpening
|
||||||
|
#
|
||||||
|
#######################
|
||||||
|
|
||||||
|
def sharpeningEngine ( files, number, maxlength, os_type, sharpening, didUpscale ):
|
||||||
|
files = files;
|
||||||
|
# Refactoring of commands that are longer than 32K characters
|
||||||
|
fileout = [];
|
||||||
|
pos = 0;
|
||||||
|
if len( files ) > maxlength:
|
||||||
|
while files[maxlength - pos:maxlength - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
file_processing = files[:maxlength - pos]
|
||||||
|
if ( didUpscale ):
|
||||||
|
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':
|
||||||
|
pos += 8
|
||||||
|
while files[maxlength - pos:maxlength - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
fileout.append(files[:maxlength - pos])
|
||||||
|
filesopt = files[maxlength - pos:]
|
||||||
|
posx = 0
|
||||||
|
posy = maxlength
|
||||||
|
|
||||||
|
# Command refactoring for commands that are longer than 64K characters
|
||||||
|
if len(filesopt) > maxlength:
|
||||||
|
while len(filesopt) > maxlength:
|
||||||
|
posx += maxlength - pos
|
||||||
|
posy += maxlength - pos
|
||||||
|
pos = 1
|
||||||
|
while files[posy - pos:posy - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
file_processing = files[posx:posy - pos]
|
||||||
|
if ( didUpscale ):
|
||||||
|
if file_processing[len(file_processing) - 14:len(file_processing) - 12] == 'up':
|
||||||
|
pos += 5
|
||||||
|
else:
|
||||||
|
if file_processing[len(file_processing) - 17:len(file_processing) - 15] == 'ru':
|
||||||
|
pos += 8
|
||||||
|
while files[posy - pos:posy - pos + 1] != ' ':
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
file_processing = files[posx:posy - pos]
|
||||||
|
fileout.append(file_processing)
|
||||||
|
filesopt = files[posy - pos:]
|
||||||
|
fileout.append(filesopt)
|
||||||
|
else:
|
||||||
|
fileout.append(files[maxlength - pos:])
|
||||||
|
else:
|
||||||
|
fileout.append(files)
|
||||||
|
|
||||||
|
# Upscaling images
|
||||||
|
print( '\n\n\nSharpening images... \n\n\n\n\n\n PROCESS: ', number, '\n\n\n' )
|
||||||
|
|
||||||
|
while len( fileout ) > 0:
|
||||||
|
files_handle = fileout.pop(0)
|
||||||
|
print( '\n\n\n PROCESS: ', number, '\nRunning sharpening filter\n\n\n' );
|
||||||
|
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'bin\\lib\\FidelityFX_CLI.exe -Mode CAS -Sharpness {sharpening} {files_handle}'
|
||||||
|
else:
|
||||||
|
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||||
|
return False
|
||||||
|
sub2 = subprocess.Popen( command_sharpening, shell=True );
|
||||||
|
sub2.wait()
|
||||||
|
time.sleep(3)
|
||||||
|
print( '\n\nCompleted executing Job\n\n\n PROCESS: ', number, '\n\n\n' );
|
||||||
|
|
||||||
16
bin/engines/ss/config.json
Normal file
16
bin/engines/ss/config.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"abbr":"SS",
|
||||||
|
"displayName":"Real-ESGRAN",
|
||||||
|
"lastUsedFilePath":"sc",
|
||||||
|
"fileNameBeginning":"ig",
|
||||||
|
"cliModeOptions": {
|
||||||
|
"av3":{ "displayName": "realesr-animevideov3", "default": true },
|
||||||
|
"x4plus":{ "displayName": "realesrgan-x4plus-anime", "default": false }
|
||||||
|
},
|
||||||
|
"pluginCreator": "Janis Hutz",
|
||||||
|
"pluginCreatorLink": "https://janishutz.com",
|
||||||
|
"engineLink": "",
|
||||||
|
"supports": [ "upscaling" ],
|
||||||
|
"engineDownloadLink":"",
|
||||||
|
"filesToInclude": [ "fsr.py" ]
|
||||||
|
}
|
||||||
41
bin/engines/ss/ss.py
Normal file
41
bin/engines/ss/ss.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import multiprocessing
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Scaler:
|
||||||
|
def __init__(self):
|
||||||
|
self.os_type = sys.platform
|
||||||
|
self.command = ""
|
||||||
|
self.tmppath = ""
|
||||||
|
self.videometa = {}
|
||||||
|
|
||||||
|
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/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'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' }
|
||||||
|
print( '\n\n==> Preparing to upscale videos <==\n\n==> You will see a lot of numbers flying by showing the progress of the upscaling of each individual image.\n==> This process might take a long time, depending on the length of the video.\n\n')
|
||||||
|
time.sleep( 2 );
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir( f'{tmppath}sc' )
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
if ( self.os_type == 'win32' ):
|
||||||
|
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 );
|
||||||
322
bin/handler.py
Normal file → Executable file
322
bin/handler.py
Normal file → Executable file
@@ -1,19 +1,35 @@
|
|||||||
###########################################################
|
'''
|
||||||
#
|
* SimpleMediaUpscalerLite - handler.py
|
||||||
# Handler for FSRImageVideoUpscalerFrontend
|
*
|
||||||
#
|
* Created by Janis Hutz 03/14/2023, Licensed under the GPL V3 License
|
||||||
# This code is licensed under the GPL V3 License!
|
* https://janishutz.com, development@janishutz.com
|
||||||
# Developed 2022 by Janis Hutz
|
*
|
||||||
#
|
*
|
||||||
###########################################################
|
'''
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import ffmpeg
|
import bin.probe
|
||||||
|
ffmpeg = bin.probe
|
||||||
import configparser
|
import configparser
|
||||||
import time
|
import json
|
||||||
|
import importlib
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
importedModules = {}
|
||||||
|
|
||||||
|
engineList = os.listdir( 'bin/engines' );
|
||||||
|
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()
|
||||||
|
|
||||||
# Loading the config file to get user preferred temp path
|
# Loading the config file to get user preferred temp path
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@@ -23,76 +39,40 @@ config.read('./config/settings.ini')
|
|||||||
class Handler:
|
class Handler:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.os_type = sys.platform
|
self.os_type = sys.platform
|
||||||
self.command = ""
|
self.command = ''
|
||||||
self.tmppath = ""
|
self.tmppath = ''
|
||||||
self.videometa = {}
|
self.videometa = {}
|
||||||
|
|
||||||
def handler(self, fsrpath, filepath, quality_mode, quality_setting, output_path):
|
|
||||||
|
# TODO: CHECK if this upscaler is any good: https://github.com/Maximellerbach/Image-Processing-using-AI (looks quite promising)
|
||||||
|
|
||||||
|
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
|
# Function to be called when using this class as this function automatically determines if file is video or image
|
||||||
if self.os_type == "linux":
|
print( '\n\n SimpleMediaUpscalerLite - V1.1.0\n\n(c) 2023 SimpleMediaUpscalerLite contributors\n\n\n\n' );
|
||||||
self.tmppath = config["PathSettings"]["tmpPathLinux"]
|
|
||||||
elif self.os_type == "win32":
|
if self.os_type == 'linux':
|
||||||
self.tmppath = config["PathSettings"]["tmpPathWindows"]
|
self.tmppath = tempfile.gettempdir()
|
||||||
|
elif self.os_type == 'win32':
|
||||||
|
self.tmppath = tempfile.gettempdir()
|
||||||
else:
|
else:
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
print('OS CURRENTLY UNSUPPORTED!')
|
||||||
return False
|
return False
|
||||||
self.tmppath += "fsru/"
|
if ( self.os_type == 'win32' ):
|
||||||
self.ffmpegpath = config["PathSettings"]["ffmpeg"]
|
self.tmppath += '\\fsru\\'
|
||||||
|
else:
|
||||||
|
if ( self.tmppath[len(self.tmppath) - 1: ] == '/' ):
|
||||||
|
self.tmppath += 'fsru/'
|
||||||
|
else:
|
||||||
|
self.tmppath += '/fsru/'
|
||||||
|
|
||||||
# checking for spaces in filepath (for use with terminal commands)
|
# checking for spaces in filepath (for use with terminal commands)
|
||||||
self.filepath = ""
|
self.filepath = ''
|
||||||
for self.letter in filepath:
|
for self.letter in filepath:
|
||||||
if self.letter == " ":
|
if self.letter == ' ':
|
||||||
self.filepath += "\ "
|
self.filepath += '\ '
|
||||||
else:
|
else:
|
||||||
self.filepath += self.letter
|
self.filepath += self.letter
|
||||||
|
|
||||||
# Determining filetype
|
|
||||||
if str(filepath)[len(filepath) - 4:] == ".mp4" or str(filepath)[len(filepath) - 4:] == ".mkv":
|
|
||||||
print("upscaling video")
|
|
||||||
self.video_scaling(self.ffmpegpath, fsrpath, filepath, quality_mode, quality_setting, output_path)
|
|
||||||
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("upscaling image")
|
|
||||||
self.photo_scaling(fsrpath, filepath, quality_mode, quality_setting, output_path)
|
|
||||||
else:
|
|
||||||
print("not supported")
|
|
||||||
|
|
||||||
def photo_scaling(self, fsrpath, filepath, quality_mode, quality_setting, output_path):
|
|
||||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
|
||||||
if quality_mode == "default":
|
|
||||||
if self.os_type == "linux":
|
|
||||||
self.command = f"wine {fsrpath} -QualityMode {quality_setting} {self.filepath} {output_path}"
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
self.command = f"{fsrpath} -QualityMode {quality_setting} {self.filepath} {output_path}"
|
|
||||||
else:
|
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
|
||||||
return False
|
|
||||||
|
|
||||||
os.system(self.command)
|
|
||||||
print("photo upscaled")
|
|
||||||
else:
|
|
||||||
if self.os_type == "linux":
|
|
||||||
self.command = f"wine {fsrpath} -Scale {quality_setting} {self.filepath} {output_path}"
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
self.command = f"{fsrpath} -Scale {quality_setting} {self.filepath} {output_path}"
|
|
||||||
else:
|
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
|
||||||
return False
|
|
||||||
os.system(self.command)
|
|
||||||
print("photo upscaled")
|
|
||||||
|
|
||||||
def video_scaling(self, ffmpegpath, fsrpath, filepath, quality_mode, quality_setting, output_path):
|
|
||||||
# DO NOT CALL THIS! Use Handler().handler() instead!
|
|
||||||
self.videometa = ffmpeg.probe(str(filepath))["streams"].pop(0)
|
|
||||||
# Retrieving Video metadata
|
|
||||||
self.duration = self.videometa.get("duration")
|
|
||||||
self.frames = self.videometa.get("nb_frames")
|
|
||||||
try:
|
|
||||||
self.framerate = round(float(self.frames) / float(self.duration), 1)
|
|
||||||
except TypeError:
|
|
||||||
self.infos = str(self.videometa.get("r_frame_rate"))
|
|
||||||
self.framerate = float(self.infos[:len(self.infos) - 2])
|
|
||||||
|
|
||||||
# Splitting video into frames
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(self.tmppath)
|
shutil.rmtree(self.tmppath)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@@ -100,130 +80,108 @@ class Handler:
|
|||||||
try:
|
try:
|
||||||
os.mkdir(self.tmppath)
|
os.mkdir(self.tmppath)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
print( '==> ERROR: Temp path does not exist! <==' )
|
||||||
|
|
||||||
if self.os_type == "linux":
|
|
||||||
print("linux")
|
|
||||||
self.command = f"ffmpeg -i {str(self.filepath)} {self.tmppath}ex%08d.png"
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
self.command = f"{ffmpegpath} -i {str(self.filepath)} {self.tmppath}ex%08d.png"
|
|
||||||
else:
|
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
|
||||||
return False
|
return False
|
||||||
os.system(self.command)
|
|
||||||
print("video split")
|
|
||||||
|
|
||||||
# Locate Images and assemble FSR-Command
|
# Determining filetype
|
||||||
self.files = ""
|
if str(filepath)[len(filepath) - 4:] == '.mp4' or str(filepath)[len(filepath) - 4:] == '.mkv' or str(filepath)[len(filepath) - 4:] == '.MP4':
|
||||||
self.filelist = os.listdir(self.tmppath)
|
print( '\n\n==> Upscaling video' )
|
||||||
self.filelist.pop(0)
|
return self.video_scaling( filepath, output_path, scalefactor, threads, sharpening, filetype, mode, engine )
|
||||||
self.filelist.reverse()
|
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':
|
||||||
self.number = 0
|
print( '\n==> Upscaling Image' )
|
||||||
for self.file in self.filelist:
|
return self.photo_scaling( filepath, output_path, scalefactor, sharpening, threads, engine, mode )
|
||||||
self.number += 1
|
|
||||||
self.files += f"{self.tmppath}{self.file} {self.tmppath}sc/ig{str(self.number).zfill(8)}.png "
|
|
||||||
self.maxlength = 31900
|
|
||||||
self.pos = 1
|
|
||||||
|
|
||||||
# Refactoring of commands that are longer than 32K characters
|
|
||||||
if len(self.files) > self.maxlength:
|
|
||||||
self.fileout = []
|
|
||||||
while self.files[self.maxlength - self.pos:self.maxlength - self.pos + 1] != " ":
|
|
||||||
self.pos += 1
|
|
||||||
self.file_processing = self.files[:self.maxlength - self.pos]
|
|
||||||
if self.file_processing[len(self.file_processing) - 14:len(self.file_processing) - 12] == "ex":
|
|
||||||
self.pos += 5
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
while self.files[self.maxlength - self.pos:self.maxlength - self.pos + 1] != " ":
|
|
||||||
self.pos += 1
|
|
||||||
self.fileout.append(self.files[:self.maxlength - self.pos])
|
|
||||||
self.filesopt = self.files[self.maxlength - self.pos:]
|
|
||||||
self.posx = 0
|
|
||||||
self.posy = self.maxlength
|
|
||||||
|
|
||||||
# Command refactoring for commands that are longer than 64K characters
|
|
||||||
if len(self.filesopt) > self.maxlength:
|
|
||||||
while len(self.filesopt) > self.maxlength:
|
|
||||||
self.posx += self.maxlength - self.pos
|
|
||||||
self.posy += self.maxlength - self.pos
|
|
||||||
self.pos = 1
|
|
||||||
while self.files[self.posy - self.pos:self.posy - self.pos + 1] != " ":
|
|
||||||
self.pos += 1
|
|
||||||
self.file_processing = self.files[self.posx:self.posy - self.pos]
|
|
||||||
print(self.file_processing[len(self.file_processing) - 14:len(self.file_processing) - 12])
|
|
||||||
if self.file_processing[len(self.file_processing) - 14:len(self.file_processing) - 12] == "ex":
|
|
||||||
self.pos += 5
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
while self.files[self.posy - self.pos:self.posy - self.pos + 1] != " ":
|
|
||||||
self.pos += 1
|
|
||||||
|
|
||||||
self.file_processing = self.files[self.posx:self.posy - self.pos]
|
|
||||||
self.fileout.append(self.file_processing)
|
|
||||||
self.filesopt = self.files[self.posy - self.pos:]
|
|
||||||
self.fileout.append(self.filesopt)
|
|
||||||
else:
|
|
||||||
self.fileout.append(self.files[self.maxlength - self.pos:])
|
|
||||||
else:
|
else:
|
||||||
self.fileout.append(self.files)
|
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' )
|
||||||
|
|
||||||
|
if self.os_type == 'linux':
|
||||||
|
self.command = f'ffmpeg -i {str(self.filepath)} {self.tmppath}ig%08d.{ filetype }'
|
||||||
|
elif self.os_type == 'win32':
|
||||||
|
self.command = f'ffmpeg -i {str(self.filepath)} \"{self.tmppath}ig%08d.{ filetype }\"'
|
||||||
|
else:
|
||||||
|
print('OS CURRENTLY UNSUPPORTED!')
|
||||||
|
return False
|
||||||
|
|
||||||
|
os.system( self.command )
|
||||||
|
print( '\n==> Video split ' )
|
||||||
|
|
||||||
|
# Retrieving Video metadata
|
||||||
|
self.filelist = os.listdir(self.tmppath)
|
||||||
try:
|
try:
|
||||||
os.mkdir(f"{self.tmppath}sc/")
|
self.videometa = ffmpeg.probe(str(input_path))['streams'].pop(0)
|
||||||
except FileExistsError:
|
except Exception:
|
||||||
pass
|
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;
|
||||||
|
|
||||||
# Upscaling images
|
self.duration = self.videometa.get( 'duration' )
|
||||||
print("\n\n\nUpscaling images... \n\n\n")
|
self.frames = len( self.filelist )
|
||||||
while self.fileout != []:
|
try:
|
||||||
self.files_handle = self.fileout.pop(0)
|
self.framerate = round(float(self.frames) / float(self.duration), 1)
|
||||||
if quality_mode == "default":
|
except TypeError:
|
||||||
if self.os_type == "linux":
|
print( '\n\n=> using fallback method to get framerate' )
|
||||||
self.command = f"wine {fsrpath} -QualityMode {quality_setting} {self.files_handle}"
|
self.infos = str( self.videometa.get( 'r_frame_rate' ) )
|
||||||
elif self.os_type == "win32":
|
self.framerate = float( self.infos[:len(self.infos) - 2] )
|
||||||
self.command = f"{fsrpath} -QualityMode {quality_setting} {self.files_handle}"
|
|
||||||
else:
|
print( '\n\n==> Video duration is: ', self.duration, 's' )
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
print( '==> Framecount is: ', self.frames, ' frames' )
|
||||||
return False
|
print( '==> Frame rate is: ', self.framerate, ' FPS' )
|
||||||
else:
|
print( '==> Running with: ', threads, ' threads\n\n' )
|
||||||
if quality_mode == "default":
|
|
||||||
if self.os_type == "linux":
|
|
||||||
self.command = f"wine {fsrpath} -Scale {quality_setting} {self.files_handle} {self.tmppath}"
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
self.command = f"{fsrpath} -Scale {quality_setting} {self.files_handle} {self.tmppath}"
|
|
||||||
else:
|
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
|
||||||
return False
|
|
||||||
print(self.command, "\n\n\nCOMMAND\n\n\n")
|
|
||||||
os.system(self.command)
|
|
||||||
print("Finished upscaling this section.")
|
|
||||||
time.sleep(3)
|
|
||||||
|
|
||||||
|
time.sleep( 2 );
|
||||||
|
|
||||||
|
importedModules[ engine ].videoScaler ( self.tmppath, int( threads ), int( scalefactor ), float( sharpening ), filetype, mode )
|
||||||
|
|
||||||
# get Video's audio
|
# get Video's audio
|
||||||
print("Retrieving Video's audio to append")
|
print( '\n\n==>Finished Upscaling individual images. \n==>Retrieving Video audio to append\n\n' )
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.remove(f"{self.tmppath}audio.aac")
|
self.framerate = round(float(self.frames) / float(self.duration), 1)
|
||||||
os.remove(f"{output_path}")
|
except TypeError:
|
||||||
|
print( '\n\n=> using fallback method to get framerate' )
|
||||||
|
self.infos = str( self.videometa.get( 'r_frame_rate' ) )
|
||||||
|
self.framerate = float( self.infos[:len(self.infos) - 2] )
|
||||||
|
|
||||||
|
time.sleep( 2 );
|
||||||
|
try:
|
||||||
|
os.remove(f'{self.tmppath}audio.aac')
|
||||||
|
os.remove(f'{output_path}')
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
if self.os_type == "linux":
|
if self.os_type == 'linux':
|
||||||
self.command = f"ffmpeg -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac"
|
self.command = f'ffmpeg -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac'
|
||||||
elif self.os_type == "win32":
|
elif self.os_type == 'win32':
|
||||||
self.command = f"{ffmpegpath} -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac"
|
self.command = f'ffmpeg -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac'
|
||||||
else:
|
else:
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
print( 'OS CURRENTLY UNSUPPORTED!' )
|
||||||
return False
|
return False
|
||||||
os.system(self.command)
|
os.system( self.command )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# reassemble Video
|
# reassemble Video
|
||||||
print("Reassembling Video... with framerate @", self.framerate)
|
print( '\n\n==> Reassembling Video... with framerate @', self.framerate, '\n\n' )
|
||||||
if self.os_type == "linux":
|
|
||||||
self.command = f"ffmpeg -framerate {self.framerate} -i {self.tmppath}sc/ig%08d.png {output_path} -i {self.tmppath}audio.aac"
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
self.command = f"{ffmpegpath} -framerate {self.framerate} -i {self.tmppath}sc/ig%08d.png {output_path} -i {self.tmppath}audio.aac"
|
|
||||||
else:
|
|
||||||
print("OS CURRENTLY UNSUPPORTED!")
|
|
||||||
return False
|
|
||||||
os.system(self.command)
|
|
||||||
|
|
||||||
print("\n\n\n DONE \n\n\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':
|
||||||
|
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'
|
||||||
|
else:
|
||||||
|
print( 'OS CURRENTLY UNSUPPORTED!' );
|
||||||
|
return False
|
||||||
|
os.system( self.command )
|
||||||
|
|
||||||
|
return True;
|
||||||
0
bin/lib/FidelityFX_CLI.exe
Normal file → Executable file
0
bin/lib/FidelityFX_CLI.exe
Normal file → Executable file
BIN
bin/lib/__pycache__/edi.cpython-311.pyc
Normal file
BIN
bin/lib/__pycache__/edi.cpython-311.pyc
Normal file
Binary file not shown.
154
bin/lib/edi.py
Normal file
154
bin/lib/edi.py
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
|
||||||
|
"""
|
||||||
|
Author:
|
||||||
|
|
||||||
|
hu.leying@columbia.edu
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
EDI_predict(img, m, s)
|
||||||
|
|
||||||
|
# img is the input image
|
||||||
|
# m is the sampling window size, not scaling factor! The larger the m, more blurry the image. Ideal m >= 4.
|
||||||
|
# s is the scaling factor, support any s > 0 (e.g. use s=2 to upscale by 2, use s=0.5 to downscale by 2)
|
||||||
|
|
||||||
|
If you want to directly call EDI_upscale to upscale image by the scale of 2:
|
||||||
|
|
||||||
|
EDI_upscale(img, m)
|
||||||
|
|
||||||
|
# m should be the power of 2. Will increment by 1 if input m is odd
|
||||||
|
|
||||||
|
If you want to directly call EDI_downscale to downscale image by the scale of 2:
|
||||||
|
|
||||||
|
EDI_downscale(img)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def EDI_downscale(img):
|
||||||
|
|
||||||
|
# initializing downgraded image
|
||||||
|
w, h = img.shape
|
||||||
|
imgo2 = np.zeros((w//2, h//2))
|
||||||
|
|
||||||
|
# downgrading image
|
||||||
|
for i in range(w//2):
|
||||||
|
for j in range(h//2):
|
||||||
|
imgo2[i][j] = int(img[2*i][2*j])
|
||||||
|
|
||||||
|
return imgo2.astype(img.dtype)
|
||||||
|
|
||||||
|
def EDI_upscale(img, m):
|
||||||
|
|
||||||
|
# m should be equal to a power of 2
|
||||||
|
if m%2 != 0:
|
||||||
|
m += 1
|
||||||
|
|
||||||
|
# initializing image to be predicted
|
||||||
|
w, h = img.shape
|
||||||
|
imgo = np.zeros((w*2,h*2))
|
||||||
|
|
||||||
|
# Place low-resolution pixels
|
||||||
|
for i in range(w):
|
||||||
|
for j in range(h):
|
||||||
|
imgo[2*i][2*j] = img[i][j]
|
||||||
|
|
||||||
|
y = np.zeros((m**2,1)) # pixels in the window
|
||||||
|
C = np.zeros((m**2,4)) # interpolation neighbours of each pixel in the window
|
||||||
|
|
||||||
|
# Reconstruct the points with the form of (2*i+1,2*j+1)
|
||||||
|
for i in range(math.floor(m/2), w-math.floor(m/2)):
|
||||||
|
for j in range(math.floor(m/2), h-math.floor(m/2)):
|
||||||
|
tmp = 0
|
||||||
|
for ii in range(i-math.floor(m/2), i+math.floor(m/2)):
|
||||||
|
for jj in range(j-math.floor(m/2), j+math.floor(m/2)):
|
||||||
|
y[tmp][0] = imgo[2*ii][2*jj]
|
||||||
|
C[tmp][0] = imgo[2*ii-2][2*jj-2]
|
||||||
|
C[tmp][1] = imgo[2*ii+2][2*jj-2]
|
||||||
|
C[tmp][2] = imgo[2*ii+2][2*jj+2]
|
||||||
|
C[tmp][3] = imgo[2*ii-2][2*jj+2]
|
||||||
|
tmp += 1
|
||||||
|
|
||||||
|
# calculating weights
|
||||||
|
# a = (C^T * C)^(-1) * (C^T * y) = (C^T * C) \ (C^T * y)
|
||||||
|
a = np.matmul(np.matmul(np.linalg.pinv(np.matmul(np.transpose(C),C)), np.transpose(C)), y)
|
||||||
|
imgo[2*i+1][2*j+1] = np.matmul([imgo[2*i][2*j], imgo[2*i+2][2*j], imgo[2*i+2][2*j+2], imgo[2*i][2*j+2]], a)
|
||||||
|
|
||||||
|
# Reconstructed the points with the forms of (2*i+1,2*j) and (2*i,2*j+1)
|
||||||
|
for i in range(math.floor(m/2), w-math.floor(m/2)):
|
||||||
|
for j in range(math.floor(m/2), h-math.floor(m/2)):
|
||||||
|
tmp = 0
|
||||||
|
for ii in range(i-math.floor(m/2), i+math.floor(m/2)):
|
||||||
|
for jj in range(j-math.floor(m/2), j+math.floor(m/2)):
|
||||||
|
y[tmp][0] = imgo[2*ii+1][2*jj-1]
|
||||||
|
C[tmp][0] = imgo[2*ii-1][2*jj-1]
|
||||||
|
C[tmp][1] = imgo[2*ii+1][2*jj-3]
|
||||||
|
C[tmp][2] = imgo[2*ii+3][2*jj-1]
|
||||||
|
C[tmp][3] = imgo[2*ii+1][2*jj+1]
|
||||||
|
tmp += 1
|
||||||
|
|
||||||
|
# calculating weights
|
||||||
|
# a = (C^T * C)^(-1) * (C^T * y) = (C^T * C) \ (C^T * y)
|
||||||
|
a = np.matmul(np.matmul(np.linalg.pinv(np.matmul(np.transpose(C),C)), np.transpose(C)), y)
|
||||||
|
imgo[2*i+1][2*j] = np.matmul([imgo[2*i][2*j], imgo[2*i+1][2*j-1], imgo[2*i+2][2*j], imgo[2*i+1][2*j+1]], a)
|
||||||
|
imgo[2*i][2*j+1] = np.matmul([imgo[2*i-1][2*j+1], imgo[2*i][2*j], imgo[2*i+1][2*j+1], imgo[2*i][2*j+2]], a)
|
||||||
|
|
||||||
|
# Fill the rest with bilinear interpolation
|
||||||
|
np.clip(imgo, 0, 255.0, out=imgo)
|
||||||
|
imgo_bilinear = cv2.resize(img, dsize=(h*2,w*2), interpolation=cv2.INTER_LINEAR)
|
||||||
|
imgo[imgo==0] = imgo_bilinear[imgo==0]
|
||||||
|
|
||||||
|
return imgo.astype(img.dtype)
|
||||||
|
|
||||||
|
def EDI_predict(img, m, s):
|
||||||
|
|
||||||
|
try:
|
||||||
|
w, h = img.shape
|
||||||
|
except:
|
||||||
|
sys.exit("Error input: Please input a valid grayscale image!")
|
||||||
|
|
||||||
|
output_type = img.dtype
|
||||||
|
|
||||||
|
if s <= 0:
|
||||||
|
sys.exit("Error input: Please input s > 0!")
|
||||||
|
|
||||||
|
elif s == 1:
|
||||||
|
print("No need to rescale since s = 1")
|
||||||
|
return img
|
||||||
|
|
||||||
|
elif s < 1:
|
||||||
|
# Calculate how many times to do the EDI downscaling
|
||||||
|
n = math.floor(math.log(1/s, 2))
|
||||||
|
|
||||||
|
# Downscale to the expected size with linear interpolation
|
||||||
|
linear_factor = 1/s / math.pow(2, n)
|
||||||
|
if linear_factor != 1:
|
||||||
|
img = cv2.resize(img, dsize=(int(h/linear_factor),int(w/linear_factor)), interpolation=cv2.INTER_LINEAR).astype(output_type)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
img = EDI_downscale(img)
|
||||||
|
return img
|
||||||
|
|
||||||
|
elif s < 2:
|
||||||
|
# Linear Interpolation is enough for upscaling not over 2
|
||||||
|
return cv2.resize(img, dsize=(int(h*s),int(w*s)), interpolation=cv2.INTER_LINEAR).astype(output_type)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Calculate how many times to do the EDI upscaling
|
||||||
|
n = math.floor(math.log(s, 2))
|
||||||
|
for i in range(n):
|
||||||
|
img = EDI_upscale(img, m)
|
||||||
|
|
||||||
|
# Upscale to the expected size with linear interpolation
|
||||||
|
linear_factor = s / math.pow(2, n)
|
||||||
|
if linear_factor == 1:
|
||||||
|
return img.astype(output_type)
|
||||||
|
|
||||||
|
# Update new shape
|
||||||
|
w, h = img.shape
|
||||||
|
return cv2.resize(img, dsize=(int(h*linear_factor),int(w*linear_factor)), interpolation=cv2.INTER_LINEAR).astype(output_type)
|
||||||
|
|
||||||
BIN
bin/lib/models/realesr-animevideov3-x2.bin
Normal file
BIN
bin/lib/models/realesr-animevideov3-x2.bin
Normal file
Binary file not shown.
43
bin/lib/models/realesr-animevideov3-x2.param
Normal file
43
bin/lib/models/realesr-animevideov3-x2.param
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
7767517
|
||||||
|
41 42
|
||||||
|
Input input.1 0 1 data
|
||||||
|
Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1
|
||||||
|
Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728
|
||||||
|
PReLU PRelu_1 1 1 54 56 0=64
|
||||||
|
Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_3 1 1 57 59 0=64
|
||||||
|
Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_5 1 1 60 62 0=64
|
||||||
|
Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_7 1 1 63 65 0=64
|
||||||
|
Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_9 1 1 66 68 0=64
|
||||||
|
Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_11 1 1 69 71 0=64
|
||||||
|
Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_13 1 1 72 74 0=64
|
||||||
|
Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_15 1 1 75 77 0=64
|
||||||
|
Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_17 1 1 78 80 0=64
|
||||||
|
Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_19 1 1 81 83 0=64
|
||||||
|
Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_21 1 1 84 86 0=64
|
||||||
|
Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_23 1 1 87 89 0=64
|
||||||
|
Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_25 1 1 90 92 0=64
|
||||||
|
Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_27 1 1 93 95 0=64
|
||||||
|
Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_29 1 1 96 98 0=64
|
||||||
|
Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_31 1 1 99 101 0=64
|
||||||
|
Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_33 1 1 102 104 0=64
|
||||||
|
Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648
|
||||||
|
PixelShuffle DepthToSpace_35 1 1 105 106 0=4
|
||||||
|
Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00
|
||||||
|
BinaryOp Add_38 2 1 106 111 112
|
||||||
|
Interp Resize_40 1 1 112 output 0=3 1=5.000000e-01 2=5.000000e-01
|
||||||
BIN
bin/lib/models/realesr-animevideov3-x3.bin
Normal file
BIN
bin/lib/models/realesr-animevideov3-x3.bin
Normal file
Binary file not shown.
43
bin/lib/models/realesr-animevideov3-x3.param
Normal file
43
bin/lib/models/realesr-animevideov3-x3.param
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
7767517
|
||||||
|
41 42
|
||||||
|
Input input.1 0 1 data
|
||||||
|
Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1
|
||||||
|
Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728
|
||||||
|
PReLU PRelu_1 1 1 54 56 0=64
|
||||||
|
Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_3 1 1 57 59 0=64
|
||||||
|
Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_5 1 1 60 62 0=64
|
||||||
|
Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_7 1 1 63 65 0=64
|
||||||
|
Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_9 1 1 66 68 0=64
|
||||||
|
Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_11 1 1 69 71 0=64
|
||||||
|
Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_13 1 1 72 74 0=64
|
||||||
|
Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_15 1 1 75 77 0=64
|
||||||
|
Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_17 1 1 78 80 0=64
|
||||||
|
Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_19 1 1 81 83 0=64
|
||||||
|
Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_21 1 1 84 86 0=64
|
||||||
|
Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_23 1 1 87 89 0=64
|
||||||
|
Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_25 1 1 90 92 0=64
|
||||||
|
Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_27 1 1 93 95 0=64
|
||||||
|
Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_29 1 1 96 98 0=64
|
||||||
|
Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_31 1 1 99 101 0=64
|
||||||
|
Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_33 1 1 102 104 0=64
|
||||||
|
Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648
|
||||||
|
PixelShuffle DepthToSpace_35 1 1 105 106 0=4
|
||||||
|
Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00
|
||||||
|
BinaryOp Add_38 2 1 106 111 112
|
||||||
|
Interp Resize_40 1 1 112 output 0=3 1=7.500000e-01 2=7.500000e-01
|
||||||
BIN
bin/lib/models/realesr-animevideov3-x4.bin
Normal file
BIN
bin/lib/models/realesr-animevideov3-x4.bin
Normal file
Binary file not shown.
42
bin/lib/models/realesr-animevideov3-x4.param
Normal file
42
bin/lib/models/realesr-animevideov3-x4.param
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
7767517
|
||||||
|
40 41
|
||||||
|
Input input.1 0 1 data
|
||||||
|
Split splitncnn_input0 1 2 data input.1_splitncnn_0 input.1_splitncnn_1
|
||||||
|
Convolution Conv_0 1 1 input.1_splitncnn_1 54 0=64 1=3 4=1 5=1 6=1728
|
||||||
|
PReLU PRelu_1 1 1 54 56 0=64
|
||||||
|
Convolution Conv_2 1 1 56 57 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_3 1 1 57 59 0=64
|
||||||
|
Convolution Conv_4 1 1 59 60 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_5 1 1 60 62 0=64
|
||||||
|
Convolution Conv_6 1 1 62 63 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_7 1 1 63 65 0=64
|
||||||
|
Convolution Conv_8 1 1 65 66 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_9 1 1 66 68 0=64
|
||||||
|
Convolution Conv_10 1 1 68 69 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_11 1 1 69 71 0=64
|
||||||
|
Convolution Conv_12 1 1 71 72 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_13 1 1 72 74 0=64
|
||||||
|
Convolution Conv_14 1 1 74 75 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_15 1 1 75 77 0=64
|
||||||
|
Convolution Conv_16 1 1 77 78 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_17 1 1 78 80 0=64
|
||||||
|
Convolution Conv_18 1 1 80 81 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_19 1 1 81 83 0=64
|
||||||
|
Convolution Conv_20 1 1 83 84 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_21 1 1 84 86 0=64
|
||||||
|
Convolution Conv_22 1 1 86 87 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_23 1 1 87 89 0=64
|
||||||
|
Convolution Conv_24 1 1 89 90 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_25 1 1 90 92 0=64
|
||||||
|
Convolution Conv_26 1 1 92 93 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_27 1 1 93 95 0=64
|
||||||
|
Convolution Conv_28 1 1 95 96 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_29 1 1 96 98 0=64
|
||||||
|
Convolution Conv_30 1 1 98 99 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_31 1 1 99 101 0=64
|
||||||
|
Convolution Conv_32 1 1 101 102 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
PReLU PRelu_33 1 1 102 104 0=64
|
||||||
|
Convolution Conv_34 1 1 104 105 0=48 1=3 4=1 5=1 6=27648
|
||||||
|
PixelShuffle DepthToSpace_35 1 1 105 106 0=4
|
||||||
|
Interp Resize_37 1 1 input.1_splitncnn_0 111 0=1 1=4.000000e+00 2=4.000000e+00
|
||||||
|
BinaryOp Add_38 2 1 106 111 output
|
||||||
BIN
bin/lib/models/realesrgan-x4plus-anime.bin
Normal file
BIN
bin/lib/models/realesrgan-x4plus-anime.bin
Normal file
Binary file not shown.
270
bin/lib/models/realesrgan-x4plus-anime.param
Normal file
270
bin/lib/models/realesrgan-x4plus-anime.param
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
7767517
|
||||||
|
268 473
|
||||||
|
Input input.1 0 1 data
|
||||||
|
Convolution Conv_0 1 1 data 193 0=64 1=3 4=1 5=1 6=1728
|
||||||
|
Split splitncnn_0 1 8 193 193_splitncnn_0 193_splitncnn_1 193_splitncnn_2 193_splitncnn_3 193_splitncnn_4 193_splitncnn_5 193_splitncnn_6 193_splitncnn_7
|
||||||
|
Convolution Conv_1 1 1 193_splitncnn_7 195 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_1 1 4 195 195_splitncnn_0 195_splitncnn_1 195_splitncnn_2 195_splitncnn_3
|
||||||
|
Concat Concat_3 2 1 193_splitncnn_6 195_splitncnn_3 196
|
||||||
|
Convolution Conv_4 1 1 196 198 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_2 1 3 198 198_splitncnn_0 198_splitncnn_1 198_splitncnn_2
|
||||||
|
Concat Concat_6 3 1 193_splitncnn_5 195_splitncnn_2 198_splitncnn_2 199
|
||||||
|
Convolution Conv_7 1 1 199 201 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_3 1 2 201 201_splitncnn_0 201_splitncnn_1
|
||||||
|
Concat Concat_9 4 1 193_splitncnn_4 195_splitncnn_1 198_splitncnn_1 201_splitncnn_1 202
|
||||||
|
Convolution Conv_10 1 1 202 204 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_12 5 1 193_splitncnn_3 195_splitncnn_0 198_splitncnn_0 201_splitncnn_0 204 205
|
||||||
|
Convolution Conv_13 1 1 205 206 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_16 2 1 206 193_splitncnn_2 209 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_4 1 6 209 209_splitncnn_0 209_splitncnn_1 209_splitncnn_2 209_splitncnn_3 209_splitncnn_4 209_splitncnn_5
|
||||||
|
Convolution Conv_17 1 1 209_splitncnn_5 211 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_5 1 4 211 211_splitncnn_0 211_splitncnn_1 211_splitncnn_2 211_splitncnn_3
|
||||||
|
Concat Concat_19 2 1 209_splitncnn_4 211_splitncnn_3 212
|
||||||
|
Convolution Conv_20 1 1 212 214 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_6 1 3 214 214_splitncnn_0 214_splitncnn_1 214_splitncnn_2
|
||||||
|
Concat Concat_22 3 1 209_splitncnn_3 211_splitncnn_2 214_splitncnn_2 215
|
||||||
|
Convolution Conv_23 1 1 215 217 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_7 1 2 217 217_splitncnn_0 217_splitncnn_1
|
||||||
|
Concat Concat_25 4 1 209_splitncnn_2 211_splitncnn_1 214_splitncnn_1 217_splitncnn_1 218
|
||||||
|
Convolution Conv_26 1 1 218 220 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_28 5 1 209_splitncnn_1 211_splitncnn_0 214_splitncnn_0 217_splitncnn_0 220 221
|
||||||
|
Convolution Conv_29 1 1 221 222 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_32 2 1 222 209_splitncnn_0 225 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_8 1 6 225 225_splitncnn_0 225_splitncnn_1 225_splitncnn_2 225_splitncnn_3 225_splitncnn_4 225_splitncnn_5
|
||||||
|
Convolution Conv_33 1 1 225_splitncnn_5 227 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_9 1 4 227 227_splitncnn_0 227_splitncnn_1 227_splitncnn_2 227_splitncnn_3
|
||||||
|
Concat Concat_35 2 1 225_splitncnn_4 227_splitncnn_3 228
|
||||||
|
Convolution Conv_36 1 1 228 230 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_10 1 3 230 230_splitncnn_0 230_splitncnn_1 230_splitncnn_2
|
||||||
|
Concat Concat_38 3 1 225_splitncnn_3 227_splitncnn_2 230_splitncnn_2 231
|
||||||
|
Convolution Conv_39 1 1 231 233 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_11 1 2 233 233_splitncnn_0 233_splitncnn_1
|
||||||
|
Concat Concat_41 4 1 225_splitncnn_2 227_splitncnn_1 230_splitncnn_1 233_splitncnn_1 234
|
||||||
|
Convolution Conv_42 1 1 234 236 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_44 5 1 225_splitncnn_1 227_splitncnn_0 230_splitncnn_0 233_splitncnn_0 236 237
|
||||||
|
Convolution Conv_45 1 1 237 238 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_48 2 1 238 225_splitncnn_0 241 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_51 2 1 241 193_splitncnn_1 244 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_12 1 7 244 244_splitncnn_0 244_splitncnn_1 244_splitncnn_2 244_splitncnn_3 244_splitncnn_4 244_splitncnn_5 244_splitncnn_6
|
||||||
|
Convolution Conv_52 1 1 244_splitncnn_6 246 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_13 1 4 246 246_splitncnn_0 246_splitncnn_1 246_splitncnn_2 246_splitncnn_3
|
||||||
|
Concat Concat_54 2 1 244_splitncnn_5 246_splitncnn_3 247
|
||||||
|
Convolution Conv_55 1 1 247 249 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_14 1 3 249 249_splitncnn_0 249_splitncnn_1 249_splitncnn_2
|
||||||
|
Concat Concat_57 3 1 244_splitncnn_4 246_splitncnn_2 249_splitncnn_2 250
|
||||||
|
Convolution Conv_58 1 1 250 252 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_15 1 2 252 252_splitncnn_0 252_splitncnn_1
|
||||||
|
Concat Concat_60 4 1 244_splitncnn_3 246_splitncnn_1 249_splitncnn_1 252_splitncnn_1 253
|
||||||
|
Convolution Conv_61 1 1 253 255 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_63 5 1 244_splitncnn_2 246_splitncnn_0 249_splitncnn_0 252_splitncnn_0 255 256
|
||||||
|
Convolution Conv_64 1 1 256 257 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_67 2 1 257 244_splitncnn_1 260 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_16 1 6 260 260_splitncnn_0 260_splitncnn_1 260_splitncnn_2 260_splitncnn_3 260_splitncnn_4 260_splitncnn_5
|
||||||
|
Convolution Conv_68 1 1 260_splitncnn_5 262 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_17 1 4 262 262_splitncnn_0 262_splitncnn_1 262_splitncnn_2 262_splitncnn_3
|
||||||
|
Concat Concat_70 2 1 260_splitncnn_4 262_splitncnn_3 263
|
||||||
|
Convolution Conv_71 1 1 263 265 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_18 1 3 265 265_splitncnn_0 265_splitncnn_1 265_splitncnn_2
|
||||||
|
Concat Concat_73 3 1 260_splitncnn_3 262_splitncnn_2 265_splitncnn_2 266
|
||||||
|
Convolution Conv_74 1 1 266 268 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_19 1 2 268 268_splitncnn_0 268_splitncnn_1
|
||||||
|
Concat Concat_76 4 1 260_splitncnn_2 262_splitncnn_1 265_splitncnn_1 268_splitncnn_1 269
|
||||||
|
Convolution Conv_77 1 1 269 271 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_79 5 1 260_splitncnn_1 262_splitncnn_0 265_splitncnn_0 268_splitncnn_0 271 272
|
||||||
|
Convolution Conv_80 1 1 272 273 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_83 2 1 273 260_splitncnn_0 276 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_20 1 6 276 276_splitncnn_0 276_splitncnn_1 276_splitncnn_2 276_splitncnn_3 276_splitncnn_4 276_splitncnn_5
|
||||||
|
Convolution Conv_84 1 1 276_splitncnn_5 278 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_21 1 4 278 278_splitncnn_0 278_splitncnn_1 278_splitncnn_2 278_splitncnn_3
|
||||||
|
Concat Concat_86 2 1 276_splitncnn_4 278_splitncnn_3 279
|
||||||
|
Convolution Conv_87 1 1 279 281 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_22 1 3 281 281_splitncnn_0 281_splitncnn_1 281_splitncnn_2
|
||||||
|
Concat Concat_89 3 1 276_splitncnn_3 278_splitncnn_2 281_splitncnn_2 282
|
||||||
|
Convolution Conv_90 1 1 282 284 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_23 1 2 284 284_splitncnn_0 284_splitncnn_1
|
||||||
|
Concat Concat_92 4 1 276_splitncnn_2 278_splitncnn_1 281_splitncnn_1 284_splitncnn_1 285
|
||||||
|
Convolution Conv_93 1 1 285 287 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_95 5 1 276_splitncnn_1 278_splitncnn_0 281_splitncnn_0 284_splitncnn_0 287 288
|
||||||
|
Convolution Conv_96 1 1 288 289 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_99 2 1 289 276_splitncnn_0 292 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_102 2 1 292 244_splitncnn_0 295 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_24 1 7 295 295_splitncnn_0 295_splitncnn_1 295_splitncnn_2 295_splitncnn_3 295_splitncnn_4 295_splitncnn_5 295_splitncnn_6
|
||||||
|
Convolution Conv_103 1 1 295_splitncnn_6 297 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_25 1 4 297 297_splitncnn_0 297_splitncnn_1 297_splitncnn_2 297_splitncnn_3
|
||||||
|
Concat Concat_105 2 1 295_splitncnn_5 297_splitncnn_3 298
|
||||||
|
Convolution Conv_106 1 1 298 300 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_26 1 3 300 300_splitncnn_0 300_splitncnn_1 300_splitncnn_2
|
||||||
|
Concat Concat_108 3 1 295_splitncnn_4 297_splitncnn_2 300_splitncnn_2 301
|
||||||
|
Convolution Conv_109 1 1 301 303 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_27 1 2 303 303_splitncnn_0 303_splitncnn_1
|
||||||
|
Concat Concat_111 4 1 295_splitncnn_3 297_splitncnn_1 300_splitncnn_1 303_splitncnn_1 304
|
||||||
|
Convolution Conv_112 1 1 304 306 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_114 5 1 295_splitncnn_2 297_splitncnn_0 300_splitncnn_0 303_splitncnn_0 306 307
|
||||||
|
Convolution Conv_115 1 1 307 308 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_118 2 1 308 295_splitncnn_1 311 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_28 1 6 311 311_splitncnn_0 311_splitncnn_1 311_splitncnn_2 311_splitncnn_3 311_splitncnn_4 311_splitncnn_5
|
||||||
|
Convolution Conv_119 1 1 311_splitncnn_5 313 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_29 1 4 313 313_splitncnn_0 313_splitncnn_1 313_splitncnn_2 313_splitncnn_3
|
||||||
|
Concat Concat_121 2 1 311_splitncnn_4 313_splitncnn_3 314
|
||||||
|
Convolution Conv_122 1 1 314 316 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_30 1 3 316 316_splitncnn_0 316_splitncnn_1 316_splitncnn_2
|
||||||
|
Concat Concat_124 3 1 311_splitncnn_3 313_splitncnn_2 316_splitncnn_2 317
|
||||||
|
Convolution Conv_125 1 1 317 319 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_31 1 2 319 319_splitncnn_0 319_splitncnn_1
|
||||||
|
Concat Concat_127 4 1 311_splitncnn_2 313_splitncnn_1 316_splitncnn_1 319_splitncnn_1 320
|
||||||
|
Convolution Conv_128 1 1 320 322 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_130 5 1 311_splitncnn_1 313_splitncnn_0 316_splitncnn_0 319_splitncnn_0 322 323
|
||||||
|
Convolution Conv_131 1 1 323 324 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_134 2 1 324 311_splitncnn_0 327 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_32 1 6 327 327_splitncnn_0 327_splitncnn_1 327_splitncnn_2 327_splitncnn_3 327_splitncnn_4 327_splitncnn_5
|
||||||
|
Convolution Conv_135 1 1 327_splitncnn_5 329 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_33 1 4 329 329_splitncnn_0 329_splitncnn_1 329_splitncnn_2 329_splitncnn_3
|
||||||
|
Concat Concat_137 2 1 327_splitncnn_4 329_splitncnn_3 330
|
||||||
|
Convolution Conv_138 1 1 330 332 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_34 1 3 332 332_splitncnn_0 332_splitncnn_1 332_splitncnn_2
|
||||||
|
Concat Concat_140 3 1 327_splitncnn_3 329_splitncnn_2 332_splitncnn_2 333
|
||||||
|
Convolution Conv_141 1 1 333 335 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_35 1 2 335 335_splitncnn_0 335_splitncnn_1
|
||||||
|
Concat Concat_143 4 1 327_splitncnn_2 329_splitncnn_1 332_splitncnn_1 335_splitncnn_1 336
|
||||||
|
Convolution Conv_144 1 1 336 338 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_146 5 1 327_splitncnn_1 329_splitncnn_0 332_splitncnn_0 335_splitncnn_0 338 339
|
||||||
|
Convolution Conv_147 1 1 339 340 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_150 2 1 340 327_splitncnn_0 343 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_153 2 1 343 295_splitncnn_0 346 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_36 1 7 346 346_splitncnn_0 346_splitncnn_1 346_splitncnn_2 346_splitncnn_3 346_splitncnn_4 346_splitncnn_5 346_splitncnn_6
|
||||||
|
Convolution Conv_154 1 1 346_splitncnn_6 348 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_37 1 4 348 348_splitncnn_0 348_splitncnn_1 348_splitncnn_2 348_splitncnn_3
|
||||||
|
Concat Concat_156 2 1 346_splitncnn_5 348_splitncnn_3 349
|
||||||
|
Convolution Conv_157 1 1 349 351 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_38 1 3 351 351_splitncnn_0 351_splitncnn_1 351_splitncnn_2
|
||||||
|
Concat Concat_159 3 1 346_splitncnn_4 348_splitncnn_2 351_splitncnn_2 352
|
||||||
|
Convolution Conv_160 1 1 352 354 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_39 1 2 354 354_splitncnn_0 354_splitncnn_1
|
||||||
|
Concat Concat_162 4 1 346_splitncnn_3 348_splitncnn_1 351_splitncnn_1 354_splitncnn_1 355
|
||||||
|
Convolution Conv_163 1 1 355 357 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_165 5 1 346_splitncnn_2 348_splitncnn_0 351_splitncnn_0 354_splitncnn_0 357 358
|
||||||
|
Convolution Conv_166 1 1 358 359 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_169 2 1 359 346_splitncnn_1 362 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_40 1 6 362 362_splitncnn_0 362_splitncnn_1 362_splitncnn_2 362_splitncnn_3 362_splitncnn_4 362_splitncnn_5
|
||||||
|
Convolution Conv_170 1 1 362_splitncnn_5 364 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_41 1 4 364 364_splitncnn_0 364_splitncnn_1 364_splitncnn_2 364_splitncnn_3
|
||||||
|
Concat Concat_172 2 1 362_splitncnn_4 364_splitncnn_3 365
|
||||||
|
Convolution Conv_173 1 1 365 367 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_42 1 3 367 367_splitncnn_0 367_splitncnn_1 367_splitncnn_2
|
||||||
|
Concat Concat_175 3 1 362_splitncnn_3 364_splitncnn_2 367_splitncnn_2 368
|
||||||
|
Convolution Conv_176 1 1 368 370 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_43 1 2 370 370_splitncnn_0 370_splitncnn_1
|
||||||
|
Concat Concat_178 4 1 362_splitncnn_2 364_splitncnn_1 367_splitncnn_1 370_splitncnn_1 371
|
||||||
|
Convolution Conv_179 1 1 371 373 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_181 5 1 362_splitncnn_1 364_splitncnn_0 367_splitncnn_0 370_splitncnn_0 373 374
|
||||||
|
Convolution Conv_182 1 1 374 375 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_185 2 1 375 362_splitncnn_0 378 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_44 1 6 378 378_splitncnn_0 378_splitncnn_1 378_splitncnn_2 378_splitncnn_3 378_splitncnn_4 378_splitncnn_5
|
||||||
|
Convolution Conv_186 1 1 378_splitncnn_5 380 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_45 1 4 380 380_splitncnn_0 380_splitncnn_1 380_splitncnn_2 380_splitncnn_3
|
||||||
|
Concat Concat_188 2 1 378_splitncnn_4 380_splitncnn_3 381
|
||||||
|
Convolution Conv_189 1 1 381 383 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_46 1 3 383 383_splitncnn_0 383_splitncnn_1 383_splitncnn_2
|
||||||
|
Concat Concat_191 3 1 378_splitncnn_3 380_splitncnn_2 383_splitncnn_2 384
|
||||||
|
Convolution Conv_192 1 1 384 386 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_47 1 2 386 386_splitncnn_0 386_splitncnn_1
|
||||||
|
Concat Concat_194 4 1 378_splitncnn_2 380_splitncnn_1 383_splitncnn_1 386_splitncnn_1 387
|
||||||
|
Convolution Conv_195 1 1 387 389 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_197 5 1 378_splitncnn_1 380_splitncnn_0 383_splitncnn_0 386_splitncnn_0 389 390
|
||||||
|
Convolution Conv_198 1 1 390 391 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_201 2 1 391 378_splitncnn_0 394 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_204 2 1 394 346_splitncnn_0 397 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_48 1 7 397 397_splitncnn_0 397_splitncnn_1 397_splitncnn_2 397_splitncnn_3 397_splitncnn_4 397_splitncnn_5 397_splitncnn_6
|
||||||
|
Convolution Conv_205 1 1 397_splitncnn_6 399 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_49 1 4 399 399_splitncnn_0 399_splitncnn_1 399_splitncnn_2 399_splitncnn_3
|
||||||
|
Concat Concat_207 2 1 397_splitncnn_5 399_splitncnn_3 400
|
||||||
|
Convolution Conv_208 1 1 400 402 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_50 1 3 402 402_splitncnn_0 402_splitncnn_1 402_splitncnn_2
|
||||||
|
Concat Concat_210 3 1 397_splitncnn_4 399_splitncnn_2 402_splitncnn_2 403
|
||||||
|
Convolution Conv_211 1 1 403 405 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_51 1 2 405 405_splitncnn_0 405_splitncnn_1
|
||||||
|
Concat Concat_213 4 1 397_splitncnn_3 399_splitncnn_1 402_splitncnn_1 405_splitncnn_1 406
|
||||||
|
Convolution Conv_214 1 1 406 408 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_216 5 1 397_splitncnn_2 399_splitncnn_0 402_splitncnn_0 405_splitncnn_0 408 409
|
||||||
|
Convolution Conv_217 1 1 409 410 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_220 2 1 410 397_splitncnn_1 413 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_52 1 6 413 413_splitncnn_0 413_splitncnn_1 413_splitncnn_2 413_splitncnn_3 413_splitncnn_4 413_splitncnn_5
|
||||||
|
Convolution Conv_221 1 1 413_splitncnn_5 415 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_53 1 4 415 415_splitncnn_0 415_splitncnn_1 415_splitncnn_2 415_splitncnn_3
|
||||||
|
Concat Concat_223 2 1 413_splitncnn_4 415_splitncnn_3 416
|
||||||
|
Convolution Conv_224 1 1 416 418 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_54 1 3 418 418_splitncnn_0 418_splitncnn_1 418_splitncnn_2
|
||||||
|
Concat Concat_226 3 1 413_splitncnn_3 415_splitncnn_2 418_splitncnn_2 419
|
||||||
|
Convolution Conv_227 1 1 419 421 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_55 1 2 421 421_splitncnn_0 421_splitncnn_1
|
||||||
|
Concat Concat_229 4 1 413_splitncnn_2 415_splitncnn_1 418_splitncnn_1 421_splitncnn_1 422
|
||||||
|
Convolution Conv_230 1 1 422 424 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_232 5 1 413_splitncnn_1 415_splitncnn_0 418_splitncnn_0 421_splitncnn_0 424 425
|
||||||
|
Convolution Conv_233 1 1 425 426 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_236 2 1 426 413_splitncnn_0 429 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_56 1 6 429 429_splitncnn_0 429_splitncnn_1 429_splitncnn_2 429_splitncnn_3 429_splitncnn_4 429_splitncnn_5
|
||||||
|
Convolution Conv_237 1 1 429_splitncnn_5 431 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_57 1 4 431 431_splitncnn_0 431_splitncnn_1 431_splitncnn_2 431_splitncnn_3
|
||||||
|
Concat Concat_239 2 1 429_splitncnn_4 431_splitncnn_3 432
|
||||||
|
Convolution Conv_240 1 1 432 434 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_58 1 3 434 434_splitncnn_0 434_splitncnn_1 434_splitncnn_2
|
||||||
|
Concat Concat_242 3 1 429_splitncnn_3 431_splitncnn_2 434_splitncnn_2 435
|
||||||
|
Convolution Conv_243 1 1 435 437 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_59 1 2 437 437_splitncnn_0 437_splitncnn_1
|
||||||
|
Concat Concat_245 4 1 429_splitncnn_2 431_splitncnn_1 434_splitncnn_1 437_splitncnn_1 438
|
||||||
|
Convolution Conv_246 1 1 438 440 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_248 5 1 429_splitncnn_1 431_splitncnn_0 434_splitncnn_0 437_splitncnn_0 440 441
|
||||||
|
Convolution Conv_249 1 1 441 442 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_252 2 1 442 429_splitncnn_0 445 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_255 2 1 445 397_splitncnn_0 448 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_60 1 7 448 448_splitncnn_0 448_splitncnn_1 448_splitncnn_2 448_splitncnn_3 448_splitncnn_4 448_splitncnn_5 448_splitncnn_6
|
||||||
|
Convolution Conv_256 1 1 448_splitncnn_6 450 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_61 1 4 450 450_splitncnn_0 450_splitncnn_1 450_splitncnn_2 450_splitncnn_3
|
||||||
|
Concat Concat_258 2 1 448_splitncnn_5 450_splitncnn_3 451
|
||||||
|
Convolution Conv_259 1 1 451 453 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_62 1 3 453 453_splitncnn_0 453_splitncnn_1 453_splitncnn_2
|
||||||
|
Concat Concat_261 3 1 448_splitncnn_4 450_splitncnn_2 453_splitncnn_2 454
|
||||||
|
Convolution Conv_262 1 1 454 456 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_63 1 2 456 456_splitncnn_0 456_splitncnn_1
|
||||||
|
Concat Concat_264 4 1 448_splitncnn_3 450_splitncnn_1 453_splitncnn_1 456_splitncnn_1 457
|
||||||
|
Convolution Conv_265 1 1 457 459 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_267 5 1 448_splitncnn_2 450_splitncnn_0 453_splitncnn_0 456_splitncnn_0 459 460
|
||||||
|
Convolution Conv_268 1 1 460 461 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_271 2 1 461 448_splitncnn_1 464 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_64 1 6 464 464_splitncnn_0 464_splitncnn_1 464_splitncnn_2 464_splitncnn_3 464_splitncnn_4 464_splitncnn_5
|
||||||
|
Convolution Conv_272 1 1 464_splitncnn_5 466 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_65 1 4 466 466_splitncnn_0 466_splitncnn_1 466_splitncnn_2 466_splitncnn_3
|
||||||
|
Concat Concat_274 2 1 464_splitncnn_4 466_splitncnn_3 467
|
||||||
|
Convolution Conv_275 1 1 467 469 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_66 1 3 469 469_splitncnn_0 469_splitncnn_1 469_splitncnn_2
|
||||||
|
Concat Concat_277 3 1 464_splitncnn_3 466_splitncnn_2 469_splitncnn_2 470
|
||||||
|
Convolution Conv_278 1 1 470 472 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_67 1 2 472 472_splitncnn_0 472_splitncnn_1
|
||||||
|
Concat Concat_280 4 1 464_splitncnn_2 466_splitncnn_1 469_splitncnn_1 472_splitncnn_1 473
|
||||||
|
Convolution Conv_281 1 1 473 475 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_283 5 1 464_splitncnn_1 466_splitncnn_0 469_splitncnn_0 472_splitncnn_0 475 476
|
||||||
|
Convolution Conv_284 1 1 476 477 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_287 2 1 477 464_splitncnn_0 480 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Split splitncnn_68 1 6 480 480_splitncnn_0 480_splitncnn_1 480_splitncnn_2 480_splitncnn_3 480_splitncnn_4 480_splitncnn_5
|
||||||
|
Convolution Conv_288 1 1 480_splitncnn_5 482 0=32 1=3 4=1 5=1 6=18432 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_69 1 4 482 482_splitncnn_0 482_splitncnn_1 482_splitncnn_2 482_splitncnn_3
|
||||||
|
Concat Concat_290 2 1 480_splitncnn_4 482_splitncnn_3 483
|
||||||
|
Convolution Conv_291 1 1 483 485 0=32 1=3 4=1 5=1 6=27648 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_70 1 3 485 485_splitncnn_0 485_splitncnn_1 485_splitncnn_2
|
||||||
|
Concat Concat_293 3 1 480_splitncnn_3 482_splitncnn_2 485_splitncnn_2 486
|
||||||
|
Convolution Conv_294 1 1 486 488 0=32 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Split splitncnn_71 1 2 488 488_splitncnn_0 488_splitncnn_1
|
||||||
|
Concat Concat_296 4 1 480_splitncnn_2 482_splitncnn_1 485_splitncnn_1 488_splitncnn_1 489
|
||||||
|
Convolution Conv_297 1 1 489 491 0=32 1=3 4=1 5=1 6=46080 9=2 -23310=1,2.000000e-01
|
||||||
|
Concat Concat_299 5 1 480_splitncnn_1 482_splitncnn_0 485_splitncnn_0 488_splitncnn_0 491 492
|
||||||
|
Convolution Conv_300 1 1 492 493 0=64 1=3 4=1 5=1 6=110592
|
||||||
|
Eltwise Add_303 2 1 493 480_splitncnn_0 496 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Eltwise Add_306 2 1 496 448_splitncnn_0 499 0=1 -23301=2,2.000000e-01,1.000000e+00
|
||||||
|
Convolution Conv_307 1 1 499 500 0=64 1=3 4=1 5=1 6=36864
|
||||||
|
BinaryOp Add_308 2 1 193_splitncnn_0 500 501
|
||||||
|
Interp Resize_310 1 1 501 506 0=1 1=2.000000e+00 2=2.000000e+00
|
||||||
|
Convolution Conv_311 1 1 506 508 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Interp Resize_314 1 1 508 513 0=1 1=2.000000e+00 2=2.000000e+00
|
||||||
|
Convolution Conv_315 1 1 513 515 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Convolution Conv_317 1 1 515 517 0=64 1=3 4=1 5=1 6=36864 9=2 -23310=1,2.000000e-01
|
||||||
|
Convolution Conv_319 1 1 517 output 0=3 1=3 4=1 5=1 6=1728
|
||||||
BIN
bin/lib/models/realesrgan-x4plus.bin
Normal file
BIN
bin/lib/models/realesrgan-x4plus.bin
Normal file
Binary file not shown.
1001
bin/lib/models/realesrgan-x4plus.param
Normal file
1001
bin/lib/models/realesrgan-x4plus.param
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/lib/realesrgan-ncnn-vulkan.exe
Normal file
BIN
bin/lib/realesrgan-ncnn-vulkan.exe
Normal file
Binary file not shown.
15
bin/lib/test.py
Normal file
15
bin/lib/test.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import edi
|
||||||
|
import numpy as np
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
ap = argparse.ArgumentParser( description='Testing for edi. NOTE: No error catching!' )
|
||||||
|
ap.add_argument( 'inputfile', help='Input file for upscaling' )
|
||||||
|
ap.add_argument( 'outputfile', help='Output file' )
|
||||||
|
ap.add_argument( '-S', '--scalefactor', help='Scale factor' )
|
||||||
|
ap.add_argument( '-a', '--sampling', help='Sampling window size. The bigger, the blurrier. Best >= 4')
|
||||||
|
ap.set_defaults( sampling=4 )
|
||||||
|
ap.set_defaults( scalefactor=2 )
|
||||||
|
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
print( edi.EDI_predict( np.load( args.inputfile, allow_pickle=True ), args.sampling, args.scalefactor ) )
|
||||||
9
bin/pluginDownloader.py
Normal file
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
|
||||||
|
*
|
||||||
|
*
|
||||||
|
"""
|
||||||
|
|
||||||
64
bin/probe.py
Normal file
64
bin/probe.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
"""
|
||||||
|
This file here was created from multiple parts of ffmpeg-python
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
from collections.abc import Iterable
|
||||||
|
except ImportError:
|
||||||
|
from collections import Iterable
|
||||||
|
|
||||||
|
def convert_kwargs_to_cmd_line_args(kwargs):
|
||||||
|
"""Helper function to build command line arguments out of dict."""
|
||||||
|
args = []
|
||||||
|
for k in sorted(kwargs.keys()):
|
||||||
|
v = kwargs[k]
|
||||||
|
if isinstance(v, Iterable) and not isinstance(v, str):
|
||||||
|
for value in v:
|
||||||
|
args.append('-{}'.format(k))
|
||||||
|
if value is not None:
|
||||||
|
args.append('{}'.format(value))
|
||||||
|
continue
|
||||||
|
args.append('-{}'.format(k))
|
||||||
|
if v is not None:
|
||||||
|
args.append('{}'.format(v))
|
||||||
|
return args
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
def __init__(self, cmd, stdout, stderr):
|
||||||
|
super(Error, self).__init__(
|
||||||
|
'{} error (see stderr output for detail)'.format(cmd)
|
||||||
|
)
|
||||||
|
self.stdout = stdout
|
||||||
|
self.stderr = stderr
|
||||||
|
|
||||||
|
def probe(filename, cmd='ffprobe', timeout=None, **kwargs):
|
||||||
|
"""Run ffprobe on the specified file and return a JSON representation of the output.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
:class:`ffmpeg.Error`: if ffprobe returns a non-zero exit code,
|
||||||
|
an :class:`Error` is returned with a generic error message.
|
||||||
|
The stderr output can be retrieved by accessing the
|
||||||
|
``stderr`` property of the exception.
|
||||||
|
"""
|
||||||
|
args = [cmd, '-show_format', '-show_streams', '-of', 'json']
|
||||||
|
args += convert_kwargs_to_cmd_line_args(kwargs)
|
||||||
|
args += [filename]
|
||||||
|
|
||||||
|
if ( sys.platform == 'win32' ):
|
||||||
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||||
|
else:
|
||||||
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
communicate_kwargs = {}
|
||||||
|
if timeout is not None:
|
||||||
|
communicate_kwargs['timeout'] = timeout
|
||||||
|
out, err = p.communicate(**communicate_kwargs)
|
||||||
|
if p.returncode != 0:
|
||||||
|
raise Error('ffprobe', out, err)
|
||||||
|
return json.loads(out.decode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['probe']
|
||||||
5
config/settings.ini
Normal file → Executable file
5
config/settings.ini
Normal file → Executable file
@@ -1,8 +1,5 @@
|
|||||||
[PathSettings]
|
[PathSettings]
|
||||||
defaultOutputPath = $HOME/FSRImageVideoUpscaler/
|
defaultOutputPath = $HOME/FSRSimpleMediaUpscalerLite/
|
||||||
tmpPathLinux = /tmp/
|
|
||||||
tmpPathWindows = %TEMP%
|
|
||||||
ffmpeg = ./bin/lib/ffmpeg.exe
|
|
||||||
|
|
||||||
[DevSettings]
|
[DevSettings]
|
||||||
loggerReqLevel = DEBUG
|
loggerReqLevel = DEBUG
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import ffmpeg
|
|
||||||
|
|
||||||
|
|
||||||
class MetaDataParser:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_metadata(self, filepath):
|
|
||||||
return ffmpeg.probe(str(filepath))["streams"]
|
|
||||||
|
|
||||||
|
|
||||||
videometa = MetaDataParser().get_metadata("/mnt/storage/SORTED/Videos/OBS_Rec/Behalten/2019-12-19 18-21-36.mp4").pop(0)
|
|
||||||
duration = videometa.get("duration")
|
|
||||||
frames = videometa.get("nb_frames")
|
|
||||||
framerate = float(frames) / float(duration)
|
|
||||||
print(framerate)
|
|
||||||
print(videometa)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
test = f"ffmpeg"
|
|
||||||
os.system(test)
|
|
||||||
4
frontend/.browserslistrc
Normal file
4
frontend/.browserslistrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
|
not dead
|
||||||
|
not ie 11
|
||||||
17
frontend/.eslintrc.js
Normal file
17
frontend/.eslintrc.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
'extends': [
|
||||||
|
'plugin:vue/vue3-essential',
|
||||||
|
'eslint:recommended'
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@babel/eslint-parser'
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||||
|
}
|
||||||
|
}
|
||||||
26
frontend/.gitignore
vendored
Normal file
26
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
#Electron-builder output
|
||||||
|
/dist_electron
|
||||||
24
frontend/README.md
Normal file
24
frontend/README.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# SimpleMediaUpscalerLite
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
5
frontend/babel.config.js
Normal file
5
frontend/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
19
frontend/jsconfig.json
Normal file
19
frontend/jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
frontend/logo.png
Executable file
BIN
frontend/logo.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 592 KiB |
28191
frontend/package-lock.json
generated
Normal file
28191
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
49
frontend/package.json
Normal file
49
frontend/package.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"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",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint",
|
||||||
|
"electron:build": "vue-cli-service electron:build",
|
||||||
|
"electron:serve": "vue-cli-service electron:serve",
|
||||||
|
"postinstall": "electron-builder install-app-deps",
|
||||||
|
"postuninstall": "electron-builder install-app-deps"
|
||||||
|
},
|
||||||
|
"main": "background.js",
|
||||||
|
"dependencies": {
|
||||||
|
"child_process": "^1.0.2",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
|
"vue": "^3.2.13",
|
||||||
|
"vue-router": "^4.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.16",
|
||||||
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@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",
|
||||||
|
"vue-cli-plugin-electron-builder": "~2.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
frontend/public/favicon.ico
Normal file
BIN
frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
17
frontend/public/index.html
Normal file
17
frontend/public/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
frontend/public/lang/about/en.json
Normal file
0
frontend/public/lang/about/en.json
Normal file
0
frontend/public/lang/home/en.json
Normal file
0
frontend/public/lang/home/en.json
Normal file
0
frontend/public/lang/settings/en.json
Normal file
0
frontend/public/lang/settings/en.json
Normal file
118
frontend/src/App.vue
Normal file
118
frontend/src/App.vue
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<component :is="Component" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'app',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
theme: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTheme () {
|
||||||
|
if ( this.theme === '☼' ) {
|
||||||
|
document.documentElement.classList.remove( 'dark' );
|
||||||
|
document.documentElement.classList.add( 'light' );
|
||||||
|
sessionStorage.setItem( 'theme', '☽' );
|
||||||
|
this.theme = '☽';
|
||||||
|
} else if ( this.theme === '☽' ) {
|
||||||
|
document.documentElement.classList.remove( 'light' );
|
||||||
|
document.documentElement.classList.add( 'dark' );
|
||||||
|
sessionStorage.setItem( 'theme', '☼' );
|
||||||
|
this.theme = '☼';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.theme = sessionStorage.getItem( 'theme' ) ? sessionStorage.getItem( 'theme' ) : '';
|
||||||
|
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches || this.theme === '☼' ) {
|
||||||
|
document.documentElement.classList.add( 'dark' );
|
||||||
|
this.theme = '☼';
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add( 'light' );
|
||||||
|
this.theme = '☽';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<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 {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
background-color: var( --background-color );
|
||||||
|
color: var( --foreground-color );
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a.router-link-exact-active {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scale-enter-active,
|
||||||
|
.scale-leave-active {
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scale-enter-from,
|
||||||
|
.scale-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
40
frontend/src/app.js
Normal file
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
Executable file
BIN
frontend/src/assets/logo.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 592 KiB |
84
frontend/src/background.js
Normal file
84
frontend/src/background.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
'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';
|
||||||
|
const path = require( 'path' );
|
||||||
|
|
||||||
|
|
||||||
|
// Scheme must be registered before the app is ready
|
||||||
|
protocol.registerSchemesAsPrivileged([
|
||||||
|
{ scheme: 'app', privileges: { secure: true, standard: true } }
|
||||||
|
])
|
||||||
|
|
||||||
|
async function createWindow() {
|
||||||
|
// Create the browser window.
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
webPreferences: {
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
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)
|
||||||
|
if (!process.env.IS_TEST) win.webContents.openDevTools()
|
||||||
|
} else {
|
||||||
|
createProtocol('app')
|
||||||
|
// Load the index.html when not in development
|
||||||
|
win.loadURL('app://./index.html')
|
||||||
|
}
|
||||||
|
require( './app.js' )( win );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quit when all windows are closed.
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
// On macOS it is common for applications and their menu bar
|
||||||
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
// On macOS it's common to re-create a window in the app when the
|
||||||
|
// dock icon is clicked and there are no other windows open.
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
// This method will be called when Electron has finished
|
||||||
|
// initialization and is ready to create browser windows.
|
||||||
|
// Some APIs can only be used after this event occurs.
|
||||||
|
app.on('ready', async () => {
|
||||||
|
if (isDevelopment && !process.env.IS_TEST) {
|
||||||
|
// Install Vue Devtools
|
||||||
|
try {
|
||||||
|
await installExtension(VUEJS3_DEVTOOLS)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Vue Devtools failed to install:', e.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Exit cleanly on request from parent process in development mode.
|
||||||
|
if (isDevelopment) {
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
process.on('message', (data) => {
|
||||||
|
if (data === 'graceful-exit') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
59
frontend/src/components/HelloWorld.vue
Normal file
59
frontend/src/components/HelloWorld.vue
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<div class="hello">
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
<p>
|
||||||
|
For a guide and recipes on how to configure / customize this project,<br>
|
||||||
|
check out the
|
||||||
|
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||||
|
</p>
|
||||||
|
<h3>Installed CLI Plugins</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||||
|
</ul>
|
||||||
|
<h3>Essential Links</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||||
|
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||||
|
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||||
|
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||||
|
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||||
|
</ul>
|
||||||
|
<h3>Ecosystem</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||||
|
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||||
|
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||||
|
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HelloWorld',
|
||||||
|
props: {
|
||||||
|
msg: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
h3 {
|
||||||
|
margin: 40px 0 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
5
frontend/src/main.js
Normal file
5
frontend/src/main.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
|
||||||
|
createApp(App).use(router).mount('#app')
|
||||||
27
frontend/src/router/index.js
Normal file
27
frontend/src/router/index.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||||
|
import HomeView from '../views/HomeView.vue'
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'home',
|
||||||
|
component: HomeView
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
name: 'about',
|
||||||
|
component: () => import( '../views/AboutView.vue' )
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/settings',
|
||||||
|
name: 'settings',
|
||||||
|
component: () => import( '../views/SettingsView.vue' )
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: process.env.IS_ELECTRON ? createWebHashHistory() : createWebHistory(process.env.BASE_URL),
|
||||||
|
routes
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
||||||
92
frontend/src/upscalingHandler.js
Normal file
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;
|
||||||
33
frontend/src/views/AboutView.vue
Normal file
33
frontend/src/views/AboutView.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<div class="about">
|
||||||
|
<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 {{ appVersion }}. {{ versionNotice[ isUpToDate ] }}.</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
versionNotice: { true: '==> up to date', false: '==> New version available' },
|
||||||
|
appVersion: 'V2.0.0',
|
||||||
|
latestVersion: '',
|
||||||
|
isUpToDate: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
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>
|
||||||
308
frontend/src/views/HomeView.vue
Normal file
308
frontend/src/views/HomeView.vue
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
<template>
|
||||||
|
<div class="home">
|
||||||
|
<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
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>
|
||||||
27
frontend/vue.config.js
Normal file
27
frontend/vue.config.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
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: [ "**/*" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
###########################################################
|
|
||||||
#
|
|
||||||
# FSRImageVideoUpscalerFrontend written in GTK+
|
|
||||||
#
|
|
||||||
# This code is licensed under the GPL V3 License!
|
|
||||||
# Developed 2022 by Janis Hutz
|
|
||||||
#
|
|
||||||
###########################################################
|
|
||||||
import sys
|
|
||||||
import gi
|
|
||||||
import bin.handler
|
|
||||||
import multiprocessing
|
|
||||||
import bin.checks
|
|
||||||
import bin.arg_assembly
|
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
|
|
||||||
arg = bin.arg_assembly.ArgAssembly()
|
|
||||||
checks = bin.checks.Checks()
|
|
||||||
handler = bin.handler.Handler()
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorDialogFileMissing(Gtk.Dialog):
|
|
||||||
def __init__(self, parent):
|
|
||||||
super().__init__(title="Error", transient_for=parent, flags=0)
|
|
||||||
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
|
||||||
self.set_default_size(150, 100)
|
|
||||||
self.label = Gtk.Label(label=" No file specified. Please select an input AND output file! ")
|
|
||||||
self.box = self.get_content_area()
|
|
||||||
self.box.pack_start(self.label, True, True, 20)
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorDialogRunning(Gtk.Dialog):
|
|
||||||
def __init__(self, parent):
|
|
||||||
super().__init__(title="Error", transient_for=parent, flags=0)
|
|
||||||
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
|
||||||
self.set_default_size(150, 100)
|
|
||||||
self.label = Gtk.Label(label=" You are already upscaling. Please wait for the current job to finish! ")
|
|
||||||
self.box = self.get_content_area()
|
|
||||||
self.box.pack_start(self.label, True, True, 20)
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorDialogCheckFail(Gtk.Dialog):
|
|
||||||
def __init__(self, parent):
|
|
||||||
super().__init__(title="Error", transient_for=parent, flags=0)
|
|
||||||
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
|
||||||
self.set_default_size(150, 100)
|
|
||||||
self.label = Gtk.Label(label=" File and settings check failed. \n Make sure to specify the same file extension in the output like in the input \n make sure that the entries you made as settings are valid! (4 >= scale >= 1) ")
|
|
||||||
self.box = self.get_content_area()
|
|
||||||
self.box.pack_start(self.label, True, True, 20)
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
|
|
||||||
class HomeWindow(Gtk.Window):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(title="Test")
|
|
||||||
self.os_type = sys.platform
|
|
||||||
self.save_file = ""
|
|
||||||
self.open_file = ""
|
|
||||||
|
|
||||||
# Spawn box
|
|
||||||
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
self.sub_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
self.orient_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
self.top_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
self.quality_select_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
self.custom_quality_selector_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
|
|
||||||
# Headerbar
|
|
||||||
self.hb = Gtk.HeaderBar()
|
|
||||||
self.hb.set_show_close_button(True)
|
|
||||||
self.hb.props.title = "FSR Image & Video Upscaler"
|
|
||||||
self.set_titlebar(self.hb)
|
|
||||||
|
|
||||||
# Create filechooser button
|
|
||||||
self.filechoosebutton = Gtk.Button(label="Choose Input File")
|
|
||||||
self.filechoosebutton.connect("clicked", self.filechooser_clicked)
|
|
||||||
self.box.pack_start(self.filechoosebutton, True, True, 0)
|
|
||||||
|
|
||||||
# Create output filechooser button
|
|
||||||
self.opfchooserbutton = Gtk.Button(label="Choose Output File")
|
|
||||||
self.opfchooserbutton.connect("clicked", self.opfilechooser_clicked)
|
|
||||||
self.box.pack_start(self.opfchooserbutton, True, True, 0)
|
|
||||||
|
|
||||||
# Create start button
|
|
||||||
self.start_button = Gtk.Button(label="Start upscaling")
|
|
||||||
self.start_button.connect("clicked", self.start_clicked)
|
|
||||||
self.box.pack_start(self.start_button, True, True, 0)
|
|
||||||
|
|
||||||
# Create Input File label
|
|
||||||
self.ip_file_label = Gtk.Label(label="Choose input file")
|
|
||||||
|
|
||||||
# Create Output File label
|
|
||||||
self.op_file_label = Gtk.Label(label="Choose output file")
|
|
||||||
|
|
||||||
# Pack File labels
|
|
||||||
self.filebox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
self.filebox.pack_start(self.ip_file_label, True, True, 10)
|
|
||||||
self.filebox.pack_start(self.op_file_label, True, True, 10)
|
|
||||||
|
|
||||||
# QualitySelect
|
|
||||||
self.title = Gtk.Label(label="Upscaling Multiplier Presets")
|
|
||||||
self.qualities = Gtk.ListStore(str)
|
|
||||||
self.qualities.append(["2x"])
|
|
||||||
self.qualities.append(["1.7x"])
|
|
||||||
self.qualities.append(["1.5x"])
|
|
||||||
self.qualities.append(["1.3x"])
|
|
||||||
self.qualities.append(["Custom (will respect value below)"])
|
|
||||||
self.quality_select = Gtk.ComboBox.new_with_model(self.qualities)
|
|
||||||
self.text_renderer = Gtk.CellRendererText()
|
|
||||||
self.quality_select.pack_start(self.text_renderer, True)
|
|
||||||
self.quality_select.add_attribute(self.text_renderer, "text", 0)
|
|
||||||
self.quality_select.connect("changed", self.on_quality_change)
|
|
||||||
self.quality_select_shrink = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
self.quality_select_shrink.pack_start(self.quality_select, True, False, 10)
|
|
||||||
|
|
||||||
self.quality_select_box.pack_start(self.title, True, True, 0)
|
|
||||||
self.quality_select_box.pack_start(self.quality_select_shrink, True, True, 20)
|
|
||||||
|
|
||||||
# Custom Quality Selector
|
|
||||||
self.custom_quality_selector_title = Gtk.Label(label="Custom Upscaling Multiplier\nNOTE that factors greater than 2 are not recommended!\nFactors greater than 4 will not run!")
|
|
||||||
self.custom_quality_selector_shrink = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
self.custom_quality_selector = Gtk.Entry()
|
|
||||||
self.custom_quality_selector_shrink.pack_start(self.custom_quality_selector, True, False, 10)
|
|
||||||
|
|
||||||
self.custom_quality_selector_box.pack_start(self.custom_quality_selector_title, True, True, 0)
|
|
||||||
self.custom_quality_selector_box.pack_start(self.custom_quality_selector_shrink, True, True, 20)
|
|
||||||
|
|
||||||
# Info
|
|
||||||
self.infos = Gtk.Label(label="Settings")
|
|
||||||
|
|
||||||
# Details
|
|
||||||
self.details = Gtk.Label(label="Ready")
|
|
||||||
|
|
||||||
# Separator
|
|
||||||
self.separator = Gtk.Separator().new(Gtk.Orientation.HORIZONTAL)
|
|
||||||
|
|
||||||
# Packing boxes
|
|
||||||
self.top_box.pack_start(self.infos, True, True, 0)
|
|
||||||
self.top_box.pack_start(self.quality_select_box, True, True, 0)
|
|
||||||
self.top_box.pack_start(self.custom_quality_selector_box, True, True, 0)
|
|
||||||
self.top_box.pack_start(self.details, True, True, 0)
|
|
||||||
self.top_box.pack_start(self.separator, True, False, 0)
|
|
||||||
|
|
||||||
|
|
||||||
self.orient_box.pack_start(self.filebox, True, True, 0)
|
|
||||||
self.orient_box.pack_start(self.box, True, True, 0)
|
|
||||||
self.sub_box.pack_start(self.orient_box, True, True, 30)
|
|
||||||
self.main_box.pack_start(self.top_box, True, True, 0)
|
|
||||||
self.main_box.pack_end(self.sub_box, True, True, 5)
|
|
||||||
self.add(self.main_box)
|
|
||||||
|
|
||||||
def on_quality_change(self, quality):
|
|
||||||
# get data from quality changer
|
|
||||||
self.tree_iter = quality.get_active_iter()
|
|
||||||
if self.tree_iter is not None:
|
|
||||||
self.model = quality.get_model()
|
|
||||||
self.output = self.model[self.tree_iter][0]
|
|
||||||
|
|
||||||
def filechooser_clicked(self, widget):
|
|
||||||
self.filechooserdialog = Gtk.FileChooserDialog(title="Choose input file", action=Gtk.FileChooserAction.OPEN)
|
|
||||||
self.filechooserdialog.add_buttons(
|
|
||||||
Gtk.STOCK_CANCEL,
|
|
||||||
Gtk.ResponseType.CANCEL,
|
|
||||||
Gtk.STOCK_OPEN,
|
|
||||||
Gtk.ResponseType.OK,
|
|
||||||
)
|
|
||||||
self.response = self.filechooserdialog.run()
|
|
||||||
if self.response == Gtk.ResponseType.OK:
|
|
||||||
self.ip_file_label.set_text(self.filechooserdialog.get_filename())
|
|
||||||
self.open_file = self.filechooserdialog.get_filename()
|
|
||||||
elif self.response == Gtk.ResponseType.CANCEL:
|
|
||||||
pass
|
|
||||||
self.filechooserdialog.destroy()
|
|
||||||
|
|
||||||
def opfilechooser_clicked(self, widget):
|
|
||||||
self.filechooserdialog_save = Gtk.FileChooserDialog(title="Choose output file", action=Gtk.FileChooserAction.SAVE)
|
|
||||||
Gtk.FileChooser.set_do_overwrite_confirmation(self.filechooserdialog_save, True)
|
|
||||||
if self.os_type == "linux":
|
|
||||||
Gtk.FileChooser.set_current_folder(self.filechooserdialog_save, "/home")
|
|
||||||
elif self.os_type == "win32":
|
|
||||||
Gtk.FileChooser.set_current_folder(self.filechooserdialog_save, "%HOMEPATH%")
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
if str(self.open_file)[len(self.open_file) - 4:] == ".mp4":
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "video.mp4")
|
|
||||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".mkv":
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "video.mkv")
|
|
||||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".png":
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.png")
|
|
||||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".jpg":
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.jpg")
|
|
||||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".jpeg":
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.jpeg")
|
|
||||||
else:
|
|
||||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "")
|
|
||||||
self.filechooserdialog_save.add_buttons(
|
|
||||||
Gtk.STOCK_CANCEL,
|
|
||||||
Gtk.ResponseType.CANCEL,
|
|
||||||
Gtk.STOCK_SAVE,
|
|
||||||
Gtk.ResponseType.OK,
|
|
||||||
)
|
|
||||||
self.response = self.filechooserdialog_save.run()
|
|
||||||
if self.response == Gtk.ResponseType.OK:
|
|
||||||
self.op_file_label.set_text(self.filechooserdialog_save.get_filename())
|
|
||||||
self.save_file = self.filechooserdialog_save.get_filename()
|
|
||||||
elif self.response == Gtk.ResponseType.CANCEL:
|
|
||||||
pass
|
|
||||||
self.filechooserdialog_save.destroy()
|
|
||||||
|
|
||||||
def info_button(self):
|
|
||||||
self.info_dialog = Gtk.Dialog()
|
|
||||||
self.remove_event = Gtk.Button(label="Don't show again")
|
|
||||||
self.info_dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
|
||||||
self.info_dialog.set_default_size(150, 100)
|
|
||||||
self.box = self.info_dialog.get_content_area()
|
|
||||||
self.label = Gtk.Label(label=" Upscaling. This process will take long (if a Video). \n Duration depends on your Hardware and length and resolution of video \n You may see the output of the app, if you switch to the other window that is behind it. \n\n\n click \"ok\" to start upscaling")
|
|
||||||
self.box.pack_start(self.label, True, True, 0)
|
|
||||||
self.info_dialog.show_all()
|
|
||||||
self.info_response = self.info_dialog.run()
|
|
||||||
self.info_dialog.destroy()
|
|
||||||
|
|
||||||
def start_clicked(self, widget):
|
|
||||||
self.respawn = True
|
|
||||||
try:
|
|
||||||
if self.scaler.is_alive():
|
|
||||||
self.respawn = False
|
|
||||||
else:
|
|
||||||
self.respawn = True
|
|
||||||
|
|
||||||
except AttributeError:
|
|
||||||
self.respawn = True
|
|
||||||
|
|
||||||
if self.respawn:
|
|
||||||
if str(self.open_file) != "" and str(self.save_file) != "":
|
|
||||||
if checks.perform(self.output, self.custom_quality_selector.get_text(), self.open_file, self.save_file):
|
|
||||||
if self.output == "Custom (will respect value below)":
|
|
||||||
self.quality_selected = "custom"
|
|
||||||
if self.custom_quality_selector.get_text()[len(self.custom_quality_selector.get_text()) - 1] == "x":
|
|
||||||
self.q = f"{self.custom_quality_selector.get_text()} {self.custom_quality_selector.get_text()}"
|
|
||||||
else:
|
|
||||||
self.q = f"{self.custom_quality_selector.get_text()}x {self.custom_quality_selector.get_text()}x"
|
|
||||||
else:
|
|
||||||
self.quality_selected = "default"
|
|
||||||
self.q = str(arg.get(self.output))
|
|
||||||
self.go = True
|
|
||||||
if self.go:
|
|
||||||
self.details.set_text("Starting upscaling process")
|
|
||||||
print("\n\nStarting upscaling process!\n\n")
|
|
||||||
self.info_button()
|
|
||||||
if self.info_response == Gtk.ResponseType.OK:
|
|
||||||
self.details.set_text("Upscaling")
|
|
||||||
self.scaler = multiprocessing.Process(name="scaler",
|
|
||||||
target=handler.handler,
|
|
||||||
args=("./bin/lib/FidelityFX_CLI.exe",
|
|
||||||
self.open_file,
|
|
||||||
self.quality_selected,
|
|
||||||
self.q,
|
|
||||||
self.save_file,)
|
|
||||||
)
|
|
||||||
self.scaler.start()
|
|
||||||
elif self.info_response == Gtk.ResponseType.CANCEL:
|
|
||||||
self.details.set_text("Ready")
|
|
||||||
print("aborted")
|
|
||||||
else:
|
|
||||||
raise Exception
|
|
||||||
else:
|
|
||||||
self.details.set_text("File-checks failed! Please check your entries!")
|
|
||||||
print("File-checks unsuccessful. Please check your entries!")
|
|
||||||
self.checkerror()
|
|
||||||
else:
|
|
||||||
self.details.set_text("No file specified!")
|
|
||||||
print("no file specified")
|
|
||||||
self.fileerror()
|
|
||||||
else:
|
|
||||||
self.runningerror()
|
|
||||||
print("Already running!")
|
|
||||||
|
|
||||||
def runningerror(self):
|
|
||||||
self.runningerrordialog = ErrorDialogRunning(self)
|
|
||||||
self.runningerrordialog.run()
|
|
||||||
self.runningerrordialog.destroy()
|
|
||||||
|
|
||||||
def fileerror(self):
|
|
||||||
self.fileerrordialog = ErrorDialogFileMissing(self)
|
|
||||||
self.fileerrordialog.run()
|
|
||||||
self.fileerrordialog.destroy()
|
|
||||||
|
|
||||||
def checkerror(self):
|
|
||||||
self.checkerrordialog = ErrorDialogCheckFail(self)
|
|
||||||
self.checkerrordialog.run()
|
|
||||||
self.checkerrordialog.destroy()
|
|
||||||
|
|
||||||
|
|
||||||
win = HomeWindow()
|
|
||||||
win.set_default_size(800, 600)
|
|
||||||
win.connect("destroy", Gtk.main_quit)
|
|
||||||
win.show_all()
|
|
||||||
Gtk.main()
|
|
||||||
BIN
logo.png
Executable file
BIN
logo.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 592 KiB |
28
package.json
Normal file
28
package.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "SimpleMediaUpscalerLite",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "A frontend to upscale your videos and images using different upscale engines",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/simplePCBuilding/SimpleMediaUpscalerLite.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"upscaler",
|
||||||
|
"electron",
|
||||||
|
"python",
|
||||||
|
"frontend",
|
||||||
|
"videos",
|
||||||
|
"images"
|
||||||
|
],
|
||||||
|
"author": "Janis Hutz",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/simplePCBuilding/SimpleMediaUpscalerLite/issues",
|
||||||
|
"email": "development@janishutz.com"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/simplePCBuilding/SimpleMediaUpscalerLite#readme"
|
||||||
|
}
|
||||||
54
packaging/package.sh
Executable file
54
packaging/package.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Compile for Linux
|
||||||
|
python -m PyInstaller smuL-cli.spec
|
||||||
|
|
||||||
|
mkdir ./frontend/lib/
|
||||||
|
cp -rv ./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 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
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
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
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'
|
||||||
0
packaging/preparePackaging.sh
Normal file
0
packaging/preparePackaging.sh
Normal file
7
packaging/prepareWindowsPackaging.sh
Executable file
7
packaging/prepareWindowsPackaging.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
curl -o ./pythonInstaller.exe https://www.python.org/ftp/python/3.11.3/python-3.11.3-amd64.exe
|
||||||
|
|
||||||
|
wine pythonInstaller.exe
|
||||||
|
|
||||||
|
wine python -m pip install pyinstaller
|
||||||
|
|
||||||
|
printf '\n\n==> Done installing python for windows\n\n'
|
||||||
15
packaging/startTesting.sh
Executable file
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
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
3
plugins/plugins.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"fsr": { "displayName":"AMD FidelityFX Super Resolution" }
|
||||||
|
}
|
||||||
163
smuL-cli.py
Normal file
163
smuL-cli.py
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
"""
|
||||||
|
* SimpleMediaUpscalerLite - fsrSimpleMediaUpscalerLite-cli.py
|
||||||
|
*
|
||||||
|
* Created by Janis Hutz 03/15/2023, Licensed under the GPL V3 License
|
||||||
|
* https://janishutz.com, development@janishutz.com
|
||||||
|
*
|
||||||
|
*
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import bin.handler
|
||||||
|
import os
|
||||||
|
import multiprocessing
|
||||||
|
import json
|
||||||
|
|
||||||
|
engineList = os.listdir( 'bin/engines' );
|
||||||
|
counter = 0;
|
||||||
|
for element in engineList:
|
||||||
|
if ( element == '__pycache__' ):
|
||||||
|
engineList.pop( counter );
|
||||||
|
counter += 1;
|
||||||
|
|
||||||
|
engineInfo = {}
|
||||||
|
|
||||||
|
for engine in engineList:
|
||||||
|
engineInfo[ engine ] = json.load( open( 'bin/engines/' + engine + '/config.json' ) )
|
||||||
|
|
||||||
|
allowedFiletypes = [ 'png', 'jpg' ];
|
||||||
|
|
||||||
|
def performChecks ( args, ap ):
|
||||||
|
if ( args.details == None or args.details == '' ):
|
||||||
|
if ( not args.printengines ):
|
||||||
|
if ( not args.version ):
|
||||||
|
# Check if input and output file arguments are available
|
||||||
|
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( 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( output );
|
||||||
|
else:
|
||||||
|
print( '\n==> Refusing to Upscale video. Please delete the file or specify another filepath! <==' )
|
||||||
|
return False
|
||||||
|
|
||||||
|
# check if engine argument is valid
|
||||||
|
try:
|
||||||
|
engineInfo[ args.engine.lower() ]
|
||||||
|
except KeyError:
|
||||||
|
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
|
||||||
|
if ( args.scalefactor != None and args.scalefactor != 0 ):
|
||||||
|
if ( int( args.scalefactor ) > 4 and int( args.scalefactor ) < -4 ):
|
||||||
|
print( '\n==> ERROR: Invalid scale factor. Value has to be an integer between -4 and 4 (option -s)' )
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if ( not 'upscaling' in engineInfo[ args.engine ][ 'supports' ] ):
|
||||||
|
print( '\n==> ERROR: This engine does NOT support upscaling' )
|
||||||
|
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.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' ] ):
|
||||||
|
print( '\n==> ERROR: This engine does NOT support sharpening' )
|
||||||
|
return False
|
||||||
|
|
||||||
|
# check if scalefactor and / or sharpening is available
|
||||||
|
if ( ( args.scalefactor == 0 or args.scalefactor == None ) and ( args.sharpening == 0 or args.sharpening == None ) ):
|
||||||
|
print( '\n==> ERROR: Either scalefactor or sharpening argument required!' )
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check if filetype argument is valid
|
||||||
|
if ( not args.filetype in allowedFiletypes ):
|
||||||
|
print( '\n==> ERROR: Unknown filetype for temp files. Can be png or jpg' )
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check if mode of engine is valid
|
||||||
|
if ( args.mode != None ):
|
||||||
|
try:
|
||||||
|
engineInfo[ args.engine.lower() ][ 'cliModeOptions' ][ args.mode.lower() ]
|
||||||
|
except KeyError:
|
||||||
|
print( '\n==> ERROR: The specified mode is not supported by this engine. Options:' )
|
||||||
|
for option in engineInfo[ args.engine ][ 'cliModeOptions' ]:
|
||||||
|
print( ' --> ' + engineInfo[ args.engine ][ 'cliModeOptions' ][ option ][ 'displayName' ] + ' (' + option + ')' )
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print( '\n\n==> You are running Version 1.1.0 of ImageVideoScaler-CLI <==\n' )
|
||||||
|
else:
|
||||||
|
print( '\n\n==> Available engines <==\n' )
|
||||||
|
for entry in engineList:
|
||||||
|
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: ' )
|
||||||
|
for mode in engineInfo[ args.details ][ 'cliModeOptions' ]:
|
||||||
|
print( ' -> ' + engineInfo[ args.details ][ 'cliModeOptions' ][ mode ][ 'displayName' ] + ':' )
|
||||||
|
print( ' > CLI name: ' + mode )
|
||||||
|
print( ' > Is the default: ' + str( engineInfo[ args.details ][ 'cliModeOptions' ][ mode ][ 'default' ] ) )
|
||||||
|
print( '\n\n' )
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
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' )
|
||||||
|
ap.add_argument( '-S', '--sharpening', help='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)' )
|
||||||
|
ap.add_argument( '-T', '--threads', help='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' )
|
||||||
|
ap.add_argument( '-E', '--engine', help='Upscaling engine. By default can be fsr or ss. Use the -p option to see all installed engines' )
|
||||||
|
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( scalefactor = 0, sharpening = 0, threads = 4, engine = 'ffc', filetype = 'png' )
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
handler = bin.handler.Handler()
|
||||||
|
|
||||||
|
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
|
||||||
|
else:
|
||||||
|
for option in engineInfo[ args.engine ][ 'cliModeOptions' ]:
|
||||||
|
if ( engineInfo[ args.engine ][ 'cliModeOptions' ][ option ][ 'default' ] ):
|
||||||
|
mode = option
|
||||||
|
break
|
||||||
|
|
||||||
|
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' );
|
||||||
50
smuL-cli.spec
Executable file
50
smuL-cli.spec
Executable file
@@ -0,0 +1,50 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['smuL-cli.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False,
|
||||||
|
)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
[],
|
||||||
|
exclude_binaries=True,
|
||||||
|
name='smuL-cli',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
console=True,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
)
|
||||||
|
coll = COLLECT(
|
||||||
|
exe,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
name='smuL-cli',
|
||||||
|
)
|
||||||
1
website/cropSymbol.svg
Normal file
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
BIN
website/logo.xcf
Normal file
Binary file not shown.
11
website/plugins.md
Normal file
11
website/plugins.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# 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.
|
||||||
|
- It has to support a folder or an individual file as an input and the function, has to take the following arguments:
|
||||||
|
|
||||||
|
Argument | Variable type
|
||||||
|
---------|---------------
|
||||||
|
x | y
|
||||||
|
|
||||||
|
- The function has to return the path to the folder where the final resulting images are located.
|
||||||
Reference in New Issue
Block a user