Add files via upload

This commit is contained in:
Iván Eduardo Chavez Ayub
2025-07-17 22:51:50 -06:00
committed by GitHub
parent fa56a60072
commit f31c1d5a23
8 changed files with 822 additions and 244 deletions
+63
View File
@@ -1,3 +1,66 @@
## Version 3.0
**Release date:** 16 July 2025
### 1. Major Features & Core Capabilities
#### 1.1 **AI-Powered Face Restoration (GFPGAN)**
- **New `AI_face_restoration` Class**: A new, specialized class has been implemented to handle face restoration models. This class is architected to manage the unique preprocessing and post-processing requirements of models like GFPGAN, distinct from standard upscaling models.
- **GFPGAN Model Integration**: The GFPGAN v1.4 model has been added to the AI model repository and is now selectable from the UI. It is listed under a new `Face_restoration_models_list` category. The main orchestrator (`upscale_orchestrator`) now detects when a face restoration model is selected and routes the task to the appropriate `AI_face_restoration` instance.
- **Specialized Processing Pipeline**: The new class introduces a dedicated pipeline for face enhancement. This includes resizing the input image to the model's required dimensions (e.g., 512x512 for GFPGAN), handling color channel conversions, and post-processing the output to restore the image to its original dimensions.
### 2. UI/UX Modernisation
#### 2.1 **Complete Thematic Redesign**
- The application has undergone a significant visual overhaul with a new, professionally designed color scheme to improve aesthetics and user comfort during long sessions. The new theme provides better contrast and a more modern look.
| Element | New Value (v3.0) | Old Value (v2.2) |
| :---------------- | :--------------------- | :------------------------ |
| Background | `#1A1A1A` (Deep Black) | `#000000` (Pure Black) |
| App Name Color | `#FF4444` (Bright Red) | `#FF0000` (Pure Red) |
| Widget Background | `#2D2D2D` (Dark Grey) | `#5A5A5A` (Grey) |
| Accent/Border | `#FFD700` (Gold) | Gold & Red |
| Button Hover | `#FF6666` (Light Red) | `background_color` |
| Info Button | `#B22222` (Dark Red) | `widget_background_color` |
#### 2.2 **Enhanced Splash Screen**
- **Dynamic Progress Bar**: The splash screen now features a `CTkProgressBar` to provide visual feedback on the application's loading status, enhancing the startup experience.
- **Smooth Fade-Out Animation**: A new `fade_out` method using a cosine function has been implemented for a smooth, animated exit transition instead of an abrupt disappearance.
- **Improved Information Display**: The splash screen now prominently displays the application version number.
#### 2.3 **Redesigned and Resizable Message Boxes**
- The `MessageBox` class was significantly improved to handle large blocks of text, such as detailed error messages. It now implements a `CTkScrollableFrame`, ensuring that content is always accessible without forcing the dialog to an unmanageable size.
- The dialogs now have defined `minsize` and `maxsize` properties for better window management.
#### 2.4 **Improved UI Readability**
- The main AI model dropdown menu is now logically grouped by model type (Upscaling, Denoising, Face Restoration, Interpolation), with a `MENU_LIST_SEPARATOR` between categories. This makes it easier for users to find and select the appropriate AI model for their task.
### 3. Performance and Code Optimisation
#### 3.1 **Memory Optimisation with Contiguous Arrays**
- Widespread use of `numpy.ascontiguousarray` has been implemented across the codebase. This is applied during critical image handling steps in `AI_upscale.preprocess_image`, `AI_interpolation.concatenate_images`, and the new `AI_face_restoration.preprocess_face_image` class. This ensures data is aligned in memory, which can significantly speed up operations in backend libraries like OpenCV and ONNX Runtime.
#### 3.2 **Refined Data Type Handling**
- The `AI_upscale` class now explicitly ensures input images are converted to `float32` before normalization, improving precision and preventing potential data type mismatches during inference.
- The `AI_face_restoration` class is configured to intelligently select between `float16` and `float32` based on the specific model's requirements (`fp16: True` in config), further optimizing performance and VRAM usage for compatible models.
### 4. Codebase Health and Maintainability
#### 4.1 **Specialised Class for Face Restoration**
- The logic for face restoration has been fully encapsulated within the new `AI_face_restoration` class, separating it from the general-purpose `AI_upscale` class. This object-oriented approach makes the code more modular, readable, and easier to extend with different face enhancement models in the future.
#### 4.2 **Robust BGRA to BGR Conversion**
- The application now explicitly handles images with an alpha channel (4-channel BGRA) when using face restoration models. A new import for `COLOR_BGRA2BGR` was added, and it is used within `preprocess_face_image` to convert images to the 3-channel BGR format expected by the GFPGAN model. This prevents runtime errors and ensures correct processing of PNGs or other images with transparency.
## Version2.2
**Release date:** 7July2025
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Iván Eduardo Chavez Ayub
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+121
View File
@@ -0,0 +1,121 @@
SOFTWARE LICENSE AGREEMENT AND TERMS OF USE FOR WARLOCK-STUDIO 3.0
---
PREAMBLE
This Software License Agreement ("Agreement") constitutes a legally binding
contract between you, either as an individual or on behalf of an entity
("USER"), and Iván Eduardo Chavez Ayub ("AUTHOR"), regarding the
Warlock-Studio 3.0 software and all its associated files, documentation,
and materials (collectively, the "SOFTWARE").
By installing, copying, downloading, accessing, or otherwise using the
SOFTWARE, the USER expressly consents to and agrees to be bound by all
terms and conditions stipulated in this Agreement.
IF THE USER DOES NOT AGREE WITH ALL THE TERMS OF THIS AGREEMENT, THEY MUST
NOT INSTALL, USE, OR COPY THE SOFTWARE AND MUST IMMEDIATELY CANCEL THE
INSTALLATION PROCESS.
---
SECTION I: THE MIT LICENSE
The original and legally binding text of the MIT License is presented below.
This text governs the use of the core SOFTWARE.
MIT License
Copyright (c) 2025 Iván Eduardo Chavez Ayub
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---
SECTION II: ADDITIONAL TERMS, NOTICES, AND ACKNOWLEDGEMENTS
1. Project Description
Warlock-Studio is a software application developed by Iván Eduardo Chavez
Ayub (GitHub profile: @Ivan-Ayub97).
The project is based on open-source
tools such as QualityScaler, FluidFrames, and RealScaler, originally
developed by Djdefrag (GitHub profile: @Djdefrag).
The main objective of
Warlock-Studio is to provide an intuitive graphical interface for
enhancing and upscaling image resolution through the use of artificial
intelligence models.
2. Third-Party Components and Applicable Licenses
The SOFTWARE integrates various third-party technologies and components.
The use of the SOFTWARE is conditioned not only on compliance with this
Agreement but also with the license terms of each of these components.
The following is a list of components and their respective licenses:
- QualityScaler, RealScaler, FluidFrames: MIT License (Djdefrag)
- RIFE: Apache 2.0 License (hzwer, Megvii Research)
- Real-ESRGAN, RealESRGAN-G, RealESR-Anime, RealESR-Net: BSD 3-Clause /
Apache 2.0 License (Xintao Wang)
- GFPGAN: MIT License (TencentARC, Xintao Wang)
- SRGAN: CC BY-NC-SA 4.0 License (TensorLayer Community)
- BSRGAN: Apache 2.0 License (Kai Zhang)
- IRCNN: BSD / Mixed License (Kai Zhang)
- Anime4K: MIT License (Tianyang Zhang / bloc97)
- ONNX Runtime: MIT License (Microsoft)
- PyTorch: BSD 3-Clause License (Meta AI)
- FFmpeg: LGPL-2.1 / GPL License (FFmpeg Team)
- ExifTool: Perl Artistic License (Phil Harvey)
- DirectML: MIT License (Microsoft)
- Python: PSF License (Python Software Foundation)
- PyInstaller: GPLv2+ License (PyInstaller Team)
- Inno Setup: Custom Inno License (Jordan Russell)
2. Limitation of Liability Clause (Extended)
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE
AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES; INCLUDING, BUT NOT LIMITED
TO, LOSS OF DATA, BUSINESS INTERRUPTION, OR HARDWARE OR SYSTEM FAILURE
ARISING FROM THE USE, MISUSE, OR INABILITY TO USE THE SOFTWARE.
THIS SOFTWARE IS PROVIDED FOR EDUCATIONAL, CREATIVE, AND RESEARCH PURPOSES.
IT IS NOT CERTIFIED FOR IMPLEMENTATION IN CRITICAL OR COMMERCIAL
INFRASTRUCTURES WITHOUT PRIOR INDEPENDENT VALIDATION.
THE USER ASSUMES
ALL RISK ASSOCIATED WITH ITS USE.
4. Intellectual Property Notice
The brand, the name "Warlock-Studio" and its associated logos are the
exclusive intellectual property of Iván Eduardo Chavez Ayub.
The use of
these elements for commercial purposes is strictly prohibited without the
prior written consent of the AUTHOR.
Any redistribution or modification of
the source code must preserve the original copyright notices and all
references to the licenses contained herein.
5. Acceptance of Terms
By proceeding with the installation and by using the SOFTWARE, the USER
acknowledges having read, understood, and accepted all the terms set forth
in the MIT License (Section I) and the Additional Terms (Section II) of
this Agreement.
---
CONTACT INFORMATION
For any inquiries or communications related to this Agreement or the SOFTWARE,
you may contact the Author:
Name: Iván Eduardo Chavez Ayub
Email: negroayub97@gmail.com
GitHub: [https://github.com/Ivan-Ayub97](https://github.com/Ivan-Ayub97)
+124 -130
View File
@@ -1,70 +1,55 @@
![Warlock-Studio banner](Assets/banner.png)
![Build Status](https://img.shields.io/badge/build-Stable_Release-blue?style=for-the-badge)
![Version](https://img.shields.io/badge/%20Version-2.2-darkred?style=for-the-badge)
# Download
### Get Warlock-Studio Installer
<p align="center">
<img src="https://img.shields.io/badge/build-Stable_Release-blue?style=for-the-badge" alt="Build Status">
<img src="https://img.shields.io/badge/%20Version-3.0--07.25-darkred?style=for-the-badge" alt="Version 3.0-07.25">
</p>
You can download the installer (latest version **2.2**) from any of this platforms:
AI Media Enhancement Suite
**Warlock-Studio** is a powerful, open-source desktop application for Windows that integrates state-of-the-art AI models for video and image enhancement. Inspired by the work of [Djdefrag](https://github.com/Djdefrag) on tools like **QualityScaler** and **FluidFrames**, this suite provides a unified, high-performance interface for upscaling, restoration, and frame interpolation.
Version 3.0 marks a major evolution, introducing **AI-powered face restoration**, a completely modernized user interface, and significant performance optimizations to deliver professional-grade results to everyone.
---
### ► Download Installer (v3.0)
Get the latest stable release from any of the following platforms:
<table>
<tr>
<td align="center">
<a href="https://github.com/Ivan-Ayub97/Warlock-Studio/releases/download/v2.2/Warlock-Studio2.2Setup.zip" target="_blank">
<td align="center" width="33%">
<a href="https://github.com/Ivan-Ayub97/Warlock-Studio/releases/latest" target="_blank">
<img src="rsc/GitHub_Lockup_Light.png" alt="Download from GitHub" width="200" />
</a>
<td align="center">
</td>
<td align="center" width="33%">
<a href="https://sourceforge.net/p/warlock-studio/"><img alt="Download Warlock-Studio" src="https://sourceforge.net/sflogo.php?type=18&amp;group_id=3880091" width=200></a>
</a>
</td>
<td align="center">
<a href="https://drive.google.com/file/d/1nqlBuxZKsk3FX_nWUqUnDUKUTfMSfjB4/view?usp=sharing">
<td align="center" width="33%">
<a href="https://drive.google.com/file/d/1m_YKY612EaMiYyxJDRj1WsCmcJnCSKC7/view?usp=sharing">
<img src="rsc/google_drive-logo.png" alt="Download from Google Drive" />
</a>
</td>
</a>
</td>
</tr>
</table>
---
### AI-Powered Media Enhancement & Upscaling Suite 2.2
**Warlock-Studio** is a powerful **open-source desktop application** inspired by the remarkable work of [Djdefrag](https://github.com/Djdefrag), integrating tools like **QualityScaler**, **RealScaler**, and **FluidFrames**. Built with performance and usability in mind, Warlock-Studio brings together the best of these technologies into a unified and user-friendly interface.
---
It features integration with state-of-the-art models for upscaling, restoration, and frame interpolation—all within an intuitive and streamlined user interface. Warlock-Studio delivers **professional-grade media processing** capabilities to everyone.
Version 2.2 introduces critical improvements focused on reliability and performance:
- **Comprehensive Logging System** for easier debugging.
- **Proactive Environment Validation** to prevent common errors.
- **Resilient Video Encoding** with automatic codec and audio fallbacks.
- **Aggressive Memory Management** and dynamic GPU VRAM recovery to handle long processing tasks without crashing.
---
## Interface Previews
### 🔹 Main
![Screenshot of Warlock-Studio](rsc/Capture.png)
### 🔹 RIFE (Frame Interpolation) Options
![Screenshot of Warlock-Studio](rsc/CaptureRIFE.png)
---
## Key Features
- **State-of-the-Art AI Models**
Real-ESRGAN, SRGAN, BSRGAN, IRCNN, Waifu2x, Anime4K, **RIFE**, and others for denoising, resolution enhancement, detail restoration, and smooth frame interpolation.
A comprehensive suite including Real-ESRGAN, BSRGAN, IRCNN, **GFPGAN**, and **RIFE** for denoising, resolution enhancement, detail restoration, and smooth frame interpolation.
- **AI Face Restoration (New in v3.0)**
Restore and enhance faces in old, blurry, or low-quality photos and videos with the integrated GFPGAN model, bringing cherished memories back to life.
- **AI Frame Interpolation & Slow Motion**
Generate new in-between frames using RIFE to create smooth **2x/4x/8x** motion or dramatic slow-motion effects.
Generate new in-between frames using RIFE to create ultra-smooth **2x, 4x, or 8x** motion or dramatic slow-motion effects.
- **Modern & Intuitive Interface**
Completely redesigned in v3.0 for a clean, efficient, and user-friendly experience for both beginners and professionals.
- **Batch Processing**
Simultaneously process multiple images or videos—ideal for large-scale media projects.
@@ -72,39 +57,30 @@ Version 2.2 introduces critical improvements focused on reliability and performa
- **Customizable Workflows**
Choose your preferred AI model, output resolution, format (PNG, JPEG, MP4, etc.), and quality settings for full creative control.
- **Intuitive Interface**
Designed for both beginners and professionals—simple, clean, and efficient.
- **Open-Source & Extensible**
Licensed under the MIT License. Additional usage terms can be found in the [NOTICE](https://www.google.com/search?q=NOTICE.md) file.
Licensed under the MIT License. Contributions are welcome! Additional usage terms can be found in the `NOTICE.md` file.
---
## Recent Enhancements (v2.2)
## What's New in Version 3.0
-**Stability Overhaul:** Major improvements in error handling, including a comprehensive logging system and proactive environment validation to prevent crashes.
-**Resilient Video Processing:** The video encoding pipeline now features automatic fallbacks for hardware codecs and audio stream processing, ensuring a valid output file is always created.
-**Performance and Memory Optimization:** Implemented aggressive memory management to handle large video files without crashing and added dynamic GPU VRAM recovery for tiling-based tasks.
-**Critical Bug Fixes:** Resolved race conditions in video encoding and GUI status updates, ensuring process integrity and predictable behavior.
-**Safe Thread Management:** Upgraded to ensure processes are terminated gracefully and system resources are properly cleaned up on exit.
-**AI Face Restoration:** Added support for the GFPGAN model, enabling powerful face enhancement and repair.
-**Modernized UI/UX:** Implemented a complete visual redesign with a new, professional color scheme and improved components like a dynamic splash screen and scrollable message boxes.
-**Performance Optimisation:** Enhanced memory efficiency by using contiguous arrays and refining data type handling during AI processing, leading to faster and more stable performance.
-**Improved Codebase Health:** Refactored the core logic to be more modular by encapsulating face restoration in its own class (`AI_face_restoration`), improving maintainability.
-**Increased Robustness:** Added explicit handling for images with transparency (BGRA) to ensure compatibility with models that require 3-channel input (BGR).
---
---
## Installation
## Interface Previews
To get started with Warlock-Studio:
### 🔹 Main View (v3.0)
1. **Run the installer** and follow the setup instructions.
2. **Launch the application** by opening `Warlock-Studio.exe`.
3. **Begin enhancing** your images and videos with just a few clicks\!
![Screenshot of Warlock-Studio's main interface](rsc/Capture.png)
Warlock-Studio uses [PyInstaller](https://www.pyinstaller.org/) and [Inno Setup](http://www.jrsoftware.org/isinfo.php) for a seamless packaging and installation experience.
### 🔹 RIFE Option
### 🔹 Installation Window
## ![Screenshot of Warlock-Studio](rsc/Installation_window.png)
## ![Screenshot of Warlock-Studio](rsc/Installation_window2.png)
![Screenshot of Warlock-Studio showing RIFE options](rsc/CaptureRIFE.png)
---
@@ -112,56 +88,87 @@ Warlock-Studio uses [PyInstaller](https://www.pyinstaller.org/) and [Inno Setup]
1. **Run as Administrator** (optional but recommended for optimal performance).
2. **Load your media**: select your images and videos into the app.
2. **Load Your Media**: Select your images and videos to import them into the app.
3. **Configure settings**:
3. **Configure Settings**:
- Select an **AI Model** (e.g., Real-ESRGAN, SRGAN, BSRGAN, IRCNN, Waifu2x, Anime4K, RIFE)
- Set the **output resolution**, **file format**, and toggle features such as **interpolation** or **slow-motion**
- Select an **AI Model** (e.g., Real-ESRGAN, BSRGAN, GFPGAN, RIFE).
- Set the **input/output resolution**, **file format**, and toggle features like **interpolation** or **blending**.
4. **Start Processing**: click **"Make Magic"** to begin enhancement.
4. **Start Processing**: Click **"Make Magic"** to begin the enhancement.
5. **Retrieve your files**: processed outputs will be saved in your chosen destination folder.
5. **Retrieve Your Files**: Processed outputs will be saved in your chosen destination folder.
---
## Quality Comparison
## AI Model Workflows & Quality Comparison
### Quality Comparison
**Comparison of an enhanced image using the BSRGANx2 model**
![Quality Comparison](rsc/image_comparison.png)
---
### AI Model Workflows
## AI-Models Workflow
#### 🔹 GFPGAN (Face Restoration)
### 🔹 RIFE
![Screenshot of Warlock-Studio showing GFPGAN workflow](rsc/WorkflowGFPGAN.png)
![Screenshot of Warlock-Studio](rsc/WorkflowRIFE.png)
#### 🔹 RIFE (Frame Interpolation)
### 🔹 Real-ESRGAN
![Screenshot of Warlock-Studio showing RIFE workflow](rsc/WorkflowRIFE.png)
![Screenshot of Warlock-Studio](rsc/WorkflowRealESRGAN.png)
#### 🔹 Real-ESRGAN (Upscaling)
### 🔹 IRCNN
![Screenshot of Warlock-Studio showing Real-ESRGAN workflow](rsc/WorkflowRealESRGAN.png)
![Screenshot of Warlock-Studio](rsc/WorkflowIRCNN.png)
#### 🔹 IRCNN (Denoising)
### 🔹 BSRGAN
![Screenshot of Warlock-Studio showing IRCNN workflow](rsc/WorkflowIRCNN.png)
![Screenshot of Warlock-Studio](rsc/WorkflowBSRGAN.png)
#### 🔹 BSRGAN (Upscaling)
![Screenshot of Warlock-Studio showing BSRGAN workflow](rsc/WorkflowBSRGAN.png)
---
## 🛠️ Development Status — v2.2
## Installation
| Component | Status | Notes |
| :---------------------------------- | :--------------- | :------------------------------------------------------------------------ |
| **Upscaling Models (ESRGAN, etc.)** | 🟢 **Stable** | Fully integrated with dynamic VRAM recovery for enhanced stability. |
| **Frame Interpolation (RIFE)** | 🟢 **Stable** | Includes slow-motion and intermediate frame generation capabilities. |
| **Batch Processing** | 🟢 **Stable** | Reliable processing with improved error handling and resource management. |
| **User Interface (UI/UX)** | 🟢 **Improved** | Updated color palette and faster start-up time. |
| **GPU Management** | 🟢 **Optimized** | Dynamic VRAM error recovery and graceful hardware codec fallbacks. |
| **Installer and Packaging** | 🟢 **Stable** | Easy-to-use installer for Windows platforms. |
To get started with Warlock-Studio:
1. **Download the installer** from the links at the top of this document.
2. **Run the installer** and follow the setup instructions.
3. **Launch the application** from the Start Menu or desktop shortcut.
Warlock-Studio uses [PyInstaller](https://www.pyinstaller.org/) and [Inno Setup](http://www.jrsoftware.org/isinfo.php) for a seamless packaging and installation experience.
### Installation Window Previews
![Screenshot of the installer window](rsc/Installation_window.png)
![Screenshot of the installer window part 2](rsc/Installation_window2.png)
---
## System Requirements
- **Operating System:** Windows 10 or later (64-bit)
- **Memory (RAM):** 8 GB or more recommended
- **Graphics Card:** NVIDIA or DirectML-compatible GPU highly recommended for performance
- **Storage:** Sufficient disk space for input and output media files
---
## Development Status — v3.0-07.25
| Component | Status | Notes |
| :---------------------------------- | :---------------- | :--------------------------------------------------------------------------------- |
| **Upscaling Models (ESRGAN, etc.)** | 🟢 **Stable** | Fully integrated with dynamic VRAM recovery for enhanced stability. |
| **Face Restoration (GFPGAN)** | 🟢 **Stable** | New feature for high-quality face enhancement. |
| **Frame Interpolation (RIFE)** | 🟢 **Stable** | Includes slow-motion and intermediate frame generation capabilities. |
| **Batch Processing** | 🟢 **Stable** | Reliable processing with improved error handling and resource management. |
| **User Interface (UI/UX)** | 🟢 **Modernized** | Complete thematic redesign with a professional color palette and improved dialogs. |
| **GPU Management** | 🟢 **Optimized** | Dynamic VRAM error recovery and graceful hardware codec fallbacks. |
| **Installer and Packaging** | 🟢 **Stable** | Easy-to-use installer for Windows platforms. |
---
@@ -173,6 +180,7 @@ Warlock-Studio/
└──├──BSRGANx2_fp16.onnx
├──BSRGANx4_fp16.onnx
├──GFPGANv1.4.fp16.onnx
├──IRCNN_Lx1_fp16.onnx
├──IRCNN_Mx1_fp16.onnx
├──RealESR_Animex4_fp16.onnx
@@ -188,8 +196,6 @@ Warlock-Studio/
├──clear_icon.png
├──exiftool.exe
├──ffmpeg.exe
├──ffmplay.exe
├──ffmprobe.exe
├──info_icon.png
├──logo.ico
├──logo.png
@@ -228,48 +234,38 @@ Warlock-Studio/
├──Manual_EN.pdf
├──Warlock-Studio.py # Main
└──Warlock-Studio.spec
```
---
### Integrated Technologies & Licenses
| Technology | License | Author / Maintainer | Source Code / Homepage |
| :------------ | :------------------------------- | :------------------------------------------------------ | :--------------------------------------------------------- |
| QualityScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler) |
| RealScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/RealScaler) |
| FluidFrames | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames) |
| Real-ESRGAN | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| RealESRGAN-G | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| RealESR-Anime | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| RealESR-Net | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| RIFE | Apache 2.0 | [hzwer](https://github.com/hzwer) | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) |
| SRGAN | CC BY-NC-SA 4.0 (Non-Commercial) | [TensorLayer Community](https://github.com/tensorlayer) | [GitHub](https://github.com/tensorlayer/srgan) |
| BSRGAN | Apache 2.0 | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/BSRGAN) |
| IRCNN | BSD / Mixed | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/IRCNN) |
| Anime4K | MIT | [Tianyang Zhang (bloc97)](https://github.com/bloc97) | [GitHub](https://github.com/bloc97/Anime4K) |
| ONNX Runtime | MIT | [Microsoft](https://github.com/microsoft) | [GitHub](https://github.com/microsoft/onnxruntime) |
| PyTorch | BSD 3-Clause | [Meta AI](https://pytorch.org/) | [GitHub](https://github.com/pytorch/pytorch) |
| FFmpeg | LGPL-2.1 / GPL (varies) | [FFmpeg Team](https://ffmpeg.org/) | [Official Site](https://ffmpeg.org) |
| ExifTool | Perl Artistic License 1.0 | [Phil Harvey](https://exiftool.org/) | [Official Site](https://exiftool.org/) |
| DirectML | MIT | [Microsoft](https://github.com/microsoft/) | [GitHub](https://github.com/microsoft/DirectML) |
| Python | Python Software Foundation (PSF) | [Python Software Foundation](https://www.python.org/) | [Official Site](https://www.python.org) |
| PyInstaller | GPLv2+ | [PyInstaller Team](https://github.com/pyinstaller) | [GitHub](https://github.com/pyinstaller/pyinstaller) |
| Inno Setup | Custom Inno License | [Jordan Russell](http://www.jrsoftware.org/) | [Official Site](http://www.jrsoftware.org/isinfo.php) |
---
## System Requirements
- **Operating System:** Windows 10 or later
- **Memory (RAM):** Minimum 4 GB (8 GB or more recommended)
- **Graphics Card:** NVIDIA or DirectML-compatible GPU highly recommended for performance
- **Storage:** Sufficient disk space for input and output media files
## Integrated Technologies & Licenses
| Technology | License | Author / Maintainer | Source Code / Homepage |
| :------------ | :------------------------ | :-------------------------------------------------------- | :--------------------------------------------------------- |
| QualityScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler) |
| RealScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/RealScaler) |
| FluidFrames | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames) |
| Real-ESRGAN | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| GFPGAN | MIT | [TencentARC / Xintao Wang](https://github.com/TencentARC) | [GitHub](https://github.com/TencentARC/GFPGAN) |
| RIFE | Apache 2.0 | [hzwer](https://github.com/hzwer) | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) |
| SRGAN | CC BY-NC-SA 4.0 | [TensorLayer Community](https://github.com/tensorlayer) | [GitHub](https://github.com/tensorlayer/srgan) |
| BSRGAN | Apache 2.0 | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/BSRGAN) |
| IRCNN | BSD / Mixed | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/IRCNN) |
| Anime4K | MIT | [Tianyang Zhang (bloc97)](https://github.com/bloc97) | [GitHub](https://github.com/bloc97/Anime4K) |
| ONNX Runtime | MIT | [Microsoft](https://github.com/microsoft) | [GitHub](https://github.com/microsoft/onnxruntime) |
| PyTorch | BSD 3-Clause | [Meta AI](https://pytorch.org/) | [GitHub](https://github.com/pytorch/pytorch) |
| FFmpeg | LGPL / GPL (varies) | [FFmpeg Team](https://ffmpeg.org/) | [Official Site](https://ffmpeg.org) |
| ExifTool | Perl Artistic License | [Phil Harvey](https://exiftool.org/) | [Official Site](https://exiftool.org/) |
| DirectML | MIT | [Microsoft](https://github.com/microsoft/) | [GitHub](https://github.com/microsoft/DirectML) |
| Python | PSF License | [Python Software Foundation](https://www.python.org/) | [Official Site](https://www.python.org) |
| PyInstaller | GPLv2+ | [PyInstaller Team](https://github.com/pyinstaller) | [GitHub](https://github.com/pyinstaller/pyinstaller) |
| Inno Setup | Custom License | [Jordan Russell](http://www.jrsoftware.org/) | [Official Site](http://www.jrsoftware.org/isinfo.php) |
---
## Contributions
We warmly welcome community contributions\!
We warmly welcome community contributions!
1. **Fork** this repository.
2. **Create a branch** for your feature or fix.
@@ -277,11 +273,9 @@ We warmly welcome community contributions\!
For bug reports, feature suggestions, or inquiries, contact us at: **[negroayub97@gmail.com](mailto:negroayub97@gmail.com)**
**Warlock-Studio** merges cutting-edge artificial intelligence with a powerful yet accessible interface—empowering creators to elevate their media effortlessly.
---
## License
© 2025 Iván Eduardo Chavez Ayub
Distributed under the MIT License. Additional terms are available in the [NOTICE.md](https://www.google.com/search?q=NOTICE.md) file.
Distributed under the MIT License. Additional terms are available in the `NOTICE.md` file.
+1
View File
@@ -6,6 +6,7 @@ We aim to support the most recent stable release of Warlock-Studio. Security upd
| Version | Supported |
| ------- | --------- |
| 3.0.x | ✅ |
| 2.2.x | ✅ |
| 2.1.x | ✅ |
| 2.0.x | ✅ |
+3 -5
View File
@@ -1,9 +1,9 @@
; ===================================================================
; Warlock-Studio 2.2 - Inno Setup Script
; Warlock-Studio 3.0- Inno Setup Script
; ===================================================================
#define AppName "Warlock-Studio"
#define AppVersion "2.2"
#define AppVersion "3.0"
#define AppPublisher "Iván Eduardo Chavez Ayub"
#define AppURL "https://github.com/Ivan-Ayub97/Warlock-Studio"
#define AppExeName "Warlock-Studio.exe"
@@ -56,7 +56,6 @@ Source: "..\Warlock-Studio\{#AppExeName}"; DestDir: "{app}"; Flags: ignoreversio
Source: "..\Warlock-Studio\logo.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\Warlock-Studio\AI-onnx\*"; DestDir: "{app}\AI-onnx"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\Warlock-Studio\Assets\*"; DestDir: "{app}\Assets"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\Warlock-Studio\rsc\*"; DestDir: "{app}\rsc"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\Warlock-Studio\LICENSE"; DestDir: "{app}"; DestName: "License.txt"; Flags: ignoreversion
Source: "..\Warlock-Studio\NOTICE.md"; DestDir: "{app}"; Flags: ignoreversion
@@ -72,5 +71,4 @@ Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(
[UninstallDelete]
; --- Limpieza Adicional Durante la Desinstalación ---
Type: filesandordirs; Name: "{app}\AI-onnx"
Type: filesandordirs; Name: "{app}\Assets"
Type: filesandordirs; Name: "{app}\rsc"
Type: filesandordirs; Name: "{app}\Assets"
+487 -107
View File
@@ -1,4 +1,3 @@
# Standard library imports
import atexit
import gc
@@ -16,7 +15,6 @@ from functools import cache
from itertools import repeat
from json import JSONDecodeError
from json import dumps as json_dumps
from shutil import copy2
from json import load as json_load
from math import cos, pi # For smooth fade effect
from multiprocessing import Process
@@ -41,6 +39,7 @@ from os.path import getsize as os_path_getsize
from os.path import join as os_path_join
from os.path import splitext as os_path_splitext
from pathlib import Path
from shutil import copy2
from shutil import move as shutil_move
from shutil import rmtree as remove_directory
from subprocess import CalledProcessError
@@ -54,13 +53,14 @@ from typing import Any, Callable, Dict, List, Optional, Union
from webbrowser import open as open_browser
from customtkinter import (CTk, CTkButton, CTkEntry, CTkFont, CTkFrame,
CTkImage, CTkLabel, CTkOptionMenu,
CTkImage, CTkLabel, CTkOptionMenu, CTkProgressBar,
CTkScrollableFrame, CTkToplevel, filedialog,
set_appearance_mode, set_default_color_theme)
# CAMBIO 1: Añadir COLOR_BGRA2BGR a la lista
from cv2 import (CAP_PROP_FPS, CAP_PROP_FRAME_COUNT, CAP_PROP_FRAME_HEIGHT,
CAP_PROP_FRAME_WIDTH, COLOR_BGR2RGB, COLOR_BGR2RGBA,
COLOR_GRAY2RGB, COLOR_RGB2GRAY, IMREAD_UNCHANGED, INTER_AREA,
INTER_CUBIC)
COLOR_BGRA2BGR, COLOR_GRAY2RGB, COLOR_RGB2GRAY,
IMREAD_UNCHANGED, INTER_AREA, INTER_CUBIC)
from cv2 import VideoCapture as opencv_VideoCapture
from cv2 import addWeighted as opencv_addWeighted
from cv2 import cvtColor as opencv_cvtColor
@@ -73,7 +73,7 @@ from numpy import ascontiguousarray as numpy_ascontiguousarray
from numpy import clip as numpy_clip
from numpy import concatenate as numpy_concatenate
from numpy import expand_dims as numpy_expand_dims
from numpy import float32
from numpy import float16, float32
from numpy import frombuffer as numpy_frombuffer
from numpy import full as numpy_full
from numpy import max as numpy_max
@@ -108,12 +108,22 @@ def find_by_relative_path(relative_path: str) -> str:
app_name = "Warlock-Studio"
version = "2.2"
version = "3.0-07.25"
background_color = "#000000" # Negro grisáceo profundo
app_name_color = "#FF0000" # Blanco puro para el nombre de la app
widget_background_color = "#5A5A5A" # Rojo oscuro (Dark Red)
text_color = "#F4F4F4" # Blanco opaco para texto legible
# Esquema de colores mejorado - Rojo, Gris, Amarillo, Negro, Blanco
background_color = "#1A1A1A" # Negro profundo
app_name_color = "#FF4444" # Rojo brillante para el nombre de la app
widget_background_color = "#2D2D2D" # Gris oscuro para widgets
text_color = "#FFFFFF" # Blanco puro para texto principal
secondary_text_color = "#E0E0E0" # Gris claro para texto secundario
accent_color = "#FFD700" # Amarillo dorado para acentos
button_hover_color = "#FF6666" # Rojo claro para hover
border_color = "#404040" # Gris medio para bordes
info_button_color = "#B22222" # Rojo oscuro para botones de info
warning_color = "#FF8C00" # Naranja para advertencias
success_color = "#32CD32" # Verde para éxito
error_color = "#DC143C" # Rojo carmesí para errores
VRAM_model_usage = {
'RealESR_Gx4': 2.2,
@@ -124,16 +134,19 @@ VRAM_model_usage = {
'RealESRGANx4': 0.6,
'IRCNN_Mx1': 4,
'IRCNN_Lx1': 4,
'GFPGAN': 1.8,
}
MENU_LIST_SEPARATOR = ["----"]
SRVGGNetCompact_models_list = ["RealESR_Gx4", "RealESR_Animex4"]
BSRGAN_models_list = ["BSRGANx4", "BSRGANx2", "RealESRGANx4", "RealESRNetx4"]
IRCNN_models_list = ["IRCNN_Mx1", "IRCNN_Lx1"]
Face_restoration_models_list = ["GFPGAN"]
RIFE_models_list = ["RIFE", "RIFE_Lite"]
AI_models_list = (SRVGGNetCompact_models_list + MENU_LIST_SEPARATOR + BSRGAN_models_list +
MENU_LIST_SEPARATOR + IRCNN_models_list + MENU_LIST_SEPARATOR + RIFE_models_list)
MENU_LIST_SEPARATOR + IRCNN_models_list + MENU_LIST_SEPARATOR + Face_restoration_models_list +
MENU_LIST_SEPARATOR + RIFE_models_list)
frame_interpolation_models_list = RIFE_models_list
frame_generation_options_list = [
"x2", "x4", "x8", "Slowmotion x2", "Slowmotion x4", "Slowmotion x8"
@@ -483,6 +496,8 @@ class AI_upscale:
return normalized_image, range
def preprocess_image(self, image: numpy_ndarray) -> numpy_ndarray:
# Optimización: Usar ascontiguousarray para mejor rendimiento de memoria
image = numpy_ascontiguousarray(image)
image = numpy_transpose(image, (2, 0, 1))
image = numpy_expand_dims(image, axis=0)
@@ -517,7 +532,8 @@ class AI_upscale:
case _: return (onnx_output * 255).astype(uint8)
def AI_upscale(self, image: numpy_ndarray) -> numpy_ndarray:
image = image.astype(float32)
# Optimización: Usar memoria contigua antes de procesar
image = numpy_ascontiguousarray(image, dtype=float32)
image_mode = self.get_image_mode(image)
image, range = self.normalize_image(image)
@@ -715,8 +731,9 @@ class AI_interpolation:
# AI CLASS FUNCTIONS
def concatenate_images(self, image1: numpy_ndarray, image2: numpy_ndarray) -> numpy_ndarray:
image1 = image1 / 255
image2 = image2 / 255
# Optimización: Normalizar in-place para reducir uso de memoria
image1 = numpy_ascontiguousarray(image1, dtype=float32) / 255.0
image2 = numpy_ascontiguousarray(image2, dtype=float32) / 255.0
concateneted_image = numpy_concatenate((image1, image2), axis=2)
return concateneted_image
@@ -753,41 +770,281 @@ class AI_interpolation:
# EXTERNAL FUNCTION
def AI_orchestration(self, image1: numpy_ndarray, image2: numpy_ndarray) -> list[numpy_ndarray]:
generated_images = []
# Generate 1 image [image1 / image_A / image2]
if self.frame_gen_factor == 2:
image_A = self.AI_interpolation(image1, image2)
generated_images.append(image_A)
def AI_orchestration(self, image1: numpy_ndarray, image2: numpy_ndarray) -> list[numpy_ndarray]:
generated_images = []
# Generate 3 images [image1 / image_A / image_B / image_C / image2]
elif self.frame_gen_factor == 4:
image_B = self.AI_interpolation(image1, image2)
image_A = self.AI_interpolation(image1, image_B)
image_C = self.AI_interpolation(image_B, image2)
generated_images.append(image_A)
generated_images.append(image_B)
generated_images.append(image_C)
# Optimización: Usar memoria contigua para las imágenes de entrada
image1 = numpy_ascontiguousarray(image1)
image2 = numpy_ascontiguousarray(image2)
# Generate 7 images [image1 / image_A / image_B / image_C / image_D / image_E / image_F / image_G / image2]
elif self.frame_gen_factor == 8:
image_D = self.AI_interpolation(image1, image2)
image_B = self.AI_interpolation(image1, image_D)
image_A = self.AI_interpolation(image1, image_B)
image_C = self.AI_interpolation(image_B, image_D)
image_F = self.AI_interpolation(image_D, image2)
image_E = self.AI_interpolation(image_D, image_F)
image_G = self.AI_interpolation(image_F, image2)
generated_images.append(image_A)
generated_images.append(image_B)
generated_images.append(image_C)
generated_images.append(image_D)
generated_images.append(image_E)
generated_images.append(image_F)
generated_images.append(image_G)
# Generate 1 image [image1 / image_A / image2]
if self.frame_gen_factor == 2:
image_A = self.AI_interpolation(image1, image2)
generated_images.append(image_A)
return generated_images
# Generate 3 images [image1 / image_A / image_B / image_C / image2]
elif self.frame_gen_factor == 4:
image_B = self.AI_interpolation(image1, image2)
image_A = self.AI_interpolation(image1, image_B)
image_C = self.AI_interpolation(image_B, image2)
generated_images.append(image_A)
generated_images.append(image_B)
generated_images.append(image_C)
# Generate 7 images [image1 / image_A / image_B / image_C / image_D / image_E / image_F / image_G / image2]
elif self.frame_gen_factor == 8:
image_D = self.AI_interpolation(image1, image2)
image_B = self.AI_interpolation(image1, image_D)
image_A = self.AI_interpolation(image1, image_B)
image_C = self.AI_interpolation(image_B, image_D)
image_F = self.AI_interpolation(image_D, image2)
image_E = self.AI_interpolation(image_D, image_F)
image_G = self.AI_interpolation(image_F, image2)
generated_images.append(image_A)
generated_images.append(image_B)
generated_images.append(image_C)
generated_images.append(image_D)
generated_images.append(image_E)
generated_images.append(image_F)
generated_images.append(image_G)
return generated_images
# AI FACE RESTORATION for face enhancement -----------------
class AI_face_restoration:
"""
Face restoration AI class for model like GFPGAN
These model are specialized for face enhancement and restoration tasks.
"""
def __init__(
self,
AI_model_name: str,
directml_gpu: str,
input_resize_factor: float,
output_resize_factor: float,
max_resolution: int
):
# Passed variables
self.AI_model_name = AI_model_name
self.directml_gpu = directml_gpu
self.input_resize_factor = input_resize_factor
self.output_resize_factor = output_resize_factor
self.max_resolution = max_resolution
# Model-specific configurations
self.model_configs = {
"GFPGAN": {
"input_size": (512, 512),
"scale_factor": 1,
"description": "GFPGAN v1.4 for face restoration",
"fp16": True
}
}
# Determine model path based on model name
self.AI_model_path = self._get_model_path()
self.model_config = self.model_configs.get(
AI_model_name, self.model_configs["GFPGAN"])
self.inferenceSession = None
def _get_model_path(self) -> str:
"""
Get the appropriate model path based on the model name
"""
if self.AI_model_name == "GFPGAN":
return find_by_relative_path(f"AI-onnx{os_separator}GFPGANv1.4.fp16.onnx")
else:
# Default fallback to GFPGAN
return find_by_relative_path(f"AI-onnx{os_separator}GFPGANv1.4.fp16.onnx")
def _load_inferenceSession(self) -> None:
"""
Load the ONNX inference session for face restoration
"""
try:
# Check if model file exists
if not os_path_exists(self.AI_model_path):
raise FileNotFoundError(
f"Face restoration model file not found: {self.AI_model_path}")
providers = ['DmlExecutionProvider']
match self.directml_gpu:
case 'Auto': provider_options = [{"performance_preference": "high_performance"}]
case 'GPU 1': provider_options = [{"device_id": "0"}]
case 'GPU 2': provider_options = [{"device_id": "1"}]
case 'GPU 3': provider_options = [{"device_id": "2"}]
case 'GPU 4': provider_options = [{"device_id": "3"}]
inference_session = InferenceSession(
path_or_bytes=self.AI_model_path,
providers=providers,
provider_options=provider_options,
)
self.inferenceSession = inference_session
print(
f"[AI] Successfully loaded face restoration model: {os_path_basename(self.AI_model_path)}")
except Exception as e:
error_msg = f"Failed to load face restoration model {os_path_basename(self.AI_model_path)}: {str(e)}"
print(f"[AI ERROR] {error_msg}")
raise RuntimeError(error_msg)
def get_image_mode(self, image: numpy_ndarray) -> str:
if image is None:
raise ValueError("Image is None")
shape = image.shape
if len(shape) == 2: # Grayscale: 2D array (rows, cols)
return "Grayscale"
# RGB: 3D array with 3 channels
elif len(shape) == 3 and shape[2] == 3:
return "RGB"
# RGBA: 3D array with 4 channels
elif len(shape) == 3 and shape[2] == 4:
return "RGBA"
else:
raise ValueError(f"Unsupported image shape: {shape}")
def get_image_resolution(self, image: numpy_ndarray) -> tuple:
height = image.shape[0]
width = image.shape[1]
return height, width
def resize_with_input_factor(self, image: numpy_ndarray) -> numpy_ndarray:
old_height, old_width = self.get_image_resolution(image)
new_width = int(old_width * self.input_resize_factor)
new_height = int(old_height * self.input_resize_factor)
new_width = new_width if new_width % 2 == 0 else new_width + 1
new_height = new_height if new_height % 2 == 0 else new_height + 1
if self.input_resize_factor > 1:
return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC)
elif self.input_resize_factor < 1:
return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA)
else:
return image
def resize_with_output_factor(self, image: numpy_ndarray) -> numpy_ndarray:
old_height, old_width = self.get_image_resolution(image)
new_width = int(old_width * self.output_resize_factor)
new_height = int(old_height * self.output_resize_factor)
new_width = new_width if new_width % 2 == 0 else new_width + 1
new_height = new_height if new_height % 2 == 0 else new_height + 1
if self.output_resize_factor > 1:
return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC)
elif self.output_resize_factor < 1:
return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA)
else:
return image
def preprocess_face_image(self, image: numpy_ndarray) -> numpy_ndarray:
"""
Preprocess image for face restoration models
Face restoration models typically expect normalized input in range [0, 1]
"""
# Optimización: Asegurar memoria contigua al inicio
image = numpy_ascontiguousarray(image)
# --- NUEVO CÓDIGO PARA CORREGIR LOS CANALES ---
# Si la imagen tiene 4 canales (BGRA), conviértela a 3 (BGR)
if image.shape[2] == 4:
image = opencv_cvtColor(image, COLOR_BGRA2BGR)
# --- FIN DEL NUEVO CÓDIGO ---
# Resize to model's expected input size
target_size = self.model_config["input_size"]
image = opencv_resize(image, target_size, interpolation=INTER_AREA)
# Determinar el tipo de dato correcto (float16 o float32)
if self.model_config.get("fp16", False):
dtype = float16
else:
dtype = float32
# Optimización: Normalizar usando memoria contigua
image = numpy_ascontiguousarray(image, dtype=dtype) / 255.0
# Transpose to CHW format (channels, height, width)
image = numpy_transpose(image, (2, 0, 1))
# Add batch dimension
image = numpy_expand_dims(image, axis=0)
return image
def postprocess_face_image(self, output: numpy_ndarray, original_size: tuple) -> numpy_ndarray:
"""
Postprocess face restoration model output
"""
# Remove batch dimension
output = numpy_squeeze(output, axis=0)
# Clamp values to [0, 1]
output = numpy_clip(output, 0, 1)
# Transpose back to HWC format
output = numpy_transpose(output, (1, 2, 0))
# Convert back to uint8
output = (output * 255).astype(uint8)
# Resize back to original size
if original_size != self.model_config["input_size"]:
output = opencv_resize(
output, (original_size[1], original_size[0]), interpolation=INTER_CUBIC)
return output
def face_restoration(self, image: numpy_ndarray) -> numpy_ndarray:
"""
Perform face restoration on the input image
"""
if self.inferenceSession is None:
self._load_inferenceSession()
# Store original size for later restoration
original_size = (image.shape[0], image.shape[1])
# Apply input resizing
image = self.resize_with_input_factor(image)
# Preprocess for face restoration
preprocessed = self.preprocess_face_image(image)
# Run inference
input_name = self.inferenceSession.get_inputs()[0].name
output_name = self.inferenceSession.get_outputs()[0].name
result = self.inferenceSession.run(
[output_name], {input_name: preprocessed})[0]
# Postprocess the result
restored_face = self.postprocess_face_image(
result, (image.shape[0], image.shape[1]))
# Apply output resizing
restored_face = self.resize_with_output_factor(restored_face)
return restored_face
def AI_orchestration(self, image: numpy_ndarray) -> numpy_ndarray:
"""
Main orchestration function for face restoration
"""
try:
return self.face_restoration(image)
except Exception as e:
print(f"[FACE RESTORATION ERROR] {str(e)}")
# Return original image if restoration fails
return image
# GUI utils ---------------------------
@@ -824,6 +1081,13 @@ class MessageBox(CTkToplevel):
self.resizable(True, True)
self.grab_set() # make other windows not clickable
# Set minimum and maximum window sizes for better scrolling
self.minsize(700, 500)
self.maxsize(1000, 800)
# Set initial window size based on content
self.geometry("750x600")
def _ok_event(
self,
event=None
@@ -852,9 +1116,9 @@ class MessageBox(CTkToplevel):
spacingLabel2 = self.createEmptyLabel()
if self._messageType == "info":
title_subtitle_text_color = "#FFD700" # Amarillo dorado
title_subtitle_text_color = accent_color # Amarillo dorado
elif self._messageType == "error":
title_subtitle_text_color = "#FF3131" # Rojo brillante
title_subtitle_text_color = error_color # Rojo brillante
titleLabel = CTkLabel(
master=self,
@@ -874,7 +1138,7 @@ class MessageBox(CTkToplevel):
anchor='w',
justify="left",
fg_color="transparent",
text_color="#FFD700", # Amarillo dorado
text_color=accent_color, # Amarillo dorado
font=bold17,
text=f"Default: {self._default_value}"
)
@@ -911,25 +1175,43 @@ class MessageBox(CTkToplevel):
columnspan=2, padx=0, pady=0, sticky="ew")
def placeInfoMessageOptionsText(self) -> None:
# Create a scrollable frame for the options
from customtkinter import CTkScrollableFrame
for option_text in self._option_list:
self.scrollable_frame = CTkScrollableFrame(
master=self,
width=600,
height=300, # Fixed height to enable scrolling
fg_color="transparent",
corner_radius=10,
scrollbar_button_color=border_color,
scrollbar_button_hover_color=button_hover_color
)
self._ctkwidgets_index += 1
self.scrollable_frame.grid(row=self._ctkwidgets_index, column=0,
columnspan=2, padx=25, pady=10, sticky="ew")
# Add options to the scrollable frame
for i, option_text in enumerate(self._option_list):
optionLabel = CTkLabel(
master=self,
width=600,
height=45,
master=self.scrollable_frame,
width=550, # Slightly smaller to account for scrollbar
anchor='w',
justify="left",
text_color=text_color,
fg_color="#282828",
fg_color=widget_background_color,
bg_color="transparent",
font=bold13,
text=option_text,
corner_radius=10,
wraplength=530 # Enable text wrapping
)
self._ctkwidgets_index += 1
optionLabel.grid(row=self._ctkwidgets_index, column=0,
columnspan=2, padx=25, pady=4, sticky="ew")
optionLabel.grid(row=i, column=0, padx=10, pady=4, sticky="ew")
# Configure grid weight for the scrollable frame
self.scrollable_frame.grid_columnconfigure(0, weight=1)
spacingLabel3 = self.createEmptyLabel()
@@ -948,9 +1230,10 @@ class MessageBox(CTkToplevel):
width=125,
font=bold11,
border_width=1,
fg_color="#282828",
text_color="#E0E0E0",
border_color="#F5E358"
fg_color=widget_background_color,
text_color=secondary_text_color,
border_color=accent_color,
hover_color=button_hover_color
)
self._ctkwidgets_index += 1
@@ -1014,7 +1297,7 @@ class FileWidget(CTkScrollableFrame):
self,
text=os_path_basename(file_path),
font=bold14,
text_color=text_color,
text_color=accent_color, # Usar color amarillo para nombres de archivo
compound="left",
anchor="w",
padx=10,
@@ -1035,7 +1318,7 @@ class FileWidget(CTkScrollableFrame):
text=infos,
image=icon,
font=bold12,
text_color=text_color,
text_color=secondary_text_color, # Usar color de texto secundario para info
compound="left",
anchor="w",
padx=10,
@@ -1066,9 +1349,10 @@ class FileWidget(CTkScrollableFrame):
font=bold11,
border_width=1,
corner_radius=1,
fg_color="#282828",
text_color="#E0E0E0",
border_color="#FFD53D"
fg_color=widget_background_color,
text_color=text_color,
border_color=accent_color,
hover_color=button_hover_color
)
button.grid(row=0, column=2, pady=(7, 7), padx=(0, 7))
@@ -1080,16 +1364,24 @@ class FileWidget(CTkScrollableFrame):
if check_if_file_is_video(file_path):
video_cap = opencv_VideoCapture(file_path)
_, frame = video_cap.read()
source_icon = opencv_cvtColor(frame, COLOR_BGR2RGB)
if frame is not None:
source_icon = opencv_cvtColor(frame, COLOR_BGR2RGB)
else:
# Fallback para videos problemáticos
source_icon = numpy_zeros((60, 60, 3), dtype=uint8)
video_cap.release()
else:
source_icon = opencv_cvtColor(image_read(file_path), COLOR_BGR2RGB)
# Optimización: Usar memoria contigua para mejor rendimiento
source_icon = numpy_ascontiguousarray(source_icon)
ratio = min(
max_size / source_icon.shape[0], max_size / source_icon.shape[1])
new_width = int(source_icon.shape[1] * ratio)
new_height = int(source_icon.shape[0] * ratio)
source_icon = opencv_resize(source_icon, (new_width, new_height))
source_icon = opencv_resize(
source_icon, (new_width, new_height), interpolation=INTER_AREA)
ctk_icon = CTkImage(pillow_image_fromarray(
source_icon, mode="RGB"), size=(new_width, new_height))
@@ -1237,10 +1529,11 @@ def create_info_button(command: Callable, text: str, width: int = 200) -> CTkFra
command=command,
font=bold12,
text="?",
border_color="#ECD125",
border_color=accent_color,
border_width=1,
fg_color=widget_background_color,
hover_color=background_color,
fg_color=info_button_color,
hover_color=button_hover_color,
text_color=text_color,
width=23,
height=15,
corner_radius=1
@@ -1270,7 +1563,7 @@ def create_option_menu(
command: Callable,
values: list,
default_value: str,
border_color: str = "#404040",
border_color: str = None,
border_width: int = 1,
width: int = 159
) -> CTkFrame:
@@ -1281,6 +1574,10 @@ def create_option_menu(
total_width = (width + 2 * border_width)
total_height = (height + 2 * border_width)
# Use default border color if none provided
if border_color is None:
border_color = accent_color
frame = CTkFrame(
master=window,
fg_color=border_color,
@@ -1301,10 +1598,12 @@ def create_option_menu(
font=bold11,
anchor="center",
text_color=text_color,
fg_color=background_color,
button_color=background_color,
button_hover_color=background_color,
dropdown_fg_color=background_color
fg_color=widget_background_color,
button_color=widget_background_color,
button_hover_color=button_hover_color,
dropdown_fg_color=widget_background_color,
dropdown_text_color=text_color,
dropdown_hover_color=button_hover_color
)
option_menu.place(
@@ -1325,9 +1624,10 @@ def create_text_box(textvariable: StringVar, width: int) -> CTkEntry:
font=bold11,
justify="center",
text_color=text_color,
fg_color="#000000",
fg_color=widget_background_color,
border_width=1,
border_color="#404040",
border_color=accent_color,
placeholder_text_color=secondary_text_color
)
@@ -1340,10 +1640,10 @@ def create_text_box_output_path(textvariable: StringVar) -> CTkEntry:
height=28,
font=bold11,
justify="center",
text_color=text_color,
fg_color="#000000",
text_color=secondary_text_color,
fg_color=widget_background_color,
border_width=1,
border_color="#404040",
border_color=border_color,
state=DISABLED
)
@@ -1354,9 +1654,13 @@ def create_active_button(
icon: CTkImage = None,
width: int = 140,
height: int = 30,
border_color: str = "#C11919"
border_color: str = None
) -> CTkButton:
# Use default border color if none provided
if border_color is None:
border_color = accent_color
return CTkButton(
master=window,
command=command,
@@ -1367,9 +1671,10 @@ def create_active_button(
font=bold11,
border_width=1,
corner_radius=1,
fg_color="#282828",
text_color="#E0E0E0",
border_color=border_color
fg_color=widget_background_color,
text_color=text_color,
border_color=border_color,
hover_color=button_hover_color
)
@@ -3201,11 +3506,19 @@ def upscale_orchestrator(
try:
write_process_status(process_status_q, f"Loading AI model")
AI_upscale_instance_list = [
AI_upscale(selected_AI_model, selected_gpu,
input_resize_factor, output_resize_factor, tiles_resolution)
for _ in range(selected_AI_multithreading)
]
# Check if the selected model is a face restoration model
if selected_AI_model in Face_restoration_models_list:
AI_upscale_instance_list = [
AI_face_restoration(selected_AI_model, selected_gpu,
input_resize_factor, output_resize_factor, tiles_resolution)
for _ in range(selected_AI_multithreading)
]
else:
AI_upscale_instance_list = [
AI_upscale(selected_AI_model, selected_gpu,
input_resize_factor, output_resize_factor, tiles_resolution)
for _ in range(selected_AI_multithreading)
]
how_many_files = len(selected_file_list)
for file_number in range(how_many_files):
@@ -3831,7 +4144,8 @@ def select_AI_from_menu(selected_option: str) -> None:
# FluidFrames/RIFE: Show frame generation menu, otherwise show blending
if selected_AI_model in RIFE_models_list:
place_frame_generation_menu()
else:
# Face restoration models don't need blending (they work differently)
elif selected_AI_model not in Face_restoration_models_list:
place_AI_blending_menu()
# Always restore other key controls
place_AI_multithreading_menu()
@@ -3938,19 +4252,20 @@ def place_loadFile_section():
master=window, fg_color=background_color, corner_radius=1)
text_drop = (" SUPPORTED FILES \n\n "
+ "IMAGES • jpg png tif bmp webp heic \n "
+ "VIDEOS • mp4 webm mkv flv gif avi mov mpg qt 3gp ")
+ "IMAGES • jpg, png, tif, bmp, webp, heic \n "
+ "VIDEOS • mp4, webm, mkv, flv, gif, avi, mov, mpg, qt, 3gp ")
input_file_text = CTkLabel(
master=window,
text=text_drop,
fg_color=background_color,
fg_color=widget_background_color,
bg_color=background_color,
text_color=text_color,
text_color=secondary_text_color,
width=300,
height=150,
font=bold13,
anchor="center"
anchor="center",
corner_radius=10
)
input_file_button = CTkButton(
@@ -3962,9 +4277,10 @@ def place_loadFile_section():
font=bold12,
border_width=1,
corner_radius=1,
fg_color="#282828",
text_color="#E0E0E0",
border_color="#ECD125"
fg_color=widget_background_color,
text_color=text_color,
border_color=accent_color,
hover_color=button_hover_color
)
background.place(relx=0.0, rely=0.0, relwidth=0.5, relheight=1.0)
@@ -3978,7 +4294,7 @@ def place_app_name():
app_name_label = CTkLabel(
master=window,
text=app_name + " " + version,
fg_color=background_color,
fg_color="transparent",
text_color=app_name_color,
font=bold20,
anchor="w"
@@ -4006,6 +4322,12 @@ def place_AI_menu():
" • Year: 2020\n"
" • Function: High-quality upscaling\n",
"\n GFPGAN \n"
"\n • Generative Face Prior GAN for face restoration\n"
" • Year: 2021\n"
" • Function: Face restoration and enhancement\n"
" • Excellent for old/blurry photos\n",
"\n RIFE | RIFE Lite\n" +
" • The complete RIFE AI model & Lite version\n" +
" • Excellent frame generation quality\n" +
@@ -4504,8 +4826,8 @@ def place_message_label():
height=26,
width=200,
font=bold11,
fg_color="#ffbf00",
text_color="#000000",
fg_color=accent_color,
text_color=background_color,
anchor="center",
corner_radius=1
)
@@ -4519,7 +4841,7 @@ def place_stop_button():
icon=stop_icon,
width=140,
height=30,
border_color="#EC1D1D"
border_color=error_color
)
stop_button.place(relx=0.75 - 0.1, rely=0.95, anchor="center")
@@ -4677,7 +4999,8 @@ class SplashScreen(CTkToplevel):
self.geometry(f"{window_width}x{window_height}+{x}+{y}")
# Configure appearance to match app
self.configure(fg_color="#212325") # background_color
# Usar color de fondo definido
self.configure(fg_color=background_color)
# Create banner or title
if has_banner:
@@ -4693,14 +5016,14 @@ class SplashScreen(CTkToplevel):
self,
text="Warlock Studio",
font=CTkFont(family="Segoe UI", size=28, weight="bold"),
text_color="#ECD125" # app_name_color
text_color=app_name_color # Usar color del nombre de la app
)
title_label.pack(pady=(50, 20))
# Create status frame with progress messages
status_frame = CTkFrame(
self,
fg_color="#343638", # widget_background_color
fg_color=widget_background_color, # Usar color de widget definido
corner_radius=10
)
status_frame.pack(pady=10, padx=20, fill="x")
@@ -4709,10 +5032,31 @@ class SplashScreen(CTkToplevel):
status_frame,
text="Loading AI-ONNX models...",
font=CTkFont(family="Segoe UI", size=12, weight="bold"),
text_color="white" # text_color
text_color=accent_color # Usar color amarillo para el texto de estado
)
self.status_label.pack(pady=10, padx=10)
# Create progress bar
self.progress_bar = CTkProgressBar(
status_frame,
width=400,
height=10,
progress_color=accent_color, # Usar color amarillo dorado
fg_color=border_color, # Usar color de borde
border_width=1
)
self.progress_bar.pack(pady=(0, 10), padx=10)
self.progress_bar.set(0) # Start at 0%
# Create version label
version_label = CTkLabel(
self,
text=f"Version {version}",
font=CTkFont(family="Segoe UI", size=10),
text_color=secondary_text_color # Usar color de texto secundario
)
version_label.pack(pady=(0, 10))
# Define enough messages to fill 15 seconds (~1.5s por mensaje)
self.messages = [
"Preparing environment...",
@@ -4755,7 +5099,43 @@ class SplashScreen(CTkToplevel):
if __name__ == "__main__":
multiprocessing_freeze_support()
set_appearance_mode("Dark")
set_default_color_theme("dark-blue")
# Crear tema personalizado
import customtkinter
from customtkinter import set_default_color_theme
# Configurar tema personalizado con colores definidos
customtkinter.set_default_color_theme("dark-blue") # Base theme
# Sobrescribir algunos colores globales de CustomTkinter
try:
# Aplicar colores personalizados a nivel global
customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] = [
widget_background_color, widget_background_color]
customtkinter.ThemeManager.theme["CTkButton"]["fg_color"] = [
widget_background_color, widget_background_color]
customtkinter.ThemeManager.theme["CTkButton"]["hover_color"] = [
button_hover_color, button_hover_color]
customtkinter.ThemeManager.theme["CTkButton"]["text_color"] = [
text_color, text_color]
customtkinter.ThemeManager.theme["CTkButton"]["border_color"] = [
accent_color, accent_color]
customtkinter.ThemeManager.theme["CTkEntry"]["fg_color"] = [
widget_background_color, widget_background_color]
customtkinter.ThemeManager.theme["CTkEntry"]["text_color"] = [
text_color, text_color]
customtkinter.ThemeManager.theme["CTkEntry"]["border_color"] = [
accent_color, accent_color]
customtkinter.ThemeManager.theme["CTkOptionMenu"]["fg_color"] = [
widget_background_color, widget_background_color]
customtkinter.ThemeManager.theme["CTkOptionMenu"]["text_color"] = [
text_color, text_color]
customtkinter.ThemeManager.theme["CTkOptionMenu"]["button_hover_color"] = [
button_hover_color, button_hover_color]
customtkinter.ThemeManager.theme["CTkLabel"]["text_color"] = [
text_color, text_color]
except Exception as e:
print(f"[THEME] Could not apply custom theme: {e}")
process_status_q = multiprocessing_Queue(maxsize=1)
+2 -2
View File
@@ -5,14 +5,14 @@ a = Analysis(
['Warlock-Studio.py'],
pathex=[],
binaries=[],
datas=[('AI-onnx', 'AI-onnx'), ('Assets', 'Assets'), ('rsc', 'rsc')],
datas=[('AI-onnx', 'AI-onnx'), ('Assets', 'Assets')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
optimize=1,
)
pyz = PYZ(a.pure)