mirror of
https://github.com/upscayl/upscayl.git
synced 2025-02-17 11:18:36 +01:00
Refactor code and remove config vars to fix ASCII path decoding
This commit is contained in:
parent
618b46f553
commit
5feabea516
5
common/decode-path.ts
Normal file
5
common/decode-path.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export default function decodePath(filePath: string): string {
|
||||||
|
return path.normalize(decodeURIComponent(filePath));
|
||||||
|
}
|
15
common/get-directory-from-path.ts
Normal file
15
common/get-directory-from-path.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default function getDirectoryFromPath(filePath: string): string {
|
||||||
|
// Define the path separator based on the operating system
|
||||||
|
const separator = filePath.includes("/") ? "/" : "\\";
|
||||||
|
|
||||||
|
// Split the file path by the path separator
|
||||||
|
const pathParts = filePath.split(separator);
|
||||||
|
|
||||||
|
// Remove the last element to get the directory
|
||||||
|
pathParts.pop();
|
||||||
|
|
||||||
|
// Join the remaining parts back together to form the directory path
|
||||||
|
const directoryPath = pathParts.join(separator);
|
||||||
|
|
||||||
|
return directoryPath || "";
|
||||||
|
}
|
8
common/get-file-name.ts
Normal file
8
common/get-file-name.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export default function getFilenameFromPath(
|
||||||
|
path: string,
|
||||||
|
withExtension: boolean = true,
|
||||||
|
) {
|
||||||
|
if (!path) return "";
|
||||||
|
if (withExtension) return path.split("/").slice(-1)[0];
|
||||||
|
return path.split("/").slice(-1)[0].split(".").slice(0, -1).join(".");
|
||||||
|
}
|
24
common/sanitize-path.ts
Normal file
24
common/sanitize-path.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export function sanitizePath(filePath: string) {
|
||||||
|
// const protocolPrefix = "file://";
|
||||||
|
|
||||||
|
// Normalize the file path to use forward slashes (for Windows)
|
||||||
|
const normalizedFilePath = filePath.replace(/\\/g, "/");
|
||||||
|
|
||||||
|
// Split the file path into segments based on forward slashes
|
||||||
|
const pathSegments = normalizedFilePath.split("/");
|
||||||
|
|
||||||
|
// Encode each segment separately using encodeURIComponent
|
||||||
|
const encodedPathSegments = pathSegments.map((segment) =>
|
||||||
|
encodeURIComponent(segment),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Join the encoded segments back together with forward slashes
|
||||||
|
const encodedFilePath = encodedPathSegments.join("/");
|
||||||
|
|
||||||
|
// Combine the protocol prefix with the encoded file path to create the final file URL
|
||||||
|
const fileUrl = encodedFilePath;
|
||||||
|
console.log("🚀 => fileUrl:", fileUrl);
|
||||||
|
|
||||||
|
// Return the final Electron file URL
|
||||||
|
return fileUrl;
|
||||||
|
}
|
13
common/types/types.d.ts
vendored
13
common/types/types.d.ts
vendored
@ -1,10 +1,12 @@
|
|||||||
|
import { ImageFormat } from "@electron/types/types";
|
||||||
|
|
||||||
export type ImageUpscaylPayload = {
|
export type ImageUpscaylPayload = {
|
||||||
imagePath: string;
|
imagePath: string;
|
||||||
outputPath?: string;
|
outputPath: string;
|
||||||
scale: string;
|
scale: string;
|
||||||
model: string;
|
model: string;
|
||||||
gpuId: string;
|
gpuId: string;
|
||||||
saveImageAs: string;
|
saveImageAs: ImageFormat;
|
||||||
overwrite: boolean;
|
overwrite: boolean;
|
||||||
compression: string;
|
compression: string;
|
||||||
noImageProcessing: boolean;
|
noImageProcessing: boolean;
|
||||||
@ -14,11 +16,14 @@ export type ImageUpscaylPayload = {
|
|||||||
|
|
||||||
export type DoubleUpscaylPayload = {
|
export type DoubleUpscaylPayload = {
|
||||||
model: string;
|
model: string;
|
||||||
|
/**
|
||||||
|
* The path to the image to upscale.
|
||||||
|
*/
|
||||||
imagePath: string;
|
imagePath: string;
|
||||||
outputPath: string;
|
outputPath: string;
|
||||||
scale: string;
|
scale: string;
|
||||||
gpuId: string;
|
gpuId: string;
|
||||||
saveImageAs: string;
|
saveImageAs: ImageFormat;
|
||||||
compression: string;
|
compression: string;
|
||||||
noImageProcessing: boolean;
|
noImageProcessing: boolean;
|
||||||
customWidth: string;
|
customWidth: string;
|
||||||
@ -30,7 +35,7 @@ export type BatchUpscaylPayload = {
|
|||||||
outputPath: string;
|
outputPath: string;
|
||||||
model: string;
|
model: string;
|
||||||
gpuId: string;
|
gpuId: string;
|
||||||
saveImageAs: string;
|
saveImageAs: ImageFormat;
|
||||||
scale: string;
|
scale: string;
|
||||||
compression: string;
|
compression: string;
|
||||||
noImageProcessing: boolean;
|
noImageProcessing: boolean;
|
||||||
|
@ -3,9 +3,6 @@ import { getMainWindow } from "../main-window";
|
|||||||
import {
|
import {
|
||||||
childProcesses,
|
childProcesses,
|
||||||
savedCustomModelsPath,
|
savedCustomModelsPath,
|
||||||
rememberOutputFolder,
|
|
||||||
setCompression,
|
|
||||||
setNoImageProcessing,
|
|
||||||
setStopped,
|
setStopped,
|
||||||
stopped,
|
stopped,
|
||||||
} from "../utils/config-variables";
|
} from "../utils/config-variables";
|
||||||
@ -16,55 +13,33 @@ import slash from "../utils/slash";
|
|||||||
import { modelsPath } from "../utils/get-resource-paths";
|
import { modelsPath } from "../utils/get-resource-paths";
|
||||||
import COMMAND from "../../common/commands";
|
import COMMAND from "../../common/commands";
|
||||||
import { BatchUpscaylPayload } from "../../common/types/types";
|
import { BatchUpscaylPayload } from "../../common/types/types";
|
||||||
import { ImageFormat } from "../types/types";
|
|
||||||
import showNotification from "../utils/show-notification";
|
import showNotification from "../utils/show-notification";
|
||||||
import { DEFAULT_MODELS } from "../../common/models-list";
|
import { DEFAULT_MODELS } from "../../common/models-list";
|
||||||
|
|
||||||
const batchUpscayl = async (event, payload: BatchUpscaylPayload) => {
|
const batchUpscayl = async (event, payload: BatchUpscaylPayload) => {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
if (!mainWindow) return;
|
if (!mainWindow) return;
|
||||||
// GET THE MODEL
|
|
||||||
const model = payload.model;
|
|
||||||
const gpuId = payload.gpuId;
|
|
||||||
const saveImageAs = payload.saveImageAs as ImageFormat;
|
|
||||||
console.log("PAYLOAD: ", payload);
|
|
||||||
// GET THE IMAGE DIRECTORY
|
|
||||||
let inputDir = payload.batchFolderPath;
|
|
||||||
// GET THE OUTPUT DIRECTORY
|
|
||||||
let outputFolderPath = payload.outputPath;
|
|
||||||
if (rememberOutputFolder === true && outputFolderPath) {
|
|
||||||
outputFolderPath = outputFolderPath;
|
|
||||||
}
|
|
||||||
// ! Don't do fetchLocalStorage() again, it causes the values to be reset
|
|
||||||
setNoImageProcessing(payload.noImageProcessing);
|
|
||||||
setCompression(parseInt(payload.compression));
|
|
||||||
|
|
||||||
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
|
||||||
|
|
||||||
const scale = payload.scale;
|
const scale = payload.scale;
|
||||||
const useCustomWidth = payload.useCustomWidth;
|
const useCustomWidth = payload.useCustomWidth;
|
||||||
const customWidth = useCustomWidth ? payload.customWidth : "";
|
const customWidth = useCustomWidth ? payload.customWidth : "";
|
||||||
|
const model = payload.model;
|
||||||
|
const gpuId = payload.gpuId;
|
||||||
|
const saveImageAs = payload.saveImageAs;
|
||||||
|
// GET THE IMAGE DIRECTORY
|
||||||
|
let inputDir = decodeURIComponent(payload.batchFolderPath);
|
||||||
|
// GET THE OUTPUT DIRECTORY
|
||||||
|
let outputFolderPath = decodeURIComponent(payload.outputPath);
|
||||||
const outputFolderName = `upscayl_${saveImageAs}_${model}_${
|
const outputFolderName = `upscayl_${saveImageAs}_${model}_${
|
||||||
useCustomWidth ? `${customWidth}px` : `${scale}x`
|
useCustomWidth ? `${customWidth}px` : `${scale}x`
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
outputFolderPath += slash + outputFolderName;
|
outputFolderPath += slash + outputFolderName;
|
||||||
|
// CREATE THE OUTPUT DIRECTORY
|
||||||
if (!fs.existsSync(outputFolderPath)) {
|
if (!fs.existsSync(outputFolderPath)) {
|
||||||
fs.mkdirSync(outputFolderPath, { recursive: true });
|
fs.mkdirSync(outputFolderPath, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete .DS_Store files
|
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
||||||
fs.readdirSync(inputDir).forEach((file) => {
|
|
||||||
if (
|
|
||||||
file === ".DS_Store" ||
|
|
||||||
file.toLowerCase() === "desktop.ini" ||
|
|
||||||
file.startsWith(".")
|
|
||||||
) {
|
|
||||||
logit("🗑️ Deleting .DS_Store file");
|
|
||||||
fs.unlinkSync(inputDir + slash + file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// UPSCALE
|
// UPSCALE
|
||||||
const upscayl = spawnUpscayl(
|
const upscayl = spawnUpscayl(
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import path, { parse } from "path";
|
import { parse } from "path";
|
||||||
import { getMainWindow } from "../main-window";
|
import { getMainWindow } from "../main-window";
|
||||||
import {
|
import {
|
||||||
childProcesses,
|
childProcesses,
|
||||||
savedCustomModelsPath,
|
savedCustomModelsPath,
|
||||||
savedOutputPath,
|
|
||||||
rememberOutputFolder,
|
|
||||||
setCompression,
|
|
||||||
setNoImageProcessing,
|
|
||||||
setStopped,
|
setStopped,
|
||||||
stopped,
|
stopped,
|
||||||
} from "../utils/config-variables";
|
} from "../utils/config-variables";
|
||||||
@ -23,38 +19,31 @@ import { DoubleUpscaylPayload } from "../../common/types/types";
|
|||||||
import { ImageFormat } from "../types/types";
|
import { ImageFormat } from "../types/types";
|
||||||
import showNotification from "../utils/show-notification";
|
import showNotification from "../utils/show-notification";
|
||||||
import { DEFAULT_MODELS } from "../../common/models-list";
|
import { DEFAULT_MODELS } from "../../common/models-list";
|
||||||
import getModelScale from "../../common/check-model-scale";
|
import getFilenameFromPath from "../../common/get-file-name";
|
||||||
|
import decodePath from "../../common/decode-path";
|
||||||
|
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
||||||
|
|
||||||
const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
if (!mainWindow) return;
|
if (!mainWindow) return;
|
||||||
|
|
||||||
const model = payload.model as string;
|
const compression = payload.compression;
|
||||||
const imagePath = payload.imagePath;
|
const scale = parseInt(payload.scale) ** 2;
|
||||||
let inputDir = (imagePath.match(/(.*)[\/\\]/) || [""])[1];
|
const useCustomWidth = payload.useCustomWidth;
|
||||||
let outputDir = path.normalize(payload.outputPath);
|
const customWidth = useCustomWidth ? payload.customWidth : "";
|
||||||
|
const model = payload.model;
|
||||||
if (rememberOutputFolder === true && savedOutputPath) {
|
|
||||||
outputDir = savedOutputPath;
|
|
||||||
}
|
|
||||||
const gpuId = payload.gpuId as string;
|
const gpuId = payload.gpuId as string;
|
||||||
const saveImageAs = payload.saveImageAs as ImageFormat;
|
const saveImageAs = payload.saveImageAs as ImageFormat;
|
||||||
|
const imagePath = decodePath(payload.imagePath);
|
||||||
setNoImageProcessing(payload.noImageProcessing);
|
let inputDir = getDirectoryFromPath(imagePath);
|
||||||
setCompression(parseInt(payload.compression));
|
let outputDir = decodePath(payload.outputPath);
|
||||||
|
const fullfileName = getFilenameFromPath(imagePath);
|
||||||
|
const fileName = parse(fullfileName).name;
|
||||||
|
|
||||||
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
||||||
|
|
||||||
// COPY IMAGE TO TMP FOLDER
|
// COPY IMAGE TO TMP FOLDER
|
||||||
|
|
||||||
const fullfileName = imagePath.split(slash).slice(-1)[0] as string;
|
|
||||||
const fileName = parse(fullfileName).name;
|
|
||||||
|
|
||||||
const modelScale = getModelScale(model);
|
|
||||||
const scale = parseInt(payload.scale) ** 2;
|
|
||||||
const useCustomWidth = payload.useCustomWidth;
|
|
||||||
const customWidth = useCustomWidth ? payload.customWidth : "";
|
|
||||||
|
|
||||||
const outFile =
|
const outFile =
|
||||||
outputDir +
|
outputDir +
|
||||||
slash +
|
slash +
|
||||||
@ -69,7 +58,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
|||||||
let upscayl = spawnUpscayl(
|
let upscayl = spawnUpscayl(
|
||||||
getDoubleUpscaleArguments({
|
getDoubleUpscaleArguments({
|
||||||
inputDir,
|
inputDir,
|
||||||
fullfileName,
|
fullfileName: decodeURIComponent(fullfileName),
|
||||||
outFile,
|
outFile,
|
||||||
modelsPath: isDefaultModel
|
modelsPath: isDefaultModel
|
||||||
? modelsPath
|
? modelsPath
|
||||||
@ -128,13 +117,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
|||||||
logit("💯 Done upscaling");
|
logit("💯 Done upscaling");
|
||||||
|
|
||||||
mainWindow.setProgressBar(-1);
|
mainWindow.setProgressBar(-1);
|
||||||
mainWindow.webContents.send(
|
mainWindow.webContents.send(COMMAND.DOUBLE_UPSCAYL_DONE, outFile);
|
||||||
COMMAND.DOUBLE_UPSCAYL_DONE,
|
|
||||||
outFile.replace(
|
|
||||||
/([^/\\]+)$/i,
|
|
||||||
encodeURIComponent(outFile.match(/[^/\\]+$/i)![0]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
showNotification("Upscayled", "Image upscayled successfully!");
|
showNotification("Upscayled", "Image upscayled successfully!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -188,6 +171,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
|||||||
saveImageAs,
|
saveImageAs,
|
||||||
scale: scale.toString(),
|
scale: scale.toString(),
|
||||||
customWidth,
|
customWidth,
|
||||||
|
compression,
|
||||||
}),
|
}),
|
||||||
logit,
|
logit,
|
||||||
);
|
);
|
||||||
|
@ -2,14 +2,8 @@ import fs from "fs";
|
|||||||
import { modelsPath } from "../utils/get-resource-paths";
|
import { modelsPath } from "../utils/get-resource-paths";
|
||||||
import COMMAND from "../../common/commands";
|
import COMMAND from "../../common/commands";
|
||||||
import {
|
import {
|
||||||
savedCompression,
|
|
||||||
savedCustomModelsPath,
|
savedCustomModelsPath,
|
||||||
savedBatchUpscaylFolderPath,
|
|
||||||
savedOutputPath,
|
|
||||||
rememberOutputFolder,
|
|
||||||
setChildProcesses,
|
setChildProcesses,
|
||||||
setCompression,
|
|
||||||
setNoImageProcessing,
|
|
||||||
setStopped,
|
setStopped,
|
||||||
stopped,
|
stopped,
|
||||||
} from "../utils/config-variables";
|
} from "../utils/config-variables";
|
||||||
@ -23,6 +17,9 @@ import { ImageUpscaylPayload } from "../../common/types/types";
|
|||||||
import { ImageFormat } from "../types/types";
|
import { ImageFormat } from "../types/types";
|
||||||
import showNotification from "../utils/show-notification";
|
import showNotification from "../utils/show-notification";
|
||||||
import { DEFAULT_MODELS } from "../../common/models-list";
|
import { DEFAULT_MODELS } from "../../common/models-list";
|
||||||
|
import getFilenameFromPath from "../../common/get-file-name";
|
||||||
|
import decodePath from "../../common/decode-path";
|
||||||
|
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
||||||
|
|
||||||
const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
@ -32,34 +29,20 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setNoImageProcessing(payload.noImageProcessing);
|
|
||||||
setCompression(parseInt(payload.compression));
|
|
||||||
|
|
||||||
// GET VARIABLES
|
// GET VARIABLES
|
||||||
|
const compression = payload.compression;
|
||||||
|
const scale = payload.scale;
|
||||||
|
const useCustomWidth = payload.useCustomWidth;
|
||||||
|
const customWidth = useCustomWidth ? payload.customWidth : "";
|
||||||
const model = payload.model as string;
|
const model = payload.model as string;
|
||||||
const gpuId = payload.gpuId as string;
|
const gpuId = payload.gpuId as string;
|
||||||
const saveImageAs = payload.saveImageAs as ImageFormat;
|
const saveImageAs = payload.saveImageAs as ImageFormat;
|
||||||
const overwrite = payload.overwrite as boolean;
|
const overwrite = payload.overwrite as boolean;
|
||||||
let inputDir = (payload.imagePath.match(/(.*)[\/\\]/)?.[1] || "") as string;
|
const imagePath = decodePath(payload.imagePath);
|
||||||
let outputDir: string | undefined =
|
let inputDir = getDirectoryFromPath(imagePath);
|
||||||
savedBatchUpscaylFolderPath || (payload.outputPath as string);
|
let outputDir = decodePath(payload.outputPath);
|
||||||
if (
|
const fileNameWithExt = getFilenameFromPath(imagePath);
|
||||||
rememberOutputFolder === true &&
|
const fileName = parse(fileNameWithExt).name;
|
||||||
savedOutputPath &&
|
|
||||||
savedOutputPath?.length > 0
|
|
||||||
) {
|
|
||||||
logit("🧠 Using saved output path");
|
|
||||||
outputDir = savedOutputPath;
|
|
||||||
}
|
|
||||||
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
|
||||||
logit("Is Default Model? : ", isDefaultModel);
|
|
||||||
const fullfileName = payload.imagePath.replace(/^.*[\\\/]/, "") as string;
|
|
||||||
const fileName = parse(fullfileName).name;
|
|
||||||
const fileExt = parse(fullfileName).ext;
|
|
||||||
const useCustomWidth = payload.useCustomWidth;
|
|
||||||
const customWidth = useCustomWidth ? payload.customWidth : "";
|
|
||||||
|
|
||||||
const scale = payload.scale;
|
|
||||||
|
|
||||||
const outFile =
|
const outFile =
|
||||||
outputDir +
|
outputDir +
|
||||||
@ -71,17 +54,13 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
|||||||
"." +
|
"." +
|
||||||
saveImageAs;
|
saveImageAs;
|
||||||
|
|
||||||
|
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
||||||
|
|
||||||
// UPSCALE
|
// UPSCALE
|
||||||
if (fs.existsSync(outFile) && !overwrite) {
|
if (fs.existsSync(outFile) && !overwrite) {
|
||||||
// If already upscayled, just output that file
|
// If already upscayled, just output that file
|
||||||
logit("✅ Already upscayled at: ", outFile);
|
logit("✅ Already upscayled at: ", outFile);
|
||||||
mainWindow.webContents.send(
|
mainWindow.webContents.send(COMMAND.UPSCAYL_DONE, outFile);
|
||||||
COMMAND.UPSCAYL_DONE,
|
|
||||||
outFile.replace(
|
|
||||||
/([^/\\]+)$/i,
|
|
||||||
encodeURIComponent(outFile.match(/[^/\\]+$/i)![0]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
logit(
|
logit(
|
||||||
"✅ Upscayl Variables: ",
|
"✅ Upscayl Variables: ",
|
||||||
@ -90,18 +69,18 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
|||||||
gpuId,
|
gpuId,
|
||||||
saveImageAs,
|
saveImageAs,
|
||||||
inputDir,
|
inputDir,
|
||||||
|
fileNameWithExt,
|
||||||
outputDir,
|
outputDir,
|
||||||
fullfileName,
|
outFile,
|
||||||
fileName,
|
fileName,
|
||||||
scale,
|
scale,
|
||||||
outFile,
|
compression,
|
||||||
compression: savedCompression,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const upscayl = spawnUpscayl(
|
const upscayl = spawnUpscayl(
|
||||||
getSingleImageArguments({
|
getSingleImageArguments({
|
||||||
inputDir,
|
inputDir: decodeURIComponent(inputDir),
|
||||||
fullfileName,
|
fileNameWithExt: decodeURIComponent(fileNameWithExt),
|
||||||
outFile,
|
outFile,
|
||||||
modelsPath: isDefaultModel
|
modelsPath: isDefaultModel
|
||||||
? modelsPath
|
? modelsPath
|
||||||
@ -146,13 +125,7 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
|||||||
// Free up memory
|
// Free up memory
|
||||||
upscayl.kill();
|
upscayl.kill();
|
||||||
mainWindow.setProgressBar(-1);
|
mainWindow.setProgressBar(-1);
|
||||||
mainWindow.webContents.send(
|
mainWindow.webContents.send(COMMAND.UPSCAYL_DONE, outFile);
|
||||||
COMMAND.UPSCAYL_DONE,
|
|
||||||
outFile.replace(
|
|
||||||
/([^/\\]+)$/i,
|
|
||||||
encodeURIComponent(outFile.match(/[^/\\]+$/i)![0]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
showNotification("Upscayl", "Image upscayled successfully!");
|
showNotification("Upscayl", "Image upscayled successfully!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -40,12 +40,6 @@ export function setRememberOutputFolder(value: boolean): void {
|
|||||||
logit("💾 Updating Remember Output Folder: ", rememberOutputFolder);
|
logit("💾 Updating Remember Output Folder: ", rememberOutputFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
export let savedCompression = 0;
|
|
||||||
export function setCompression(value: number): void {
|
|
||||||
savedCompression = value;
|
|
||||||
logit("📐 Updating Compression: ", savedCompression);
|
|
||||||
}
|
|
||||||
|
|
||||||
export let stopped = false;
|
export let stopped = false;
|
||||||
export let childProcesses: {
|
export let childProcesses: {
|
||||||
process: ChildProcessWithoutNullStreams;
|
process: ChildProcessWithoutNullStreams;
|
||||||
@ -148,14 +142,7 @@ export function fetchLocalStorage(): void {
|
|||||||
setRememberOutputFolder(lastSaveOutputFolder);
|
setRememberOutputFolder(lastSaveOutputFolder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// GET IMAGE COMPRESSION (NUMBER) FROM LOCAL STORAGE
|
|
||||||
mainWindow.webContents
|
|
||||||
.executeJavaScript('localStorage.getItem("compression");', true)
|
|
||||||
.then((lastSavedCompression: string | null) => {
|
|
||||||
if (lastSavedCompression !== null) {
|
|
||||||
setCompression(parseInt(lastSavedCompression));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// GET PROCESS IMAGE (BOOLEAN) FROM LOCAL STORAGE
|
// GET PROCESS IMAGE (BOOLEAN) FROM LOCAL STORAGE
|
||||||
mainWindow.webContents
|
mainWindow.webContents
|
||||||
.executeJavaScript('localStorage.getItem("noImageProcessing");', true)
|
.executeJavaScript('localStorage.getItem("noImageProcessing");', true)
|
||||||
|
@ -5,7 +5,7 @@ const slash: string = getPlatform() === "win" ? "\\" : "/";
|
|||||||
|
|
||||||
export const getSingleImageArguments = ({
|
export const getSingleImageArguments = ({
|
||||||
inputDir,
|
inputDir,
|
||||||
fullfileName,
|
fileNameWithExt,
|
||||||
outFile,
|
outFile,
|
||||||
modelsPath,
|
modelsPath,
|
||||||
model,
|
model,
|
||||||
@ -15,7 +15,7 @@ export const getSingleImageArguments = ({
|
|||||||
customWidth,
|
customWidth,
|
||||||
}: {
|
}: {
|
||||||
inputDir: string;
|
inputDir: string;
|
||||||
fullfileName: string;
|
fileNameWithExt: string;
|
||||||
outFile: string;
|
outFile: string;
|
||||||
modelsPath: string;
|
modelsPath: string;
|
||||||
model: string;
|
model: string;
|
||||||
@ -29,7 +29,7 @@ export const getSingleImageArguments = ({
|
|||||||
return [
|
return [
|
||||||
// INPUT IMAGE
|
// INPUT IMAGE
|
||||||
"-i",
|
"-i",
|
||||||
inputDir + slash + fullfileName,
|
inputDir + slash + fileNameWithExt,
|
||||||
// OUTPUT IMAGE
|
// OUTPUT IMAGE
|
||||||
"-o",
|
"-o",
|
||||||
outFile,
|
outFile,
|
||||||
@ -109,6 +109,7 @@ export const getDoubleUpscaleSecondPassArguments = ({
|
|||||||
saveImageAs: ImageFormat;
|
saveImageAs: ImageFormat;
|
||||||
scale: string;
|
scale: string;
|
||||||
customWidth: string;
|
customWidth: string;
|
||||||
|
compression: string;
|
||||||
}) => {
|
}) => {
|
||||||
const modelScale = (parseInt(getModelScale(model)) ** 2).toString();
|
const modelScale = (parseInt(getModelScale(model)) ** 2).toString();
|
||||||
let includeScale = modelScale !== scale && !customWidth;
|
let includeScale = modelScale !== scale && !customWidth;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "upscayl",
|
"name": "upscayl",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.10.9",
|
"version": "2.11.0",
|
||||||
"productName": "Upscayl",
|
"productName": "Upscayl",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Nayam Amarshe",
|
"name": "Nayam Amarshe",
|
||||||
|
@ -10,6 +10,10 @@ export const scaleAtom = atomWithStorage<string>("scale", "4");
|
|||||||
|
|
||||||
export const batchModeAtom = atom<boolean>(false);
|
export const batchModeAtom = atom<boolean>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the last folder the user saved an image to.
|
||||||
|
* Reset to "" if rememberOutputFolder is false.
|
||||||
|
*/
|
||||||
export const savedOutputPathAtom = atomWithStorage<string | null>(
|
export const savedOutputPathAtom = atomWithStorage<string | null>(
|
||||||
"savedOutputPath",
|
"savedOutputPath",
|
||||||
null,
|
null,
|
||||||
|
@ -9,12 +9,7 @@ import { DonateButton } from "./DonateButton";
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { themeChange } from "theme-change";
|
import { themeChange } from "theme-change";
|
||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import {
|
import { customModelsPathAtom, scaleAtom } from "../../atoms/userSettingsAtom";
|
||||||
customModelsPathAtom,
|
|
||||||
noImageProcessingAtom,
|
|
||||||
overwriteAtom,
|
|
||||||
scaleAtom,
|
|
||||||
} from "../../atoms/userSettingsAtom";
|
|
||||||
import { modelsListAtom } from "../../atoms/modelsListAtom";
|
import { modelsListAtom } from "../../atoms/modelsListAtom";
|
||||||
import useLog from "../hooks/useLog";
|
import useLog from "../hooks/useLog";
|
||||||
import { CompressionInput } from "./CompressionInput";
|
import { CompressionInput } from "./CompressionInput";
|
||||||
|
@ -334,7 +334,7 @@ function LeftPaneImageSteps({
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
className="btn btn-accent"
|
className="btn btn-secondary"
|
||||||
onClick={
|
onClick={
|
||||||
progress.length > 0 || !outputPath
|
progress.length > 0 || !outputPath
|
||||||
? () =>
|
? () =>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
import COMMAND from "../../common/commands";
|
import COMMAND from "../../common/commands";
|
||||||
import { ReactCompareSlider } from "react-compare-slider";
|
import { ReactCompareSlider } from "react-compare-slider";
|
||||||
import Header from "../components/Header";
|
import Header from "../components/Header";
|
||||||
@ -40,16 +40,13 @@ import {
|
|||||||
import { NewsModal } from "@/components/NewsModal";
|
import { NewsModal } from "@/components/NewsModal";
|
||||||
import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom";
|
import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom";
|
||||||
import matter from "gray-matter";
|
import matter from "gray-matter";
|
||||||
import {
|
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||||
ChevronLeftIcon,
|
|
||||||
ChevronRightIcon,
|
|
||||||
PanelLeftCloseIcon,
|
|
||||||
PanelRightCloseIcon,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { ToastAction } from "@/components/ui/toast";
|
import { ToastAction } from "@/components/ui/toast";
|
||||||
import Logo from "@/components/icons/Logo";
|
import Logo from "@/components/icons/Logo";
|
||||||
|
import { sanitizePath } from "@common/sanitize-path";
|
||||||
|
import getDirectoryFromPath from "@common/get-directory-from-path";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const allowedFileTypes = ["png", "jpg", "jpeg", "webp"];
|
const allowedFileTypes = ["png", "jpg", "jpeg", "webp"];
|
||||||
@ -103,6 +100,16 @@ const Home = () => {
|
|||||||
const { logit } = useLog();
|
const { logit } = useLog();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const sanitizedImagePath = useMemo(
|
||||||
|
() => sanitizePath(imagePath),
|
||||||
|
[imagePath],
|
||||||
|
);
|
||||||
|
|
||||||
|
const sanitizedUpscaledImagePath = useMemo(
|
||||||
|
() => sanitizePath(upscaledImagePath),
|
||||||
|
[upscaledImagePath],
|
||||||
|
);
|
||||||
|
|
||||||
const handleMouseMoveCompare = (e: React.MouseEvent) => {
|
const handleMouseMoveCompare = (e: React.MouseEvent) => {
|
||||||
const { left, top, height, width } =
|
const { left, top, height, width } =
|
||||||
e.currentTarget.getBoundingClientRect();
|
e.currentTarget.getBoundingClientRect();
|
||||||
@ -129,7 +136,7 @@ const Home = () => {
|
|||||||
if (data.includes("Invalid GPU")) {
|
if (data.includes("Invalid GPU")) {
|
||||||
toast({
|
toast({
|
||||||
title: "GPU Error",
|
title: "GPU Error",
|
||||||
description: `GPU error occurred. Please read the wiki for troubleshooting! ${data})`,
|
description: `Ran into an issue with the GPU. Please read the wiki for troubleshooting! (${data})`,
|
||||||
action: (
|
action: (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<ToastAction
|
<ToastAction
|
||||||
@ -345,7 +352,7 @@ const Home = () => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// * HANDLERS
|
// HANDLERS
|
||||||
const resetImagePaths = () => {
|
const resetImagePaths = () => {
|
||||||
logit("🔄 Resetting image paths");
|
logit("🔄 Resetting image paths");
|
||||||
setDimensions({
|
setDimensions({
|
||||||
@ -393,7 +400,7 @@ const Home = () => {
|
|||||||
if (path === null) return;
|
if (path === null) return;
|
||||||
logit("🖼 Selected Image Path: ", path);
|
logit("🖼 Selected Image Path: ", path);
|
||||||
setImagePath(path);
|
setImagePath(path);
|
||||||
var dirname = path.match(/(.*)[\/\\]/)[1] || "";
|
var dirname = getDirectoryFromPath(path);
|
||||||
logit("📁 Selected Image Directory: ", dirname);
|
logit("📁 Selected Image Directory: ", dirname);
|
||||||
if (!featureFlags.APP_STORE_BUILD) {
|
if (!featureFlags.APP_STORE_BUILD) {
|
||||||
if (!rememberOutputFolder) {
|
if (!rememberOutputFolder) {
|
||||||
@ -478,7 +485,7 @@ const Home = () => {
|
|||||||
} else {
|
} else {
|
||||||
logit("🖼 Setting image path: ", filePath);
|
logit("🖼 Setting image path: ", filePath);
|
||||||
setImagePath(filePath);
|
setImagePath(filePath);
|
||||||
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
|
var dirname = getDirectoryFromPath(filePath);
|
||||||
logit("🗂 Setting output path: ", dirname);
|
logit("🗂 Setting output path: ", dirname);
|
||||||
if (!featureFlags.APP_STORE_BUILD) {
|
if (!featureFlags.APP_STORE_BUILD) {
|
||||||
if (!rememberOutputFolder) {
|
if (!rememberOutputFolder) {
|
||||||
@ -506,7 +513,7 @@ const Home = () => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setImagePath(filePath);
|
setImagePath(filePath);
|
||||||
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
|
var dirname = getDirectoryFromPath(filePath);
|
||||||
logit("🗂 Setting output path: ", dirname);
|
logit("🗂 Setting output path: ", dirname);
|
||||||
if (!rememberOutputFolder) {
|
if (!rememberOutputFolder) {
|
||||||
setOutputPath(dirname);
|
setOutputPath(dirname);
|
||||||
@ -748,7 +755,7 @@ const Home = () => {
|
|||||||
hideZoomOptions={true}
|
hideZoomOptions={true}
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src={"file:///" + imagePath}
|
src={"file:///" + sanitizePath(imagePath)}
|
||||||
onLoad={(e: any) => {
|
onLoad={(e: any) => {
|
||||||
setDimensions({
|
setDimensions({
|
||||||
width: e.target.naturalWidth,
|
width: e.target.naturalWidth,
|
||||||
@ -851,7 +858,7 @@ const Home = () => {
|
|||||||
|
|
||||||
<img
|
<img
|
||||||
/* USE REGEX TO GET THE FILENAME AND ENCODE IT INTO PROPER FORM IN ORDER TO AVOID ERRORS DUE TO SPECIAL CHARACTERS */
|
/* USE REGEX TO GET THE FILENAME AND ENCODE IT INTO PROPER FORM IN ORDER TO AVOID ERRORS DUE TO SPECIAL CHARACTERS */
|
||||||
src={"file:///" + imagePath}
|
src={"file:///" + sanitizedImagePath}
|
||||||
alt="Original"
|
alt="Original"
|
||||||
onMouseMove={handleMouseMove}
|
onMouseMove={handleMouseMove}
|
||||||
style={{
|
style={{
|
||||||
@ -870,7 +877,7 @@ const Home = () => {
|
|||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
/* USE REGEX TO GET THE FILENAME AND ENCODE IT INTO PROPER FORM IN ORDER TO AVOID ERRORS DUE TO SPECIAL CHARACTERS */
|
/* USE REGEX TO GET THE FILENAME AND ENCODE IT INTO PROPER FORM IN ORDER TO AVOID ERRORS DUE TO SPECIAL CHARACTERS */
|
||||||
src={"file:///" + upscaledImagePath}
|
src={"file:///" + sanitizedUpscaledImagePath}
|
||||||
alt="Upscayl"
|
alt="Upscayl"
|
||||||
style={{
|
style={{
|
||||||
objectFit: "contain",
|
objectFit: "contain",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user