1
0
mirror of https://github.com/upscayl/upscayl.git synced 2025-01-31 04:03:51 +01:00

Add no process toggle

This commit is contained in:
Nayam Amarshe 2023-09-19 00:00:43 +05:30
parent 58172d6359
commit 7533867de8
10 changed files with 226 additions and 96 deletions

View File

@ -5,6 +5,7 @@ import {
compression,
customModelsFolderPath,
folderPath,
noImageProcessing,
outputFolderPath,
overwrite,
saveOutputFolder,
@ -50,21 +51,23 @@ const imageUpscayl = async (event, payload) => {
const fileName = parse(fullfileName).name;
const fileExt = parse(fullfileName).ext;
let scale = "4";
let initialScale = "4";
if (model.includes("x2")) {
scale = "2";
initialScale = "2";
} else if (model.includes("x3")) {
scale = "3";
initialScale = "3";
} else {
scale = "4";
initialScale = "4";
}
const desiredScale = payload.scale;
const outFile =
outputDir +
slash +
fileName +
"_upscayl_" +
payload.scale +
desiredScale +
"x_" +
model +
"." +
@ -82,6 +85,19 @@ const imageUpscayl = async (event, payload) => {
)
);
} else {
logit("✅ Upscayl Variables: ", {
model,
gpuId,
saveImageAs,
inputDir,
outputDir,
fullfileName,
fileName,
initialScale: initialScale,
desiredScale,
outFile,
compression,
});
const upscayl = spawnUpscayl(
"realesrgan",
getSingleImageArguments(
@ -90,7 +106,7 @@ const imageUpscayl = async (event, payload) => {
outFile,
isDefaultModel ? modelsPath : customModelsFolderPath ?? modelsPath,
model,
scale,
initialScale,
gpuId,
"png"
),
@ -130,20 +146,40 @@ const imageUpscayl = async (event, payload) => {
if (!failed && !stopped) {
logit("💯 Done upscaling");
logit("♻ Scaling and converting now...");
mainWindow.webContents.send(COMMAND.SCALING_AND_CONVERTING);
// Free up memory
upscayl.kill();
try {
if (saveImageAs !== "png" && scale !== "4" && compression !== 0) {
if (noImageProcessing === false) {
mainWindow.webContents.send(COMMAND.SCALING_AND_CONVERTING);
// Free up memory
upscayl.kill();
try {
await convertAndScale(
inputDir + slash + fullfileName,
isAlpha ? outFile + ".png" : outFile,
outFile,
payload.scale,
desiredScale,
saveImageAs,
onError
);
mainWindow.setProgressBar(-1);
mainWindow.webContents.send(
COMMAND.UPSCAYL_DONE,
outFile.replace(
/([^/\\]+)$/i,
encodeURIComponent(outFile.match(/[^/\\]+$/i)![0])
)
);
} catch (error) {
logit(
"❌ Error processing (scaling and converting) the image. Please report this error on GitHub.",
error
);
upscayl.kill();
mainWindow.webContents.send(
COMMAND.UPSCAYL_ERROR,
"Error processing (scaling and converting) the image. Please report this error on Upscayl GitHub Issues page."
);
}
} else {
logit("🚫 Skipping scaling and converting");
mainWindow.setProgressBar(-1);
mainWindow.webContents.send(
COMMAND.UPSCAYL_DONE,
@ -152,16 +188,6 @@ const imageUpscayl = async (event, payload) => {
encodeURIComponent(outFile.match(/[^/\\]+$/i)![0])
)
);
} catch (error) {
logit(
"❌ Error processing (scaling and converting) the image. Please report this error on GitHub.",
error
);
upscayl.kill();
mainWindow.webContents.send(
COMMAND.UPSCAYL_ERROR,
"Error processing (scaling and converting) the image. Please report this error on Upscayl GitHub Issues page."
);
}
}
};

View File

@ -11,6 +11,7 @@ import {
setOverwrite,
setCompression,
setSaveOutputFolder,
fetchLocalStorage,
} from "./utils/config-variables";
import electronIsDev from "electron-is-dev";
import { format } from "url";
@ -55,65 +56,7 @@ const createMainWindow = () => {
mainWindow.show();
});
// GET LAST IMAGE PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastImagePath");', true)
.then((lastImagePath: string | null) => {
if (lastImagePath && lastImagePath.length > 0) {
setImagePath(lastImagePath);
}
});
// GET LAST FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastFolderPath");', true)
.then((lastFolderPath: string | null) => {
if (lastFolderPath && lastFolderPath.length > 0) {
setFolderPath(lastFolderPath);
}
});
// GET LAST CUSTOM MODELS FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript(
'localStorage.getItem("lastCustomModelsFolderPath");',
true
)
.then((lastCustomModelsFolderPath: string | null) => {
if (lastCustomModelsFolderPath && lastCustomModelsFolderPath.length > 0) {
setCustomModelsFolderPath(lastCustomModelsFolderPath);
}
});
// GET LAST CUSTOM MODELS FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastOutputFolderPath");', true)
.then((lastOutputFolderPath: string | null) => {
if (lastOutputFolderPath && lastOutputFolderPath.length > 0) {
setOutputFolderPath(lastOutputFolderPath);
}
});
// GET LAST SAVE OUTPUT FOLDER (BOOLEAN) TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("rememberOutputFolder");', true)
.then((lastSaveOutputFolder: boolean | null) => {
if (lastSaveOutputFolder !== null) {
setSaveOutputFolder(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 OVERWRITE (BOOLEAN) FROM LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("overwrite");', true)
.then((lastSavedOverwrite: string | null) => {
if (lastSavedOverwrite !== null) {
setOverwrite(lastSavedOverwrite === "true");
}
});
fetchLocalStorage();
mainWindow.webContents.send(COMMAND.OS, getPlatform());

View File

@ -1,4 +1,6 @@
import { ChildProcessWithoutNullStreams } from "child_process";
import { getMainWindow } from "../main-window";
import logit from "./logit";
export let imagePath: string | undefined = "";
export let folderPath: string | undefined = undefined;
@ -12,38 +14,47 @@ export let childProcesses: {
process: ChildProcessWithoutNullStreams;
kill: () => boolean;
}[] = [];
export let noImageProcessing: boolean = false;
export function setImagePath(value: string | undefined): void {
imagePath = value;
logit("🖼️ Updating Image Path: ", imagePath);
}
export function setFolderPath(value: string | undefined): void {
folderPath = value;
logit("📁 Updating Folder Path: ", folderPath);
}
export function setCustomModelsFolderPath(value: string | undefined): void {
customModelsFolderPath = value;
logit("📁 Updating Custom Models Folder Path: ", customModelsFolderPath);
}
// SETTERS
export function setOutputFolderPath(value: string | undefined): void {
outputFolderPath = value;
logit("📁 Updating Output Folder Path: ", outputFolderPath);
}
export function setSaveOutputFolder(value: boolean): void {
saveOutputFolder = value;
logit("💾 Updating Save Output Folder: ", saveOutputFolder);
}
export function setCompression(value: number): void {
compression = value;
logit("📐 Updating Compression: ", compression);
}
export function setOverwrite(value: boolean): void {
overwrite = value;
logit("📝 Updating Overwrite: ", overwrite);
}
export function setStopped(value: boolean): void {
stopped = value;
logit("🛑 Updating Stopped: ", stopped);
}
export function setChildProcesses(value: {
@ -51,4 +62,84 @@ export function setChildProcesses(value: {
kill: () => boolean;
}): void {
childProcesses.push(value);
logit("👶 Updating Child Processes: ", childProcesses);
}
export function setNoImageProcessing(value: boolean): void {
noImageProcessing = value;
logit("🖼️ Updating No Image Processing: ", noImageProcessing);
}
// LOCAL STORAGE
export function fetchLocalStorage(): void {
const mainWindow = getMainWindow();
if (!mainWindow) return;
// GET LAST IMAGE PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastImagePath");', true)
.then((lastImagePath: string | null) => {
if (lastImagePath && lastImagePath.length > 0) {
setImagePath(lastImagePath);
}
});
// GET LAST FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastFolderPath");', true)
.then((lastFolderPath: string | null) => {
if (lastFolderPath && lastFolderPath.length > 0) {
setFolderPath(lastFolderPath);
}
});
// GET LAST CUSTOM MODELS FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript(
'localStorage.getItem("lastCustomModelsFolderPath");',
true
)
.then((lastCustomModelsFolderPath: string | null) => {
if (lastCustomModelsFolderPath && lastCustomModelsFolderPath.length > 0) {
setCustomModelsFolderPath(lastCustomModelsFolderPath);
}
});
// GET LAST CUSTOM MODELS FOLDER PATH TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("lastOutputFolderPath");', true)
.then((lastOutputFolderPath: string | null) => {
if (lastOutputFolderPath && lastOutputFolderPath.length > 0) {
setOutputFolderPath(lastOutputFolderPath);
}
});
// GET LAST SAVE OUTPUT FOLDER (BOOLEAN) TO LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("rememberOutputFolder");', true)
.then((lastSaveOutputFolder: boolean | null) => {
if (lastSaveOutputFolder !== null) {
setSaveOutputFolder(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 OVERWRITE (BOOLEAN) FROM LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("overwrite");', true)
.then((lastSavedOverwrite: string | null) => {
if (lastSavedOverwrite !== null) {
setOverwrite(lastSavedOverwrite === "true");
}
});
// GET PROCESS IMAGE (BOOLEAN) FROM LOCAL STORAGE
mainWindow.webContents
.executeJavaScript('localStorage.getItem("noImageProcessing");', true)
.then((lastSaved: string | null) => {
if (lastSaved !== null) {
setNoImageProcessing(lastSaved === "true");
}
});
}

View File

@ -18,20 +18,33 @@ const convertAndScale = async (
if (!mainWindow || !originalImage) {
throw new Error("Could not grab the original image!");
}
// Resize the image to the scale
const newImage = sharp(upscaledImagePath, {
limitInputPixels: false,
}).resize(
originalImage.width && originalImage.width * parseInt(scale),
originalImage.height && originalImage.height * parseInt(scale)
originalImage.height && originalImage.height * parseInt(scale),
{
fit: "outside",
}
);
// Convert compression percentage (0-100) to compressionLevel (0-9)
const compressionLevel = Math.round((compression / 100) * 9);
logit("Compression: ", compression);
logit("📐 Processing Image: ", {
originalWidth: originalImage.width,
originalHeight: originalImage.height,
scale,
saveImageAs,
compressionPercentage: compression,
compressionLevel,
});
const buffer = await newImage.toBuffer();
try {
logit("");
await sharp(buffer, {
limitInputPixels: false,
})

View File

View File

@ -19,3 +19,8 @@ export const dontShowCloudModalAtom = atomWithStorage<boolean>(
"dontShowCloudModal",
false
);
export const noImageProcessingAtom = atomWithStorage<boolean>(
"noImageProcessing",
false
);

View File

@ -6,7 +6,11 @@ type LogAreaProps = {
logData: string[];
};
export function LogArea({ copyOnClickHandler, isCopied, logData }) {
export function LogArea({
copyOnClickHandler,
isCopied,
logData,
}: LogAreaProps) {
return (
<div className="relative flex flex-col gap-2">
<button

View File

@ -1,11 +1,11 @@
import React, { useEffect } from "react";
type ToggleOverwriteProps = {
type OverwriteToggleProps = {
overwrite: boolean;
setOverwrite: (arg: any) => void;
};
const ToggleOverwrite = ({ overwrite, setOverwrite }: ToggleOverwriteProps) => {
const OverwriteToggle = ({ overwrite, setOverwrite }: OverwriteToggleProps) => {
useEffect(() => {
if (!localStorage.getItem("overwrite")) {
localStorage.setItem("overwrite", JSON.stringify(overwrite));
@ -44,4 +44,4 @@ const ToggleOverwrite = ({ overwrite, setOverwrite }: ToggleOverwriteProps) => {
);
};
export default ToggleOverwrite;
export default OverwriteToggle;

View File

@ -0,0 +1,31 @@
type ProcessImageToggleProps = {
noImageProcessing: boolean;
setNoImageProcessing: (arg: any) => void;
};
const ProcessImageToggle = ({
noImageProcessing,
setNoImageProcessing,
}: ProcessImageToggleProps) => {
return (
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">DON'T POST-PROCESS IMAGE</p>
<p className="text-xs text-base-content/80">
If enabled, the image will not be converted or scaled or post-processed.
This will output the original AI upscaling result as-is (Restart
Required)
</p>
<input
type="checkbox"
className="toggle"
checked={noImageProcessing}
onClick={() => {
setNoImageProcessing(!noImageProcessing);
alert("Please restart Upscayl for the changes to take effect.");
}}
/>
</div>
);
};
export default ProcessImageToggle;

View File

@ -9,13 +9,18 @@ import { DonateButton } from "./DonateButton";
import React, { useEffect, useState } from "react";
import { themeChange } from "theme-change";
import { useAtom, useAtomValue } from "jotai";
import { customModelsPathAtom, scaleAtom } from "../../atoms/userSettingsAtom";
import {
customModelsPathAtom,
noImageProcessingAtom,
scaleAtom,
} from "../../atoms/userSettingsAtom";
import { modelsListAtom } from "../../atoms/modelsListAtom";
import useLog from "../hooks/useLog";
import { CompressionInput } from "./CompressionInput";
import ToggleOverwrite from "./ToggleOverwrite";
import OverwriteToggle from "./OverwriteToggle";
import { UpscaylCloudModal } from "../UpscaylCloudModal";
import { ResetSettings } from "./ResetSettings";
import ProcessImageToggle from "./ProcessImageToggle";
interface IProps {
batchMode: boolean;
@ -66,6 +71,9 @@ function SettingsTab({
const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom);
const modelOptions = useAtomValue(modelsListAtom);
const [scale, setScale] = useAtom(scaleAtom);
const [noImageProcessing, setNoImageProcessing] = useAtom(
noImageProcessingAtom
);
const { logit } = useLog();
@ -191,20 +199,29 @@ function SettingsTab({
setExportType={setExportType}
/>
{/* IMAGE SCALE */}
<ImageScaleSelect scale={scale} setScale={setScale} />
<CompressionInput
compression={compression}
handleCompressionChange={handleCompressionChange}
<ProcessImageToggle
noImageProcessing={noImageProcessing}
setNoImageProcessing={setNoImageProcessing}
/>
{!noImageProcessing && (
<>
{/* IMAGE SCALE */}
<ImageScaleSelect scale={scale} setScale={setScale} />
<CompressionInput
compression={compression}
handleCompressionChange={handleCompressionChange}
/>
</>
)}
<SaveOutputFolderToggle
rememberOutputFolder={rememberOutputFolder}
setRememberOutputFolder={setRememberOutputFolder}
/>
<ToggleOverwrite overwrite={overwrite} setOverwrite={setOverwrite} />
<OverwriteToggle overwrite={overwrite} setOverwrite={setOverwrite} />
{/* GPU ID INPUT */}
<GpuIdInput gpuId={gpuId} handleGpuIdChange={handleGpuIdChange} />