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

View File

@ -11,6 +11,7 @@ import {
setOverwrite, setOverwrite,
setCompression, setCompression,
setSaveOutputFolder, setSaveOutputFolder,
fetchLocalStorage,
} from "./utils/config-variables"; } from "./utils/config-variables";
import electronIsDev from "electron-is-dev"; import electronIsDev from "electron-is-dev";
import { format } from "url"; import { format } from "url";
@ -55,65 +56,7 @@ const createMainWindow = () => {
mainWindow.show(); mainWindow.show();
}); });
// GET LAST IMAGE PATH TO LOCAL STORAGE fetchLocalStorage();
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");
}
});
mainWindow.webContents.send(COMMAND.OS, getPlatform()); mainWindow.webContents.send(COMMAND.OS, getPlatform());

View File

@ -1,4 +1,6 @@
import { ChildProcessWithoutNullStreams } from "child_process"; import { ChildProcessWithoutNullStreams } from "child_process";
import { getMainWindow } from "../main-window";
import logit from "./logit";
export let imagePath: string | undefined = ""; export let imagePath: string | undefined = "";
export let folderPath: string | undefined = undefined; export let folderPath: string | undefined = undefined;
@ -12,38 +14,47 @@ export let childProcesses: {
process: ChildProcessWithoutNullStreams; process: ChildProcessWithoutNullStreams;
kill: () => boolean; kill: () => boolean;
}[] = []; }[] = [];
export let noImageProcessing: boolean = false;
export function setImagePath(value: string | undefined): void { export function setImagePath(value: string | undefined): void {
imagePath = value; imagePath = value;
logit("🖼️ Updating Image Path: ", imagePath);
} }
export function setFolderPath(value: string | undefined): void { export function setFolderPath(value: string | undefined): void {
folderPath = value; folderPath = value;
logit("📁 Updating Folder Path: ", folderPath);
} }
export function setCustomModelsFolderPath(value: string | undefined): void { export function setCustomModelsFolderPath(value: string | undefined): void {
customModelsFolderPath = value; customModelsFolderPath = value;
logit("📁 Updating Custom Models Folder Path: ", customModelsFolderPath);
} }
// SETTERS // SETTERS
export function setOutputFolderPath(value: string | undefined): void { export function setOutputFolderPath(value: string | undefined): void {
outputFolderPath = value; outputFolderPath = value;
logit("📁 Updating Output Folder Path: ", outputFolderPath);
} }
export function setSaveOutputFolder(value: boolean): void { export function setSaveOutputFolder(value: boolean): void {
saveOutputFolder = value; saveOutputFolder = value;
logit("💾 Updating Save Output Folder: ", saveOutputFolder);
} }
export function setCompression(value: number): void { export function setCompression(value: number): void {
compression = value; compression = value;
logit("📐 Updating Compression: ", compression);
} }
export function setOverwrite(value: boolean): void { export function setOverwrite(value: boolean): void {
overwrite = value; overwrite = value;
logit("📝 Updating Overwrite: ", overwrite);
} }
export function setStopped(value: boolean): void { export function setStopped(value: boolean): void {
stopped = value; stopped = value;
logit("🛑 Updating Stopped: ", stopped);
} }
export function setChildProcesses(value: { export function setChildProcesses(value: {
@ -51,4 +62,84 @@ export function setChildProcesses(value: {
kill: () => boolean; kill: () => boolean;
}): void { }): void {
childProcesses.push(value); 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) { if (!mainWindow || !originalImage) {
throw new Error("Could not grab the original image!"); throw new Error("Could not grab the original image!");
} }
// Resize the image to the scale // Resize the image to the scale
const newImage = sharp(upscaledImagePath, { const newImage = sharp(upscaledImagePath, {
limitInputPixels: false, limitInputPixels: false,
}).resize( }).resize(
originalImage.width && originalImage.width * parseInt(scale), 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) // Convert compression percentage (0-100) to compressionLevel (0-9)
const compressionLevel = Math.round((compression / 100) * 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(); const buffer = await newImage.toBuffer();
try { try {
logit("");
await sharp(buffer, { await sharp(buffer, {
limitInputPixels: false, limitInputPixels: false,
}) })

View File

View File

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

View File

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

View File

@ -1,11 +1,11 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
type ToggleOverwriteProps = { type OverwriteToggleProps = {
overwrite: boolean; overwrite: boolean;
setOverwrite: (arg: any) => void; setOverwrite: (arg: any) => void;
}; };
const ToggleOverwrite = ({ overwrite, setOverwrite }: ToggleOverwriteProps) => { const OverwriteToggle = ({ overwrite, setOverwrite }: OverwriteToggleProps) => {
useEffect(() => { useEffect(() => {
if (!localStorage.getItem("overwrite")) { if (!localStorage.getItem("overwrite")) {
localStorage.setItem("overwrite", JSON.stringify(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 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 { customModelsPathAtom, scaleAtom } from "../../atoms/userSettingsAtom"; import {
customModelsPathAtom,
noImageProcessingAtom,
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";
import ToggleOverwrite from "./ToggleOverwrite"; import OverwriteToggle from "./OverwriteToggle";
import { UpscaylCloudModal } from "../UpscaylCloudModal"; import { UpscaylCloudModal } from "../UpscaylCloudModal";
import { ResetSettings } from "./ResetSettings"; import { ResetSettings } from "./ResetSettings";
import ProcessImageToggle from "./ProcessImageToggle";
interface IProps { interface IProps {
batchMode: boolean; batchMode: boolean;
@ -66,6 +71,9 @@ function SettingsTab({
const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom); const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom);
const modelOptions = useAtomValue(modelsListAtom); const modelOptions = useAtomValue(modelsListAtom);
const [scale, setScale] = useAtom(scaleAtom); const [scale, setScale] = useAtom(scaleAtom);
const [noImageProcessing, setNoImageProcessing] = useAtom(
noImageProcessingAtom
);
const { logit } = useLog(); const { logit } = useLog();
@ -191,6 +199,13 @@ function SettingsTab({
setExportType={setExportType} setExportType={setExportType}
/> />
<ProcessImageToggle
noImageProcessing={noImageProcessing}
setNoImageProcessing={setNoImageProcessing}
/>
{!noImageProcessing && (
<>
{/* IMAGE SCALE */} {/* IMAGE SCALE */}
<ImageScaleSelect scale={scale} setScale={setScale} /> <ImageScaleSelect scale={scale} setScale={setScale} />
@ -198,13 +213,15 @@ function SettingsTab({
compression={compression} compression={compression}
handleCompressionChange={handleCompressionChange} handleCompressionChange={handleCompressionChange}
/> />
</>
)}
<SaveOutputFolderToggle <SaveOutputFolderToggle
rememberOutputFolder={rememberOutputFolder} rememberOutputFolder={rememberOutputFolder}
setRememberOutputFolder={setRememberOutputFolder} setRememberOutputFolder={setRememberOutputFolder}
/> />
<ToggleOverwrite overwrite={overwrite} setOverwrite={setOverwrite} /> <OverwriteToggle overwrite={overwrite} setOverwrite={setOverwrite} />
{/* GPU ID INPUT */} {/* GPU ID INPUT */}
<GpuIdInput gpuId={gpuId} handleGpuIdChange={handleGpuIdChange} /> <GpuIdInput gpuId={gpuId} handleGpuIdChange={handleGpuIdChange} />