mirror of
https://github.com/upscayl/upscayl.git
synced 2024-11-23 23:21:05 +01:00
Removed jsx
This commit is contained in:
parent
a2e7cc16a7
commit
973525bac9
25
main/binaries.js
Normal file
25
main/binaries.js
Normal file
@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
/*
|
||||
appRootDir is the resources directory inside the unpacked electron app temp directory.
|
||||
resources contains app.asar file, that contains the main and renderer files.
|
||||
We're putting resources/{os}/bin from project inside resources/bin of electron. Same for the models directory as well.
|
||||
*/
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.modelsPath = exports.execPath = void 0;
|
||||
const path_1 = require("path");
|
||||
const getPlatform_1 = require("./getPlatform");
|
||||
const electron_is_dev_1 = __importDefault(require("electron-is-dev"));
|
||||
const electron_1 = require("electron");
|
||||
const appRootDir = electron_1.app.getAppPath();
|
||||
const binariesPath = electron_is_dev_1.default
|
||||
? (0, path_1.join)(appRootDir, "resources", (0, getPlatform_1.getPlatform)(), "bin")
|
||||
: (0, path_1.join)((0, path_1.dirname)(appRootDir), "bin");
|
||||
const execPath = (execName) => (0, path_1.resolve)((0, path_1.join)(binariesPath, `./upscayl-${execName}`));
|
||||
exports.execPath = execPath;
|
||||
const modelsPath = electron_is_dev_1.default
|
||||
? (0, path_1.resolve)((0, path_1.join)(appRootDir, "resources", "models"))
|
||||
: (0, path_1.resolve)((0, path_1.join)((0, path_1.dirname)(appRootDir), "models"));
|
||||
exports.modelsPath = modelsPath;
|
BIN
main/build/icon.icns
Normal file
BIN
main/build/icon.icns
Normal file
Binary file not shown.
BIN
main/build/icon.png
Normal file
BIN
main/build/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
17
main/commands.js
Normal file
17
main/commands.js
Normal file
@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commands = {
|
||||
SELECT_FILE: "Select a File",
|
||||
SELECT_FOLDER: "Select a Folder",
|
||||
UPSCAYL: "Upscale the Image",
|
||||
UPSCAYL_DONE: "Upscaling Done",
|
||||
UPSCAYL_PROGRESS: "Send Progress from Main to Renderer",
|
||||
DOUBLE_UPSCAYL: "Double Upscale the Image",
|
||||
DOUBLE_UPSCAYL_DONE: "Double Upscaling Done",
|
||||
DOUBLE_UPSCAYL_PROGRESS: "Send Double Upscayl Progress from Main to Renderer",
|
||||
FOLDER_UPSCAYL: "Upscale a Folder",
|
||||
FOLDER_UPSCAYL_DONE: "Folder upscaling successful",
|
||||
FOLDER_UPSCAYL_PROGRESS: "Send Folder Upscaling Progress from Main to Renderer",
|
||||
OPEN_FOLDER: "Open Folder",
|
||||
};
|
||||
exports.default = commands;
|
20
main/getPlatform.js
Normal file
20
main/getPlatform.js
Normal file
@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPlatform = void 0;
|
||||
const os_1 = require("os");
|
||||
const getPlatform = () => {
|
||||
switch ((0, os_1.platform)()) {
|
||||
case "aix":
|
||||
case "freebsd":
|
||||
case "linux":
|
||||
case "openbsd":
|
||||
case "android":
|
||||
return "linux";
|
||||
case "darwin":
|
||||
case "sunos":
|
||||
return "mac";
|
||||
case "win32":
|
||||
return "win";
|
||||
}
|
||||
};
|
||||
exports.getPlatform = getPlatform;
|
390
main/index.js
Normal file
390
main/index.js
Normal file
@ -0,0 +1,390 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// Native
|
||||
const path_1 = require("path");
|
||||
const url_1 = require("url");
|
||||
const child_process_1 = require("child_process");
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const electron_updater_1 = require("electron-updater");
|
||||
const getPlatform_1 = require("./getPlatform");
|
||||
const binaries_1 = require("./binaries");
|
||||
// Packages
|
||||
const electron_1 = require("electron");
|
||||
const electron_is_dev_1 = __importDefault(require("electron-is-dev"));
|
||||
const electron_next_1 = __importDefault(require("electron-next"));
|
||||
const commands_1 = __importDefault(require("./commands"));
|
||||
// Prepare the renderer once the app is ready
|
||||
let mainWindow;
|
||||
electron_1.app.on("ready", () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
yield (0, electron_next_1.default)("./renderer");
|
||||
console.log("🚀 Icon Path: ", (0, path_1.join)(__dirname, "build", "icon.png"));
|
||||
console.log("🚀 Development Mode? :", electron_is_dev_1.default);
|
||||
console.log("🚀 RS Executable Path: ", (0, binaries_1.execPath)(""));
|
||||
console.log("🚀 Models: ", binaries_1.modelsPath);
|
||||
mainWindow = new electron_1.BrowserWindow({
|
||||
icon: (0, path_1.join)(__dirname, "build", "icon.png"),
|
||||
width: 1100,
|
||||
height: 740,
|
||||
minHeight: 500,
|
||||
minWidth: 500,
|
||||
show: false,
|
||||
backgroundColor: "#171717",
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webSecurity: false,
|
||||
preload: (0, path_1.join)(__dirname, "preload.js"),
|
||||
},
|
||||
});
|
||||
const url = electron_is_dev_1.default
|
||||
? "http://localhost:8000"
|
||||
: (0, url_1.format)({
|
||||
pathname: (0, path_1.join)(__dirname, "../renderer/out/index.html"),
|
||||
protocol: "file:",
|
||||
slashes: true,
|
||||
});
|
||||
mainWindow.setMenuBarVisibility(false);
|
||||
mainWindow.loadURL(url);
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
electron_1.shell.openExternal(url);
|
||||
return { action: "deny" };
|
||||
});
|
||||
mainWindow.once("ready-to-show", () => {
|
||||
mainWindow.show();
|
||||
mainWindow.webContents.setZoomFactor(1);
|
||||
});
|
||||
if (!electron_is_dev_1.default) {
|
||||
electron_updater_1.autoUpdater.checkForUpdates();
|
||||
}
|
||||
}));
|
||||
// Quit the app once all windows are closed
|
||||
electron_1.app.on("window-all-closed", electron_1.app.quit);
|
||||
console.log(electron_1.app.getAppPath());
|
||||
//------------------------Select File-----------------------------//
|
||||
// ! DONT FORGET TO RESTART THE APP WHEN YOU CHANGE CODE HERE
|
||||
electron_1.ipcMain.handle(commands_1.default.SELECT_FILE, () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { canceled, filePaths } = yield electron_1.dialog.showOpenDialog({
|
||||
properties: ["openFile", "multiSelections"],
|
||||
});
|
||||
if (canceled) {
|
||||
console.log("operation cancelled");
|
||||
return "cancelled";
|
||||
}
|
||||
else {
|
||||
console.log(filePaths[0]);
|
||||
// CREATE input AND upscaled FOLDER
|
||||
return filePaths[0];
|
||||
}
|
||||
}));
|
||||
//------------------------Select Folder-----------------------------//
|
||||
electron_1.ipcMain.handle(commands_1.default.SELECT_FOLDER, (event, message) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const { canceled, filePaths } = yield electron_1.dialog.showOpenDialog({
|
||||
properties: ["openDirectory"],
|
||||
});
|
||||
if (canceled) {
|
||||
console.log("operation cancelled");
|
||||
return "cancelled";
|
||||
}
|
||||
else {
|
||||
console.log(filePaths[0]);
|
||||
return filePaths[0];
|
||||
}
|
||||
}));
|
||||
//------------------------Double Upscayl-----------------------------//
|
||||
electron_1.ipcMain.on(commands_1.default.DOUBLE_UPSCAYL, (event, payload) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const model = payload.model;
|
||||
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
||||
let outputDir = payload.outputPath;
|
||||
// COPY IMAGE TO TMP FOLDER
|
||||
const platform = (0, getPlatform_1.getPlatform)();
|
||||
const fullfileName = platform === "win"
|
||||
? payload.imagePath.split("\\").slice(-1)[0]
|
||||
: payload.imagePath.split("/").slice(-1)[0];
|
||||
const fileName = (0, path_1.parse)(fullfileName).name;
|
||||
const fileExt = (0, path_1.parse)(fullfileName).ext;
|
||||
const outFile = outputDir + "/" + fileName + "_upscayl_8x_" + model + fileExt;
|
||||
// UPSCALE
|
||||
let upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realesrgan"), [
|
||||
"-i",
|
||||
inputDir + "/" + fullfileName,
|
||||
"-o",
|
||||
outFile,
|
||||
"-s",
|
||||
4,
|
||||
"-m",
|
||||
binaries_1.modelsPath,
|
||||
"-n",
|
||||
model,
|
||||
], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
let failed = false;
|
||||
// TAKE UPSCAYL OUTPUT
|
||||
upscayl.stderr.on("data", (data) => {
|
||||
// CONVERT DATA TO STRING
|
||||
data = data.toString();
|
||||
// PRINT TO CONSOLE
|
||||
console.log(data);
|
||||
// SEND UPSCAYL PROGRESS TO RENDERER
|
||||
mainWindow.webContents.send(commands_1.default.DOUBLE_UPSCAYL_PROGRESS, data);
|
||||
// IF PROGRESS HAS ERROR, UPSCAYL FAILED
|
||||
if (data.includes("invalid gpu") || data.includes("failed")) {
|
||||
failed = true;
|
||||
}
|
||||
});
|
||||
// IF ERROR
|
||||
upscayl.on("error", (data) => {
|
||||
data.toString();
|
||||
// SEND UPSCAYL PROGRESS TO RENDERER
|
||||
mainWindow.webContents.send(commands_1.default.DOUBLE_UPSCAYL_PROGRESS, data);
|
||||
// SET FAILED TO TRUE
|
||||
failed = true;
|
||||
return;
|
||||
});
|
||||
// ON UPSCAYL DONE
|
||||
upscayl.on("close", (code) => {
|
||||
// IF NOT FAILED
|
||||
if (!failed) {
|
||||
// UPSCALE
|
||||
let upscayl2 = (0, child_process_1.spawn)((0, binaries_1.execPath)("realesrgan"), ["-i", outFile, "-o", outFile, "-s", 4, "-m", binaries_1.modelsPath, "-n", model], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
let failed2 = false;
|
||||
// TAKE UPSCAYL OUTPUT
|
||||
upscayl2.stderr.on("data", (data) => {
|
||||
// CONVERT DATA TO STRING
|
||||
data = data.toString();
|
||||
// PRINT TO CONSOLE
|
||||
console.log(data);
|
||||
// SEND UPSCAYL PROGRESS TO RENDERER
|
||||
mainWindow.webContents.send(commands_1.default.DOUBLE_UPSCAYL_PROGRESS, data);
|
||||
// IF PROGRESS HAS ERROR, UPSCAYL FAILED
|
||||
if (data.includes("invalid gpu") || data.includes("failed")) {
|
||||
failed2 = true;
|
||||
}
|
||||
});
|
||||
// IF ERROR
|
||||
upscayl2.on("error", (data) => {
|
||||
data.toString();
|
||||
// SEND UPSCAYL PROGRESS TO RENDERER
|
||||
mainWindow.webContents.send(commands_1.default.DOUBLE_UPSCAYL_PROGRESS, data);
|
||||
// SET FAILED TO TRUE
|
||||
failed2 = true;
|
||||
return;
|
||||
});
|
||||
upscayl2.on("close", (code) => {
|
||||
if (!failed2) {
|
||||
console.log("Done upscaling");
|
||||
mainWindow.webContents.send(commands_1.default.DOUBLE_UPSCAYL_DONE, outFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
//------------------------Image Upscayl-----------------------------//
|
||||
electron_1.ipcMain.on(commands_1.default.UPSCAYL, (event, payload) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const model = payload.model;
|
||||
const scale = payload.scaleFactor;
|
||||
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
||||
let outputDir = payload.outputPath;
|
||||
// COPY IMAGE TO TMP FOLDER
|
||||
const platform = (0, getPlatform_1.getPlatform)();
|
||||
const fullfileName = platform === "win"
|
||||
? payload.imagePath.split("\\").slice(-1)[0]
|
||||
: payload.imagePath.split("/").slice(-1)[0];
|
||||
console.log(fullfileName);
|
||||
const fileName = (0, path_1.parse)(fullfileName).name;
|
||||
const fileExt = (0, path_1.parse)(fullfileName).ext;
|
||||
const outFile = model.includes("realesrgan")
|
||||
? outputDir + "/" + fileName + "_upscayl_" + scale + "x_" + model + fileExt
|
||||
: outputDir +
|
||||
"/" +
|
||||
fileName +
|
||||
"_upscayl_sharpened_" +
|
||||
scale +
|
||||
"x_" +
|
||||
model +
|
||||
fileExt;
|
||||
// UPSCALE
|
||||
if (fs_1.default.existsSync(outFile)) {
|
||||
// If already upscayled, just output that file
|
||||
mainWindow.webContents.send(commands_1.default.UPSCAYL_DONE, outFile);
|
||||
}
|
||||
else {
|
||||
let upscayl = null;
|
||||
switch (model) {
|
||||
case "realesrgan-x4plus":
|
||||
case "realesrgan-x4plus-anime":
|
||||
upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realesrgan"), [
|
||||
"-i",
|
||||
inputDir + "/" + fullfileName,
|
||||
"-o",
|
||||
outFile,
|
||||
"-s",
|
||||
scale === 2 ? 4 : scale,
|
||||
"-m",
|
||||
binaries_1.modelsPath,
|
||||
"-n",
|
||||
model,
|
||||
], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
break;
|
||||
case "models-DF2K":
|
||||
upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realsr"), [
|
||||
"-i",
|
||||
inputDir + "/" + fullfileName,
|
||||
"-o",
|
||||
outFile,
|
||||
"-s",
|
||||
scale,
|
||||
"-x",
|
||||
"-m",
|
||||
binaries_1.modelsPath + "/" + model,
|
||||
], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
break;
|
||||
}
|
||||
let failed = false;
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.stderr.on("data", (data) => {
|
||||
console.log("🚀 => upscayl.stderr.on => stderr.toString()", data.toString());
|
||||
data = data.toString();
|
||||
mainWindow.webContents.send(commands_1.default.UPSCAYL_PROGRESS, data.toString());
|
||||
if (data.includes("invalid gpu") || data.includes("failed")) {
|
||||
failed = true;
|
||||
}
|
||||
});
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.on("error", (data) => {
|
||||
mainWindow.webContents.send(commands_1.default.UPSCAYL_PROGRESS, data.toString());
|
||||
failed = true;
|
||||
return;
|
||||
});
|
||||
// Send done comamnd when
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.on("close", (code) => {
|
||||
if (failed !== true) {
|
||||
console.log("Done upscaling");
|
||||
mainWindow.webContents.send(commands_1.default.UPSCAYL_DONE, outFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
//------------------------Upscayl Folder-----------------------------//
|
||||
electron_1.ipcMain.on(commands_1.default.FOLDER_UPSCAYL, (event, payload) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const model = payload.model;
|
||||
let inputDir = payload.batchFolderPath;
|
||||
let outputDir = model.includes("realesrgan")
|
||||
? payload.outputPath
|
||||
: payload.outputPath + "_sharpened";
|
||||
console.log(outputDir);
|
||||
if (!fs_1.default.existsSync(outputDir)) {
|
||||
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
// UPSCALE
|
||||
let upscayl = null;
|
||||
switch (model) {
|
||||
case "realesrgan-x4plus":
|
||||
case "realesrgan-x4plus-anime":
|
||||
upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realesrgan"), [
|
||||
"-i",
|
||||
inputDir,
|
||||
"-o",
|
||||
outputDir,
|
||||
"-s",
|
||||
4,
|
||||
"-m",
|
||||
binaries_1.modelsPath,
|
||||
"-n",
|
||||
model,
|
||||
], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
break;
|
||||
case "models-DF2K":
|
||||
upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realsr"), [
|
||||
"-i",
|
||||
inputDir,
|
||||
"-o",
|
||||
outputDir,
|
||||
"-s",
|
||||
4,
|
||||
"-x",
|
||||
"-m",
|
||||
binaries_1.modelsPath + "/" + model,
|
||||
], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
break;
|
||||
}
|
||||
let failed = false;
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.stderr.on("data", (data) => {
|
||||
console.log("🚀 => upscayl.stderr.on => stderr.toString()", data.toString());
|
||||
data = data.toString();
|
||||
mainWindow.webContents.send(commands_1.default.FOLDER_UPSCAYL_PROGRESS, data.toString());
|
||||
if (data.includes("invalid gpu") || data.includes("failed")) {
|
||||
failed = true;
|
||||
}
|
||||
});
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.on("error", (data) => {
|
||||
mainWindow.webContents.send(commands_1.default.FOLDER_UPSCAYL_PROGRESS, data.toString());
|
||||
failed = true;
|
||||
return;
|
||||
});
|
||||
// Send done comamnd when
|
||||
upscayl === null || upscayl === void 0 ? void 0 : upscayl.on("close", (code) => {
|
||||
if (failed !== true) {
|
||||
console.log("Done upscaling");
|
||||
mainWindow.webContents.send(commands_1.default.FOLDER_UPSCAYL_DONE, outputDir);
|
||||
}
|
||||
});
|
||||
}));
|
||||
electron_1.ipcMain.on(commands_1.default.OPEN_FOLDER, (event, payload) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
console.log(payload);
|
||||
electron_1.shell.openPath(payload);
|
||||
}));
|
||||
//------------------------Auto-Update Code-----------------------------//
|
||||
// ! AUTO UPDATE STUFF
|
||||
electron_updater_1.autoUpdater.on("update-available", ({ releaseNotes, releaseName }) => {
|
||||
const dialogOpts = {
|
||||
type: "info",
|
||||
buttons: ["Ok"],
|
||||
title: "Application Update",
|
||||
message: process.platform === "win32"
|
||||
? releaseNotes
|
||||
: releaseName,
|
||||
detail: "A new version is being downloaded.",
|
||||
};
|
||||
electron_1.dialog.showMessageBox(dialogOpts).then((returnValue) => { });
|
||||
});
|
||||
electron_updater_1.autoUpdater.on("update-downloaded", (event) => {
|
||||
const dialogOpts = {
|
||||
type: "info",
|
||||
buttons: ["Restart", "Later"],
|
||||
title: "Application Update",
|
||||
message: process.platform === "win32"
|
||||
? event.releaseNotes
|
||||
: event.releaseName,
|
||||
detail: "A new version has been downloaded. Restart the application to apply the updates.",
|
||||
};
|
||||
electron_1.dialog.showMessageBox(dialogOpts).then((returnValue) => {
|
||||
if (returnValue.response === 0)
|
||||
electron_updater_1.autoUpdater.quitAndInstall();
|
||||
});
|
||||
});
|
11
main/preload.js
Normal file
11
main/preload.js
Normal file
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const electron_1 = require("electron");
|
||||
// 'ipcRenderer' will be available in index.js with the method 'window.electron'
|
||||
electron_1.contextBridge.exposeInMainWorld("electron", {
|
||||
send: (command, payload) => electron_1.ipcRenderer.send(command, payload),
|
||||
on: (command, func) => electron_1.ipcRenderer.on(command, (event, args) => {
|
||||
func(event, args);
|
||||
}),
|
||||
invoke: (command, payload) => electron_1.ipcRenderer.invoke(command, payload),
|
||||
});
|
21
main/utils.js
Normal file
21
main/utils.js
Normal file
@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const child_process_1 = require("child_process");
|
||||
const binaries_1 = require("./binaries");
|
||||
/**
|
||||
*
|
||||
* @param {*} inputFile
|
||||
* @param {*} outFile
|
||||
* @param {*} modelsPath
|
||||
* @param {*} model
|
||||
* @returns
|
||||
*/
|
||||
function upscaylImage(inputFile, outFile, modelsPath, model) {
|
||||
// UPSCALE
|
||||
let upscayl = (0, child_process_1.spawn)((0, binaries_1.execPath)("realesrgan"), ["-i", inputFile, "-o", outFile, "-s", "4", "-m", modelsPath, "-n", model], {
|
||||
cwd: undefined,
|
||||
detached: false,
|
||||
});
|
||||
return upscayl;
|
||||
}
|
||||
module.exports = { upscaylImage };
|
162
package.json
162
package.json
@ -1,162 +0,0 @@
|
||||
{
|
||||
"name": "upscayl",
|
||||
"private": true,
|
||||
"version": "1.5.5",
|
||||
"productName": "Upscayl",
|
||||
"homepage": "https://github.com/TGS963/upscayl",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Nayam Amarshe",
|
||||
"email": "nayam@amars.he",
|
||||
"url": "https://github.com/NayamAmarshe"
|
||||
},
|
||||
{
|
||||
"name": "TGS963",
|
||||
"email": "tgs@963.com",
|
||||
"url": "https://github.com/TGS963"
|
||||
}
|
||||
],
|
||||
"email": "simplelogin-newsletter.j1zez@aleeas.com",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Upscayl - Free and Open Source AI Image Upscaler",
|
||||
"keywords": [
|
||||
"AI",
|
||||
"Upscaler",
|
||||
"Image Upscale",
|
||||
"Linux image upscale",
|
||||
"Topaz Gigapixel",
|
||||
"Linux",
|
||||
"KDE",
|
||||
"Gnome"
|
||||
],
|
||||
"main": "main/index.js",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist renderer/.next renderer/out",
|
||||
"start": "electron .",
|
||||
"build": "next build renderer && next export renderer",
|
||||
"tsc": "tsc",
|
||||
"pack-app": "npm run build && electron-builder --dir",
|
||||
"dist": "npm run build && DEBUG=* electron-builder",
|
||||
"dist:appimage": "npm run build && DEBUG=* electron-builder build -l AppImage",
|
||||
"dist:flatpak": "npm run build && DEBUG=* electron-builder build -l flatpak",
|
||||
"dist:zip": "npm run build && DEBUG=* electron-builder build -l zip",
|
||||
"dist:dmg": "npm run build && DEBUG=* electron-builder build -m dmg",
|
||||
"dist:msi": "npm run build && DEBUG=* electron-builder build -w nsis",
|
||||
"dist:pkg": "npm run build && DEBUG=* electron-builder build -m pkg",
|
||||
"publish-app": "npm run build && electron-builder -wl --publish always",
|
||||
"publish-linux-app": "npm run build && electron-builder -l --publish always",
|
||||
"publish-win-app": "npm run build && electron-builder -w --publish always",
|
||||
"publish-mac-app": "npm run build && electron-builder -m --publish always"
|
||||
},
|
||||
"build": {
|
||||
"productName": "Upscayl",
|
||||
"appId": "org.upscayl.app",
|
||||
"artifactName": "${name}-${version}-${os}.${ext}",
|
||||
"asar": true,
|
||||
"extraFiles": [
|
||||
{
|
||||
"from": "resources/${os}/bin",
|
||||
"to": "resources/bin",
|
||||
"filter": [
|
||||
"**/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "resources/models",
|
||||
"to": "resources/models",
|
||||
"filter": [
|
||||
"**/*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"mac": {
|
||||
"type": "distribution",
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "main/resources/entitlements.mac.plist",
|
||||
"entitlementsInherit": "main/resources/entitlements.mac.plist",
|
||||
"gatekeeperAssess": false,
|
||||
"target": [
|
||||
{
|
||||
"target": "dmg",
|
||||
"arch": [
|
||||
"x64"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dmg": {
|
||||
"contents": [
|
||||
{
|
||||
"x": 130,
|
||||
"y": 220
|
||||
},
|
||||
{
|
||||
"x": 410,
|
||||
"y": 220,
|
||||
"type": "link",
|
||||
"path": "/Applications"
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux": {
|
||||
"publish": [
|
||||
"github"
|
||||
],
|
||||
"target": [
|
||||
"AppImage",
|
||||
"flatpak",
|
||||
"zip"
|
||||
],
|
||||
"category": "Graphics;2DGraphics;RasterGraphics;ImageProcessing;"
|
||||
},
|
||||
"win": {
|
||||
"publish": [
|
||||
"github"
|
||||
],
|
||||
"target": [
|
||||
"nsis"
|
||||
],
|
||||
"icon": "main/build/icon.png"
|
||||
},
|
||||
"files": [
|
||||
"main",
|
||||
"renderer/out"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.8",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"electron": "^21.2.2",
|
||||
"electron-builder": "^23.6.0",
|
||||
"next": "^13.0.2",
|
||||
"postcss": "^8.4.18",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-tailwindcss": "^0.1.13",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"tailwindcss": "^3.2.2",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"app-root-dir": "^1.0.2",
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"electron-is-packaged": "^1.0.2",
|
||||
"electron-next": "^3.1.5",
|
||||
"electron-root-path": "^1.1.0",
|
||||
"electron-updater": "^5.3.0",
|
||||
"image-size": "^1.0.2",
|
||||
"react-compare-slider": "^2.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-image-zoom": "^1.3.1",
|
||||
"react-magnifier": "^3.0.4",
|
||||
"react-select": "^5.6.0",
|
||||
"react-tooltip": "^4.4.3",
|
||||
"tailwind-scrollbar": "^2.0.1"
|
||||
},
|
||||
"volta": {
|
||||
"node": "16.17.0"
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<div className="p-2 text-center text-sm text-neutral-500">
|
||||
<p>
|
||||
Copyright © 2022 -{" "}
|
||||
<a
|
||||
className="font-bold"
|
||||
href="https://github.com/upscayl/upscayl"
|
||||
target="_blank"
|
||||
>
|
||||
Upscayl
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
By{" "}
|
||||
<a
|
||||
href="https://github.com/TGS963"
|
||||
className="font-bold"
|
||||
target="_blank"
|
||||
>
|
||||
TGS963
|
||||
</a>{" "}
|
||||
and{" "}
|
||||
<a
|
||||
href="https://github.com/NayamAmarshe"
|
||||
className="font-bold"
|
||||
target="_blank"
|
||||
>
|
||||
Nayam Amarshe
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
@ -1,24 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<a
|
||||
href="https://github.com/upscayl/upscayl"
|
||||
target="_blank"
|
||||
className="outline-none focus-visible:ring-2"
|
||||
>
|
||||
<div className="flex items-center gap-3 px-5 py-5">
|
||||
<img
|
||||
src="icon.png"
|
||||
className="inline-block w-14"
|
||||
alt="Upscayl Logo"
|
||||
data-tip="Star us on GitHub 😁"
|
||||
/>
|
||||
<div className="flex flex-col justify-center">
|
||||
<h1 className="text-3xl font-bold text-neutral-50">Upscayl</h1>
|
||||
<p className="text-neutral-400">AI Image Upscaler</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
import React from "react";
|
||||
import Select from "react-select";
|
||||
import ReactTooltip from "react-tooltip";
|
||||
|
||||
function LeftPaneSteps(props) {
|
||||
const handleBatchMode = () => {
|
||||
props.setBatchMode((oldValue) => !oldValue);
|
||||
};
|
||||
|
||||
const customStyles = {
|
||||
option: (provided, state) => ({
|
||||
...provided,
|
||||
borderBottom: "1px dotted pink",
|
||||
color: state.isSelected ? "red" : "blue",
|
||||
padding: 20,
|
||||
}),
|
||||
control: () => ({
|
||||
// none of react-select's styles are passed to <Control />
|
||||
width: 200,
|
||||
}),
|
||||
singleValue: (provided, state) => {
|
||||
const opacity = state.isDisabled ? 0.5 : 1;
|
||||
const transition = "opacity 300ms";
|
||||
|
||||
return { ...provided, opacity, transition };
|
||||
},
|
||||
};
|
||||
|
||||
const modelOptions = [
|
||||
{ label: "General Photo", value: "realesrgan-x4plus" },
|
||||
{ label: "Digital Art", value: "realesrgan-x4plus-anime" },
|
||||
{ label: "Sharpen Image", value: "models-DF2K" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="animate-step-in animate flex h-screen flex-col gap-7 overflow-auto p-5">
|
||||
{/* BATCH OPTION */}
|
||||
<div className="flex flex-row items-end">
|
||||
<p
|
||||
className="mr-1 inline-block cursor-help text-sm text-white/70"
|
||||
data-tip="This will let you upscale all files in a folder at once"
|
||||
>
|
||||
Batch Upscale:
|
||||
</p>
|
||||
<button
|
||||
className={`animate relative inline-block h-5 w-8 cursor-pointer rounded-full outline-none focus-visible:shadow-lg focus-visible:shadow-purple-500 ${
|
||||
props.batchMode ? "bg-gradient-purple" : "bg-neutral-500"
|
||||
}`}
|
||||
onClick={handleBatchMode}
|
||||
>
|
||||
<div
|
||||
className={`${
|
||||
props.batchMode ? "translate-x-4" : "translate-x-1"
|
||||
} animate absolute top-1/2 h-3 w-3 -translate-y-1/2 rounded-full bg-neutral-100`}
|
||||
></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 1 */}
|
||||
<div data-tip={props.imagePath}>
|
||||
<p className="step-heading">Step 1</p>
|
||||
<button
|
||||
className="animate bg-gradient-red rounded-lg p-3 font-medium text-white/90 outline-none transition-colors focus-visible:shadow-lg focus-visible:shadow-red-500"
|
||||
onClick={
|
||||
!props.batchMode
|
||||
? props.selectImageHandler
|
||||
: props.selectFolderHandler
|
||||
}
|
||||
>
|
||||
Select {props.batchMode ? "Folder" : "Image"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 2 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="step-heading">Step 2</p>
|
||||
<p className="mb-2 text-sm text-white/60">Select Upscaling Type</p>
|
||||
|
||||
<Select
|
||||
options={modelOptions}
|
||||
components={{
|
||||
IndicatorSeparator: () => null,
|
||||
DropdownIndicator: () => null,
|
||||
}}
|
||||
onChange={props.handleModelChange}
|
||||
className="react-select-container"
|
||||
classNamePrefix="react-select"
|
||||
defaultValue={modelOptions[0]}
|
||||
theme={(theme) => ({
|
||||
...theme,
|
||||
colors: {
|
||||
...theme.colors,
|
||||
primary: "rgb(71 85 105)",
|
||||
primary25: "#f5f5f5",
|
||||
primary50: "#f5f5f5",
|
||||
},
|
||||
})}
|
||||
styles={{
|
||||
input: (provided, state) => ({
|
||||
...provided,
|
||||
color: "rgb(100 100 100)",
|
||||
}),
|
||||
dropdownIndicator: (provided, state) => ({
|
||||
...provided,
|
||||
color: "rgb(15 15 15)",
|
||||
}),
|
||||
placeholder: (provided, state) => ({
|
||||
...provided,
|
||||
color: "rgb(15 15 15)",
|
||||
fontWeight: "500",
|
||||
}),
|
||||
singleValue: (provided, state) => ({
|
||||
...provided,
|
||||
color: "rgb(15 15 15)",
|
||||
fontWeight: "500",
|
||||
}),
|
||||
menu: (provided, state) => ({
|
||||
...provided,
|
||||
background: "#f5f5f5",
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* <select
|
||||
name="select-model"
|
||||
onDrop={(e) => props.handleDrop(e)}
|
||||
className="animate bg-gradient-white block cursor-pointer rounded-lg p-3 font-medium text-black/90 outline-none hover:bg-slate-200 focus-visible:ring-2 focus-visible:ring-slate-400"
|
||||
onChange={props.handleModelChange}
|
||||
>
|
||||
<option value="realesrgan-x4plus">General Photo</option>
|
||||
<option value="realesrgan-x4plus-anime">Digital Art</option>
|
||||
<option value="models-DF2K">Sharpen Image</option>
|
||||
</select> */}
|
||||
|
||||
{props.model !== "models-DF2K" && !props.batchMode && (
|
||||
<div className="mt-2 flex items-center gap-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="checked:bg-gradient-white h-4 w-4 cursor-pointer appearance-none rounded-full bg-white/30 transition duration-200 focus:outline-none focus-visible:border focus-visible:shadow-lg focus-visible:shadow-white/40"
|
||||
checked={props.doubleUpscayl}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
props.setDoubleUpscayl(true);
|
||||
} else {
|
||||
props.setDoubleUpscayl(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p
|
||||
className={`inline-block cursor-pointer select-none rounded-full text-sm font-medium ${
|
||||
props.doubleUpscayl
|
||||
? "bg-gradient-white px-2 text-black/90"
|
||||
: "text-white/50"
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
props.setDoubleUpscayl(!props.doubleUpscayl);
|
||||
}}
|
||||
>
|
||||
Double Upscayl
|
||||
</p>
|
||||
<span
|
||||
className="cursor-help rounded-full bg-white/20 px-3 text-center font-bold text-white/40"
|
||||
data-tip="Enable this option to get an 8x upscayl. Note that this may not always work properly with all images, for example, images with really large resolutions."
|
||||
>
|
||||
i
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* STEP 3 */}
|
||||
<div className="animate-step-in" data-tip={props.outputPath}>
|
||||
<p className="step-heading">Step 3</p>
|
||||
<p className="mb-2 text-sm text-white/60">Defaults to Image's path</p>
|
||||
<button
|
||||
className="animate bg-gradient mt-1 rounded-lg p-3 font-medium text-black/90 outline-none transition-colors focus-visible:shadow-lg focus-visible:shadow-green-500"
|
||||
onClick={props.outputHandler}
|
||||
>
|
||||
Set Output Folder
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 4 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="step-heading">Step 4</p>
|
||||
<button
|
||||
className="animate bg-gradient-upscayl rounded-lg p-3 font-medium text-white/90 outline-none transition-colors focus-visible:shadow-lg focus-visible:shadow-violet-500"
|
||||
onClick={props.upscaylHandler}
|
||||
disabled={props.progress.length > 0}
|
||||
>
|
||||
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ReactTooltip
|
||||
className="max-w-md break-words bg-neutral-900 text-neutral-50"
|
||||
place="top"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LeftPaneSteps;
|
@ -1,20 +0,0 @@
|
||||
import React from "react";
|
||||
import Animated from "../public/loading.svg";
|
||||
import Image from "next/image";
|
||||
|
||||
function ProgressBar(props) {
|
||||
console.log(props.sharpening);
|
||||
return (
|
||||
<div className="absolute flex h-full w-full flex-col items-center justify-center bg-black/50 backdrop-blur-lg">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<Image src={Animated} />
|
||||
<p className="font-bold text-neutral-50">{props.progress}</p>
|
||||
<p className="text-sm font-medium text-neutral-200">
|
||||
Doing the Upscayl magic...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProgressBar;
|
@ -1,14 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function ResetButton(props) {
|
||||
return (
|
||||
<button
|
||||
className="animate bg-gradient-blue absolute top-1 right-1 z-10 rounded-full py-2 px-4 text-white opacity-30 hover:opacity-100"
|
||||
onClick={props.resetImagePaths}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default ResetButton;
|
@ -1,20 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function RightPaneInfo({ version, batchMode }) {
|
||||
return (
|
||||
<>
|
||||
<p className="p-5 pb-0 text-lg font-medium text-neutral-400">
|
||||
Select {batchMode ? "a Folder" : "an Image"} to Upscale
|
||||
</p>
|
||||
{batchMode && (
|
||||
<p className="w-full py-5 text-center text-neutral-500 md:w-96">
|
||||
Make sure that the folder doesn't contain anything except PNG, JPG,
|
||||
JPEG & WEBP images.
|
||||
</p>
|
||||
)}
|
||||
<p className="text-neutral-600">Upscayl v{version}</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RightPaneInfo;
|
@ -1,409 +0,0 @@
|
||||
import { useState, useEffect, useRef, useCallback } from "react";
|
||||
import commands from "../../main/commands";
|
||||
import {
|
||||
ReactCompareSlider,
|
||||
ReactCompareSliderImage,
|
||||
} from "react-compare-slider";
|
||||
import Header from "../components/Header";
|
||||
import Footer from "../components/Footer";
|
||||
import ProgressBar from "../components/ProgressBar";
|
||||
import ResetButton from "../components/ResetButton";
|
||||
import LeftPaneSteps from "../components/LeftPaneSteps";
|
||||
import RightPaneInfo from "../components/RightPaneInfo";
|
||||
|
||||
const Home = () => {
|
||||
const [imagePath, SetImagePath] = useState("");
|
||||
const [upscaledImagePath, setUpscaledImagePath] = useState("");
|
||||
const [outputPath, SetOutputPath] = useState("");
|
||||
const [scaleFactor, setScaleFactor] = useState(4);
|
||||
const [progress, setProgress] = useState("");
|
||||
const [model, setModel] = useState("realesrgan-x4plus");
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [version, setVersion] = useState("");
|
||||
const [batchMode, setBatchMode] = useState(false);
|
||||
const [batchFolderPath, setBatchFolderPath] = useState("");
|
||||
const [upscaledBatchFolderPath, setUpscaledBatchFolderPath] = useState("");
|
||||
const [doubleUpscayl, setDoubleUpscayl] = useState(false);
|
||||
|
||||
const resetImagePaths = () => {
|
||||
setProgress("");
|
||||
|
||||
SetImagePath("");
|
||||
setUpscaledImagePath("");
|
||||
|
||||
setBatchFolderPath("");
|
||||
setUpscaledBatchFolderPath("");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setLoaded(true);
|
||||
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
setVersion(navigator.userAgent.match(/Upscayl\/([\d\.]+\d+)/)[1]);
|
||||
|
||||
const handleErrors = (data) => {
|
||||
if (data.includes("invalid gpu")) {
|
||||
alert(
|
||||
"Error. Please make sure you have a Vulkan compatible GPU (Most modern GPUs support Vulkan). Upscayl does not work with CPU or iGPU sadly."
|
||||
);
|
||||
resetImagePaths();
|
||||
} else if (data.includes("failed")) {
|
||||
if (batchMode) return;
|
||||
alert(
|
||||
data.includes("encode") ? "ENCODING ERROR => " : "DECODING ERROR => ",
|
||||
"This image is possibly corrupt or not supported by Upscayl. You could try converting the image into another format and upscaling again. Otherwise, make sure that the output path is correct and you have the proper write permissions for the directory. If not, then unfortuantely this image is not supported by Upscayl, sorry."
|
||||
);
|
||||
resetImagePaths();
|
||||
} else if (data.includes("uncaughtException")) {
|
||||
alert(
|
||||
"Upscayl encountered an error. Possibly, the upscayl binary failed to execute the commands properly. Try launching Upscayl using commandline through Terminal and see if you get any information. You can post an issue on Upscayl's GitHub repository for more help."
|
||||
);
|
||||
resetImagePaths();
|
||||
}
|
||||
};
|
||||
|
||||
window.electron.on(commands.UPSCAYL_PROGRESS, (_, data) => {
|
||||
console.log(
|
||||
"🚀 => file: index.jsx => line 61 => window.electron.on => data",
|
||||
data
|
||||
);
|
||||
|
||||
if (data.length > 0 && data.length < 10) {
|
||||
setProgress(data);
|
||||
}
|
||||
handleErrors(data);
|
||||
});
|
||||
window.electron.on(commands.FOLDER_UPSCAYL_PROGRESS, (_, data) => {
|
||||
if (data.length > 0 && data.length < 10) {
|
||||
setProgress(data);
|
||||
}
|
||||
handleErrors(data);
|
||||
});
|
||||
window.electron.on(commands.DOUBLE_UPSCAYL_PROGRESS, (_, data) => {
|
||||
if (data.length > 0 && data.length < 10) {
|
||||
setProgress(data);
|
||||
}
|
||||
handleErrors(data);
|
||||
});
|
||||
|
||||
window.electron.on(commands.UPSCAYL_DONE, (_, data) => {
|
||||
setProgress("");
|
||||
setUpscaledImagePath(data);
|
||||
});
|
||||
window.electron.on(commands.FOLDER_UPSCAYL_DONE, (_, data) => {
|
||||
setProgress("");
|
||||
setUpscaledBatchFolderPath(data);
|
||||
});
|
||||
window.electron.on(commands.DOUBLE_UPSCAYL_DONE, (_, data) => {
|
||||
setUpscaledImagePath(data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setProgress("");
|
||||
}, [batchMode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (imagePath.length > 0) {
|
||||
const filePath = imagePath;
|
||||
console.log(
|
||||
"🚀 => file: index.jsx => line 109 => useEffect => filePath",
|
||||
filePath
|
||||
);
|
||||
|
||||
const extension = imagePath.toLocaleLowerCase().split(".").pop();
|
||||
console.log(
|
||||
"🚀 => file: index.jsx => line 111 => useEffect => extension",
|
||||
extension
|
||||
);
|
||||
|
||||
if (!allowedFileTypes.includes(extension.toLowerCase())) {
|
||||
alert("Please select an image");
|
||||
resetImagePaths();
|
||||
}
|
||||
}
|
||||
}, [imagePath]);
|
||||
|
||||
const selectImageHandler = async () => {
|
||||
resetImagePaths();
|
||||
|
||||
var path = await window.electron.invoke(commands.SELECT_FILE);
|
||||
|
||||
if (path !== "cancelled") {
|
||||
SetImagePath(path);
|
||||
var dirname = path.match(/(.*)[\/\\]/)[1] || "";
|
||||
SetOutputPath(dirname);
|
||||
}
|
||||
};
|
||||
|
||||
const selectFolderHandler = async () => {
|
||||
resetImagePaths();
|
||||
|
||||
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
||||
|
||||
if (path !== "cancelled") {
|
||||
setBatchFolderPath(path);
|
||||
SetOutputPath(path + "_upscayled");
|
||||
}
|
||||
};
|
||||
|
||||
const handleModelChange = (e) => {
|
||||
setModel(e.value);
|
||||
if (e.value === "models-DF2K") {
|
||||
setDoubleUpscayl(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnter = (e) => {
|
||||
e.preventDefault();
|
||||
console.log("drag enter");
|
||||
};
|
||||
const handleDragLeave = (e) => {
|
||||
e.preventDefault();
|
||||
console.log("drag leave");
|
||||
};
|
||||
const handleDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
console.log("drag over");
|
||||
};
|
||||
const openFolderHandler = (e) => {
|
||||
window.electron.send(commands.OPEN_FOLDER, upscaledBatchFolderPath);
|
||||
};
|
||||
|
||||
const allowedFileTypes = ["png", "jpg", "jpeg", "webp"];
|
||||
|
||||
const handleDrop = (e) => {
|
||||
e.preventDefault();
|
||||
resetImagePaths();
|
||||
|
||||
const type = e.dataTransfer.items[0].type;
|
||||
console.log("🚀 => handleDrop => type", type);
|
||||
const filePath = e.dataTransfer.files[0].path;
|
||||
console.log("🚀 => handleDrop => filePath", filePath);
|
||||
const extension = e.dataTransfer.files[0].name.split(".").at(-1);
|
||||
console.log("🚀 => handleDrop => extension", extension);
|
||||
|
||||
if (
|
||||
!type.includes("image") ||
|
||||
!allowedFileTypes.includes(extension.toLowerCase())
|
||||
) {
|
||||
alert("Please drag and drop an image");
|
||||
} else {
|
||||
SetImagePath(filePath);
|
||||
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
|
||||
console.log("🚀 => handleDrop => dirname", dirname);
|
||||
SetOutputPath(dirname);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePaste = (e) => {
|
||||
console.log(e);
|
||||
resetImagePaths();
|
||||
e.preventDefault();
|
||||
const type = e.clipboardData.items[0].type;
|
||||
const filePath = e.clipboardData.files[0].path;
|
||||
const extension = e.clipboardData.files[0].name.split(".").at(-1);
|
||||
|
||||
if (
|
||||
!type.includes("image") &&
|
||||
!allowedFileTypes.includes(extension.toLowerCase())
|
||||
) {
|
||||
alert("Please drag and drop an image");
|
||||
} else {
|
||||
SetImagePath(filePath);
|
||||
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
|
||||
SetOutputPath(dirname);
|
||||
}
|
||||
};
|
||||
|
||||
const outputHandler = async () => {
|
||||
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
||||
if (path !== "cancelled") {
|
||||
SetOutputPath(path);
|
||||
} else {
|
||||
console.log("Getting output path from input file");
|
||||
}
|
||||
};
|
||||
|
||||
const upscaylHandler = async () => {
|
||||
setUpscaledImagePath("");
|
||||
if (imagePath !== "" || batchFolderPath !== "") {
|
||||
setProgress("Hold on...");
|
||||
if (model === "models-DF2K") {
|
||||
setDoubleUpscayl(false);
|
||||
}
|
||||
|
||||
if (doubleUpscayl) {
|
||||
await window.electron.send(commands.DOUBLE_UPSCAYL, {
|
||||
imagePath,
|
||||
outputPath,
|
||||
model,
|
||||
});
|
||||
} else if (batchMode) {
|
||||
setDoubleUpscayl(false);
|
||||
await window.electron.send(commands.FOLDER_UPSCAYL, {
|
||||
scaleFactor,
|
||||
batchFolderPath,
|
||||
outputPath,
|
||||
model,
|
||||
});
|
||||
} else {
|
||||
await window.electron.send(commands.UPSCAYL, {
|
||||
scaleFactor,
|
||||
imagePath,
|
||||
outputPath,
|
||||
model,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
alert("Please select an image to upscale");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-screen flex-row overflow-hidden bg-[#1d1c23]">
|
||||
<div className="flex h-screen w-96 flex-col bg-[#26222c]">
|
||||
{((!batchMode && imagePath.length > 0) ||
|
||||
(batchMode && batchFolderPath.length > 0)) && (
|
||||
<ResetButton resetImagePaths={resetImagePaths} />
|
||||
)}
|
||||
{/* HEADER */}
|
||||
<Header />
|
||||
|
||||
{/* LEFT PANE */}
|
||||
<LeftPaneSteps
|
||||
progress={progress}
|
||||
selectImageHandler={selectImageHandler}
|
||||
selectFolderHandler={selectFolderHandler}
|
||||
handleModelChange={handleModelChange}
|
||||
handleDrop={handleDrop}
|
||||
outputHandler={outputHandler}
|
||||
upscaylHandler={upscaylHandler}
|
||||
batchMode={batchMode}
|
||||
setBatchMode={setBatchMode}
|
||||
imagePath={imagePath}
|
||||
outputPath={outputPath}
|
||||
doubleUpscayl={doubleUpscayl}
|
||||
setDoubleUpscayl={setDoubleUpscayl}
|
||||
model={model}
|
||||
/>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
{/* RIGHT PANE */}
|
||||
<div
|
||||
className="relative flex h-screen w-full flex-col items-center justify-center"
|
||||
onDrop={(e) => handleDrop(e)}
|
||||
onDragOver={(e) => handleDragOver(e)}
|
||||
onDragEnter={(e) => handleDragEnter(e)}
|
||||
onDragLeave={(e) => handleDragLeave(e)}
|
||||
onPaste={(e) => handlePaste(e)}
|
||||
>
|
||||
{progress.length > 0 &&
|
||||
upscaledImagePath.length === 0 &&
|
||||
upscaledBatchFolderPath.length === 0 ? (
|
||||
<ProgressBar progress={progress} />
|
||||
) : null}
|
||||
|
||||
{((!batchMode &&
|
||||
imagePath.length === 0 &&
|
||||
upscaledImagePath.length === 0) ||
|
||||
(batchMode &&
|
||||
batchFolderPath.length === 0 &&
|
||||
upscaledBatchFolderPath.length === 0)) && (
|
||||
<RightPaneInfo version={version} batchMode={batchMode} />
|
||||
)}
|
||||
|
||||
{!batchMode &&
|
||||
upscaledImagePath.length === 0 &&
|
||||
imagePath.length > 0 && (
|
||||
<img
|
||||
className="h-full w-full object-contain"
|
||||
src={
|
||||
"file://" +
|
||||
`${upscaledImagePath ? upscaledImagePath : imagePath}`
|
||||
}
|
||||
draggable="false"
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
|
||||
{batchMode &&
|
||||
upscaledBatchFolderPath.length === 0 &&
|
||||
batchFolderPath.length > 0 && (
|
||||
<p className="select-none font-bold text-neutral-50">
|
||||
Selected folder: {batchFolderPath}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{batchMode && upscaledBatchFolderPath.length > 0 && (
|
||||
<>
|
||||
<p className="select-none py-4 font-bold text-neutral-50">
|
||||
All done!
|
||||
</p>
|
||||
<button
|
||||
className="bg-gradient-blue rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||
onClick={openFolderHandler}
|
||||
>
|
||||
Open Upscayled Folder
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{!batchMode && imagePath.length > 0 && upscaledImagePath.length > 0 && (
|
||||
<ReactCompareSlider
|
||||
itemOne={
|
||||
<>
|
||||
<p className="absolute bottom-1 left-1 rounded-md bg-black p-1 text-sm font-medium text-white opacity-30">
|
||||
Original
|
||||
</p>
|
||||
<ReactCompareSliderImage
|
||||
src={"file://" + imagePath}
|
||||
alt="Original"
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
}}
|
||||
className="bg-[#1d1c23]"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
itemTwo={
|
||||
<>
|
||||
<p className="absolute bottom-1 right-1 rounded-md bg-black p-1 text-sm font-medium text-white opacity-30">
|
||||
Upscayled
|
||||
</p>
|
||||
<ReactCompareSliderImage
|
||||
src={"file://" + upscaledImagePath}
|
||||
alt="Upscayl"
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
}}
|
||||
className="bg-[#1d1c23]"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
className="h-screen"
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* {imagePath.length === 0 && batchFolderPath.length === 0 ? (
|
||||
<RightPaneInfo version={version} />
|
||||
) : upscaledImagePath.length === 0 &&
|
||||
upscaledBatchFolderPath.length === 0 ? (
|
||||
!batchMode ? (
|
||||
|
||||
) : (
|
||||
|
||||
)
|
||||
) : !batchMode ? (
|
||||
|
||||
) : (
|
||||
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
Loading…
Reference in New Issue
Block a user