diff --git a/common/types/types.d.ts b/common/types/types.d.ts index 79c18a1..464d0d9 100644 --- a/common/types/types.d.ts +++ b/common/types/types.d.ts @@ -8,6 +8,8 @@ export type ImageUpscaylPayload = { overwrite: boolean; compression: string; noImageProcessing: boolean; + customWidth: string; + useCustomWidth: boolean; }; export type DoubleUpscaylPayload = { @@ -19,6 +21,8 @@ export type DoubleUpscaylPayload = { saveImageAs: string; compression: string; noImageProcessing: boolean; + customWidth: string; + useCustomWidth: boolean; }; export type BatchUpscaylPayload = { @@ -30,4 +34,6 @@ export type BatchUpscaylPayload = { scale: string; compression: string; noImageProcessing: boolean; + customWidth: string; + useCustomWidth: boolean; }; diff --git a/electron/commands/batch-upscayl.ts b/electron/commands/batch-upscayl.ts index bd2864f..9e5c70a 100644 --- a/electron/commands/batch-upscayl.ts +++ b/electron/commands/batch-upscayl.ts @@ -3,14 +3,12 @@ import { getMainWindow } from "../main-window"; import { childProcesses, savedCustomModelsPath, - customWidth, noImageProcessing, rememberOutputFolder, setCompression, setNoImageProcessing, setStopped, stopped, - useCustomWidth, } from "../utils/config-variables"; import logit from "../utils/logit"; import { spawnUpscayl } from "../utils/spawn-upscayl"; @@ -20,8 +18,6 @@ import { modelsPath } from "../utils/get-resource-paths"; import COMMAND from "../../common/commands"; import { BatchUpscaylPayload } from "../../common/types/types"; import { ImageFormat } from "../utils/types"; -import getModelScale from "../../common/check-model-scale"; -import removeFileExtension from "../utils/remove-file-extension"; import showNotification from "../utils/show-notification"; import { DEFAULT_MODELS } from "../../common/models-list"; @@ -47,8 +43,11 @@ const batchUpscayl = async (event, payload: BatchUpscaylPayload) => { const isDefaultModel = DEFAULT_MODELS.includes(model); const scale = payload.scale; + const customWidth = payload.customWidth; + const useCustomWidth = payload.useCustomWidth; + + const outputFolderName = `upscayl_${saveImageAs}_${model}_${scale ? scale : ""}${useCustomWidth ? "px" : "x"}`; - const outputFolderName = `upscayl_${saveImageAs}_${model}_${scale}${useCustomWidth ? "px" : "x"}`; outputFolderPath += slash + outputFolderName; if (!fs.existsSync(outputFolderPath)) { fs.mkdirSync(outputFolderPath, { recursive: true }); @@ -78,6 +77,7 @@ const batchUpscayl = async (event, payload: BatchUpscaylPayload) => { gpuId, saveImageAs, scale, + customWidth, }), logit, ); diff --git a/electron/commands/double-upscayl.ts b/electron/commands/double-upscayl.ts index e3703e7..9549a2b 100644 --- a/electron/commands/double-upscayl.ts +++ b/electron/commands/double-upscayl.ts @@ -3,8 +3,6 @@ import { getMainWindow } from "../main-window"; import { childProcesses, savedCustomModelsPath, - customWidth, - savedBatchUpscaylFolderPath, noImageProcessing, savedOutputPath, rememberOutputFolder, @@ -12,7 +10,6 @@ import { setNoImageProcessing, setStopped, stopped, - useCustomWidth, } from "../utils/config-variables"; import slash from "../utils/slash"; import { spawnUpscayl } from "../utils/spawn-upscayl"; @@ -25,9 +22,7 @@ import logit from "../utils/logit"; import COMMAND from "../../common/commands"; import { DoubleUpscaylPayload } from "../../common/types/types"; import { ImageFormat } from "../utils/types"; -import getModelScale from "../../common/check-model-scale"; import showNotification from "../utils/show-notification"; -import { unlinkSync } from "fs"; import { DEFAULT_MODELS } from "../../common/models-list"; const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => { @@ -56,13 +51,15 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => { const fileName = parse(fullfileName).name; const scale = parseInt(payload.scale) * parseInt(payload.scale); + const customWidth = payload.customWidth; + const useCustomWidth = payload.useCustomWidth; const outFile = outputDir + slash + fileName + "_upscayl_" + - scale + + (scale ? scale : "") + (useCustomWidth ? "px_" : "x_") + model + "." + @@ -186,6 +183,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => { gpuId, saveImageAs, scale: scale.toString(), + customWidth, }), logit, ); diff --git a/electron/commands/image-upscayl.ts b/electron/commands/image-upscayl.ts index 54c72d2..29c4530 100644 --- a/electron/commands/image-upscayl.ts +++ b/electron/commands/image-upscayl.ts @@ -4,7 +4,6 @@ import COMMAND from "../../common/commands"; import { savedCompression, savedCustomModelsPath, - customWidth, savedBatchUpscaylFolderPath, noImageProcessing, savedOutputPath, @@ -14,7 +13,6 @@ import { setNoImageProcessing, setStopped, stopped, - useCustomWidth, } from "../utils/config-variables"; import { getSingleImageArguments } from "../utils/get-arguments"; import logit from "../utils/logit"; @@ -60,6 +58,9 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => { const fullfileName = payload.imagePath.replace(/^.*[\\\/]/, "") as string; const fileName = parse(fullfileName).name; const fileExt = parse(fullfileName).ext; + const useCustomWidth = payload.useCustomWidth; + const customWidth = payload.customWidth; + const desiredScale = useCustomWidth ? customWidth || payload.scale : payload.scale; @@ -115,6 +116,7 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => { scale: desiredScale, gpuId, saveImageAs, + customWidth, }), logit, ); diff --git a/electron/utils/config-variables.ts b/electron/utils/config-variables.ts index a56fb12..a6c74e6 100644 --- a/electron/utils/config-variables.ts +++ b/electron/utils/config-variables.ts @@ -64,17 +64,17 @@ export function setTurnOffNotifications(value: boolean): void { logit("🔕 Updating Turn Off Notifications: ", turnOffNotifications); } -export let customWidth: string | null = null; -export function setCustomWidth(value: string | null): void { - customWidth = value; - logit("📏 Updating Custom Width: ", customWidth); -} +// export let customWidth: string | null = null; +// export function setCustomWidth(value: string | null): void { +// customWidth = value; +// logit("📏 Updating Custom Width: ", customWidth); +// } -export let useCustomWidth: boolean = false; -export function setUseCustomWidth(value: boolean): void { - useCustomWidth = value; - logit("📏 Updating Use Custom Width: ", useCustomWidth); -} +// export let useCustomWidth: boolean = false; +// export function setUseCustomWidth(value: boolean): void { +// useCustomWidth = value; +// logit("📏 Updating Use Custom Width: ", useCustomWidth); +// } // SETTERS @@ -174,21 +174,21 @@ export function fetchLocalStorage(): void { } }); - // GET CUSTOM WIDTH (STRING) FROM LOCAL STORAGE - mainWindow.webContents - .executeJavaScript('localStorage.getItem("customWidth");', true) - .then((lastSaved: string | null) => { - if (lastSaved !== null) { - setCustomWidth(lastSaved); - } - }); + // // GET CUSTOM WIDTH (STRING) FROM LOCAL STORAGE + // mainWindow.webContents + // .executeJavaScript('localStorage.getItem("customWidth");', true) + // .then((lastSaved: string | null) => { + // if (lastSaved !== null) { + // setCustomWidth(lastSaved); + // } + // }); - // GET USE CUSTOM WIDTH (BOOLEAN) FROM LOCAL STORAGE - mainWindow.webContents - .executeJavaScript('localStorage.getItem("useCustomWidth");', true) - .then((lastSaved: string | null) => { - if (lastSaved !== null) { - setUseCustomWidth(lastSaved === "true"); - } - }); + // // GET USE CUSTOM WIDTH (BOOLEAN) FROM LOCAL STORAGE + // mainWindow.webContents + // .executeJavaScript('localStorage.getItem("useCustomWidth");', true) + // .then((lastSaved: string | null) => { + // if (lastSaved !== null) { + // setUseCustomWidth(lastSaved === "true"); + // } + // }); } diff --git a/electron/utils/get-arguments.ts b/electron/utils/get-arguments.ts index e4dce09..002a1b6 100644 --- a/electron/utils/get-arguments.ts +++ b/electron/utils/get-arguments.ts @@ -11,6 +11,7 @@ export const getSingleImageArguments = ({ scale, gpuId, saveImageAs, + customWidth, }: { inputDir: string; fullfileName: string; @@ -20,6 +21,7 @@ export const getSingleImageArguments = ({ scale: any; gpuId: string; saveImageAs: ImageFormat; + customWidth: string; }) => { return [ "-i", @@ -36,6 +38,7 @@ export const getSingleImageArguments = ({ gpuId ? gpuId : "", "-f", saveImageAs, + customWidth ? `-w ${customWidth}` : "", ]; }; @@ -84,6 +87,7 @@ export const getDoubleUpscaleSecondPassArguments = ({ gpuId, saveImageAs, scale, + customWidth, }: { isAlpha: boolean; outFile: string; @@ -92,6 +96,7 @@ export const getDoubleUpscaleSecondPassArguments = ({ gpuId: string; saveImageAs: ImageFormat; scale: string; + customWidth: string; }) => { return [ "-i", @@ -108,6 +113,7 @@ export const getDoubleUpscaleSecondPassArguments = ({ gpuId ? gpuId : "", isAlpha ? "" : "-f", isAlpha ? "" : saveImageAs, + customWidth ? `-w ${customWidth}` : "", ]; }; @@ -119,6 +125,7 @@ export const getBatchArguments = ({ gpuId, saveImageAs, scale, + customWidth, }: { inputDir: string; outputDir: string; @@ -127,6 +134,7 @@ export const getBatchArguments = ({ gpuId: string; saveImageAs: ImageFormat; scale: string; + customWidth: string; }) => { return [ "-i", @@ -143,5 +151,6 @@ export const getBatchArguments = ({ gpuId ? gpuId : "", "-f", saveImageAs, + customWidth ? `-w ${customWidth}` : "", ]; }; diff --git a/renderer/components/Tabs.tsx b/renderer/components/Tabs.tsx index 6402627..a1620ad 100644 --- a/renderer/components/Tabs.tsx +++ b/renderer/components/Tabs.tsx @@ -7,19 +7,21 @@ type TabsProps = { const Tabs = ({ selectedTab, setSelectedTab }: TabsProps) => { return ( -
+
{ setSelectedTab(0); - }}> + }} + > Upscayl { setSelectedTab(1); - }}> + }} + > Settings
diff --git a/renderer/components/settings-tab/CustomResolutionInput.tsx b/renderer/components/settings-tab/CustomResolutionInput.tsx new file mode 100644 index 0000000..f98b5f9 --- /dev/null +++ b/renderer/components/settings-tab/CustomResolutionInput.tsx @@ -0,0 +1,53 @@ +import { customWidthAtom, useCustomWidthAtom } from "@/atoms/userSettingsAtom"; +import { useAtom } from "jotai"; +import React, { useState } from "react"; +import { Input } from "../ui/input"; + +export function CustomResolutionInput() { + const [useCustomWidth, setUseCustomWidth] = useAtom(useCustomWidthAtom); + const [customWidth, setCustomWidth] = useAtom(customWidthAtom); + + return ( +
+
+

CUSTOM OUTPUT WIDTH

+

+ REQUIRES RESTART +
+ Use a custom width for the output images. The height will be adjusted + automatically. Enabling this will override the scale setting. +

+
+
+ { + if (!e.currentTarget.checked) { + localStorage.removeItem("customWidth"); + } + setUseCustomWidth(!useCustomWidth); + }} + /> + { + if (e.currentTarget.value === "") { + setUseCustomWidth(false); + setCustomWidth(null); + localStorage.removeItem("customWidth"); + return; + } + setCustomWidth(parseInt(e.currentTarget.value)); + }} + step="1" + min="1" + className="input input-primary h-7 w-32 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none" + /> +
+
+ ); +} diff --git a/renderer/components/settings-tab/ImageScaleSelect.tsx b/renderer/components/settings-tab/ImageScaleSelect.tsx index f1df2d0..bf7a766 100644 --- a/renderer/components/settings-tab/ImageScaleSelect.tsx +++ b/renderer/components/settings-tab/ImageScaleSelect.tsx @@ -1,13 +1,20 @@ +import { useCustomWidthAtom } from "@/atoms/userSettingsAtom"; +import { useAtom } from "jotai"; + type ImageScaleSelectProps = { scale: "4" | "2" | "3"; setScale: (arg: "4" | "2" | "3") => void; }; export function ImageScaleSelect({ scale, setScale }: ImageScaleSelectProps) { + const [useCustomWidth, setUseCustomWidth] = useAtom(useCustomWidthAtom); + return ( -
+
-

IMAGE SCALE ({scale}X)

+

+ IMAGE SCALE ({scale}X) {useCustomWidth && "DISABLED"} +

Anything above 4X (except 16X Double Upscayl) only resizes the image and @@ -23,14 +30,8 @@ export function ImageScaleSelect({ scale, setScale }: ImageScaleSelectProps) { }} step="1" className="range range-primary mt-2" + disabled={useCustomWidth} /> - {/*

- 1 - 4 - 8 - 12 - 16 -
*/}
); } diff --git a/renderer/components/settings-tab/index.tsx b/renderer/components/settings-tab/index.tsx index ea0ae25..22907f2 100644 --- a/renderer/components/settings-tab/index.tsx +++ b/renderer/components/settings-tab/index.tsx @@ -24,6 +24,7 @@ import { ResetSettings } from "./ResetSettings"; import { featureFlags } from "@common/feature-flags"; import TurnOffNotificationsToggle from "./TurnOffNotificationsToggle"; import { cn } from "@/lib/utils"; +import { CustomResolutionInput } from "./CustomResolutionInput"; interface IProps { batchMode: boolean; @@ -225,6 +226,8 @@ function SettingsTab({ {/* IMAGE SCALE */} + +