Fixed for v1.5 release
BIN
build/icon.icns
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 221 KiB |
@ -110,7 +110,6 @@ ipcMain.on(commands.DOUBLE_UPSCAYL, async (event, payload) => {
|
||||
const model = payload.model;
|
||||
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
||||
let outputDir = payload.outputPath;
|
||||
console.log(outputDir);
|
||||
|
||||
// COPY IMAGE TO TMP FOLDER
|
||||
const platform = getPlatform();
|
||||
|
@ -143,5 +143,8 @@
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-tooltip": "^4.2.21",
|
||||
"tailwind-scrollbar": "^1.3.1"
|
||||
},
|
||||
"volta": {
|
||||
"node": "16.17.0"
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,18 @@ import React from "react";
|
||||
export default function Header() {
|
||||
return (
|
||||
<a href="https://github.com/upscayl/upscayl" target="_blank">
|
||||
<h1 className="pl-5 pt-5 text-3xl font-bold text-neutral-50">Upscayl</h1>
|
||||
<p className="mb-2 pl-5 text-neutral-400">AI Image Upscaler</p>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
@ -30,150 +30,92 @@ function LeftPaneSteps(props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!props.batchMode ? (
|
||||
<>
|
||||
{/* STEP 1 */}
|
||||
<div data-tip={props.imagePath}>
|
||||
<p className="mb-2 font-medium text-white/70">Step 1</p>
|
||||
<button
|
||||
className="bg-gradient-red rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||
onClick={props.selectImageHandler}
|
||||
>
|
||||
Select Image
|
||||
</button>
|
||||
</div>
|
||||
{/* STEP 1 */}
|
||||
<div data-tip={props.imagePath}>
|
||||
<p className="mb-2 font-medium text-white/70">Step 1</p>
|
||||
<button
|
||||
className="bg-gradient-red rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||
onClick={
|
||||
!props.batchMode
|
||||
? props.selectImageHandler
|
||||
: props.selectFolderHandler
|
||||
}
|
||||
>
|
||||
Select {props.batchMode ? "Folder" : "Image"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 2 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="font-medium text-neutral-100">Step 2</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">
|
||||
Select Upscaling Type
|
||||
{/* STEP 2 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="font-medium text-neutral-100">Step 2</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">Select Upscaling Type</p>
|
||||
{props.model !== "models-DF2K" && !props.batchMode && (
|
||||
<div className="mb-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-neutral-500 transition duration-200 focus:outline-none focus-visible:border focus-visible:border-green-400"
|
||||
checked={props.doubleUpscayl}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
props.setDoubleUpscayl(true);
|
||||
} else {
|
||||
props.setDoubleUpscayl(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p
|
||||
data-tip="Enable this option to get an 8x upscayl"
|
||||
className={`inline-block cursor-help rounded-full text-sm font-medium ${
|
||||
props.doubleUpscayl
|
||||
? "bg-gradient-white px-2 text-black/90"
|
||||
: "text-neutral-500"
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
props.setDoubleUpscayl(!props.doubleUpscayl);
|
||||
}}
|
||||
>
|
||||
Double Upscayl
|
||||
</p>
|
||||
{props.model !== "models-DF2K" && (
|
||||
<div className="mb-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-neutral-500 transition duration-200 focus:outline-none focus-visible:border focus-visible:border-green-400"
|
||||
checked={props.doubleUpscayl}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
props.setDoubleUpscayl(true);
|
||||
} else {
|
||||
props.setDoubleUpscayl(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p
|
||||
data-tip="Enable this option to get an 8x upscayl"
|
||||
className={`inline-block cursor-help rounded-full text-sm font-medium ${
|
||||
props.doubleUpscayl
|
||||
? "bg-gradient-white px-2 text-black/90"
|
||||
: "text-neutral-500"
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
props.setDoubleUpscayl(!props.doubleUpscayl);
|
||||
}}
|
||||
>
|
||||
Double Upscayl
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<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 hover:bg-slate-200"
|
||||
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>
|
||||
</div>
|
||||
)}
|
||||
<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 hover:bg-slate-200"
|
||||
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>
|
||||
</div>
|
||||
|
||||
{/* STEP 3 */}
|
||||
<div className="animate-step-in" data-tip={props.outputPath}>
|
||||
<p className="font-medium text-neutral-100">Step 3</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">
|
||||
Defaults to Image's path
|
||||
</p>
|
||||
<button
|
||||
className="bg-gradient mt-1 rounded-lg p-3 font-medium text-black/90 transition-colors hover:bg-teal-300"
|
||||
onClick={props.outputHandler}
|
||||
>
|
||||
Set Output Folder
|
||||
</button>
|
||||
</div>
|
||||
{/* STEP 3 */}
|
||||
<div className="animate-step-in" data-tip={props.outputPath}>
|
||||
<p className="font-medium text-neutral-100">Step 3</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">
|
||||
Defaults to Image's path
|
||||
</p>
|
||||
<button
|
||||
className="bg-gradient mt-1 rounded-lg p-3 font-medium text-black/90 transition-colors hover:bg-teal-300"
|
||||
onClick={props.outputHandler}
|
||||
>
|
||||
Set Output Folder
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 4 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
||||
<button
|
||||
className="bg-gradient-upscayl rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||
onClick={props.upscaylHandler}
|
||||
disabled={props.progress.length > 0}
|
||||
>
|
||||
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{/* STEP 1 */}
|
||||
<div className="">
|
||||
<p className="mb-2 font-medium text-neutral-100">Step 1</p>
|
||||
<button
|
||||
className="rounded-lg bg-rose-400 p-3 transition-colors hover:bg-rose-300"
|
||||
onClick={props.selectFolderHandler}
|
||||
>
|
||||
Select Folder
|
||||
</button>
|
||||
</div>
|
||||
{/* STEP 4 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
||||
<button
|
||||
className="bg-gradient-upscayl rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||
onClick={props.upscaylHandler}
|
||||
disabled={props.progress.length > 0}
|
||||
>
|
||||
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 2 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="font-medium text-neutral-100">Step 2</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">
|
||||
Select Upscaling Type
|
||||
</p>
|
||||
<select
|
||||
name="select-model"
|
||||
onDrop={(e) => props.handleDrop(e)}
|
||||
className="rounded-lg bg-slate-300 p-3 hover:bg-slate-200"
|
||||
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>
|
||||
</div>
|
||||
|
||||
{/* STEP 3 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="font-medium text-neutral-100">Step 3</p>
|
||||
<p className="mb-2 text-sm text-neutral-400">
|
||||
Defaults to Folder's path
|
||||
</p>
|
||||
<button
|
||||
className="mt-1 rounded-lg bg-teal-400 p-3 transition-colors hover:bg-teal-300"
|
||||
onClick={props.outputHandler}
|
||||
>
|
||||
Set Output Folder
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* STEP 4 */}
|
||||
<div className="animate-step-in">
|
||||
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
||||
<button
|
||||
className="rounded-lg bg-sky-400 p-3 transition-colors hover:bg-sky-300"
|
||||
onClick={props.upscaylHandler}
|
||||
disabled={props.progress.length > 0}
|
||||
>
|
||||
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<ReactTooltip
|
||||
className="max-w-72 break-words bg-neutral-900 text-neutral-50"
|
||||
place="top"
|
||||
|
@ -3,7 +3,7 @@ import React from "react";
|
||||
function ResetButton(props) {
|
||||
return (
|
||||
<button
|
||||
className="animate absolute bottom-1 right-1 z-10 rounded-full bg-sky-400 py-2 px-4 opacity-50 hover:opacity-100"
|
||||
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
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
function RightPaneInfo({ version }) {
|
||||
function RightPaneInfo({ version, batchMode }) {
|
||||
return (
|
||||
<>
|
||||
<p className="p-5 text-lg font-medium text-neutral-400">
|
||||
Select an Image to Upscale
|
||||
Select {batchMode ? "a Folder" : "an Image"} to Upscale
|
||||
</p>
|
||||
<p className="text-neutral-600">Upscayl v{version}</p>
|
||||
</>
|
||||
|
@ -27,8 +27,12 @@ const Home = () => {
|
||||
|
||||
const resetImagePaths = () => {
|
||||
setProgress("");
|
||||
|
||||
SetImagePath("");
|
||||
setUpscaledImagePath("");
|
||||
|
||||
setBatchFolderPath("");
|
||||
setUpscaledBatchFolderPath("");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -44,6 +48,7 @@ const Home = () => {
|
||||
);
|
||||
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."
|
||||
@ -100,6 +105,7 @@ const Home = () => {
|
||||
|
||||
const selectImageHandler = async () => {
|
||||
resetImagePaths();
|
||||
|
||||
var path = await window.electron.invoke(commands.SELECT_FILE);
|
||||
|
||||
if (path !== "cancelled") {
|
||||
@ -110,7 +116,10 @@ const Home = () => {
|
||||
};
|
||||
|
||||
const selectFolderHandler = async () => {
|
||||
resetImagePaths();
|
||||
|
||||
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
||||
|
||||
if (path !== "cancelled") {
|
||||
setBatchFolderPath(path);
|
||||
SetOutputPath(path + "_upscayled");
|
||||
@ -271,11 +280,18 @@ const Home = () => {
|
||||
<ProgressBar progress={progress} />
|
||||
) : null}
|
||||
|
||||
{imagePath.length === 0 && batchFolderPath.length === 0 ? (
|
||||
<RightPaneInfo version={version} />
|
||||
) : upscaledImagePath.length === 0 &&
|
||||
upscaledBatchFolderPath.length === 0 ? (
|
||||
!batchMode ? (
|
||||
{((!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={
|
||||
@ -285,46 +301,78 @@ const Home = () => {
|
||||
draggable="false"
|
||||
alt=""
|
||||
/>
|
||||
) : (
|
||||
)}
|
||||
|
||||
{batchMode &&
|
||||
upscaledBatchFolderPath.length === 0 &&
|
||||
batchFolderPath.length > 0 && (
|
||||
<p className="select-none font-bold text-neutral-50">
|
||||
Selected folder: {batchFolderPath}
|
||||
</p>
|
||||
)
|
||||
) : !batchMode ? (
|
||||
<ReactCompareSlider
|
||||
itemOne={
|
||||
<ReactCompareSliderImage
|
||||
src={"file://" + imagePath}
|
||||
alt="Original"
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
itemTwo={
|
||||
<ReactCompareSliderImage
|
||||
src={"file://" + upscaledImagePath}
|
||||
alt="Upscayl"
|
||||
style={{
|
||||
objectFit: "contain",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
className="h-screen"
|
||||
/>
|
||||
) : (
|
||||
)}
|
||||
|
||||
{batchMode && upscaledBatchFolderPath.length > 0 && (
|
||||
<>
|
||||
<p className="select-none py-4 font-bold text-neutral-50">
|
||||
Finished Upscaling Folder!
|
||||
All done!
|
||||
</p>
|
||||
<button
|
||||
className="rounded-lg bg-blue-400 p-3 font-medium text-white/90 transition-colors"
|
||||
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",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
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="h-screen"
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* {imagePath.length === 0 && batchFolderPath.length === 0 ? (
|
||||
<RightPaneInfo version={version} />
|
||||
) : upscaledImagePath.length === 0 &&
|
||||
upscaledBatchFolderPath.length === 0 ? (
|
||||
!batchMode ? (
|
||||
|
||||
) : (
|
||||
|
||||
)
|
||||
) : !batchMode ? (
|
||||
|
||||
) : (
|
||||
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1 +0,0 @@
|
||||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M9 9H15V15H9z"></path><path d="M19,17V7c0-1.103-0.897-2-2-2H7C5.897,5,5,5.897,5,7v10c0,1.103,0.897,2,2,2h10C18.103,19,19,18.103,19,17z M7,7h10 l0.002,10H7V7z"></path></svg>
|
Before Width: | Height: | Size: 325 B |
BIN
renderer/public/icon.png
Normal file
After Width: | Height: | Size: 20 KiB |
@ -39,6 +39,9 @@
|
||||
.bg-gradient {
|
||||
@apply bg-gradient-to-br from-green-500 to-lime-300 hover:from-lime-300 hover:to-green-500;
|
||||
}
|
||||
.bg-gradient-blue {
|
||||
@apply bg-gradient-to-br from-blue-500 to-sky-400 hover:from-sky-400 hover:to-blue-500;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-step-in {
|
||||
|
BIN
to_upscale_upscayl_8x_realesrgan-x4plus.jpeg
Normal file
After Width: | Height: | Size: 15 MiB |
BIN
ups/to_upscale.jpeg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
ups_upscayled/to_upscale.png
Normal file
After Width: | Height: | Size: 2.5 MiB |