1
0
mirror of https://github.com/upscayl/upscayl.git synced 2024-11-30 18:24:27 +01:00

Merge pull request #39 from xanderfrangos/xanderfrangos

Various adjustments (new save options, updated step order, CSS tweaks)
This commit is contained in:
TGS963 2022-08-29 18:01:34 +05:30 committed by GitHub
commit fbdc3f7bfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 43 deletions

View File

@ -1,6 +1,8 @@
const commands = {
SELECT_FILE: "Select a File",
SELECT_FOLDER: "Select a Folder",
SELECT_OUTPUT: "Save as",
SET_FILE: "Set file",
REPLACE_ORIGINAL: "Replace original",
UPSCAYL: "Upscale the Image",
UPSCAYL_DONE: "Upscaling Done",
UPSCAYL_PROGRESS: "Send Progress from Main to Renderer",

View File

@ -4,6 +4,7 @@ const { format } = require("url");
const { spawn } = require("child_process");
const fs = require("fs");
const sizeOf = require("image-size");
const path = require('path');
const { autoUpdater } = require("electron-updater");
const { getPlatform } = require("./getPlatform");
@ -21,6 +22,7 @@ const {
const isDev = require("electron-is-dev");
const prepareNext = require("electron-next");
const commands = require("./commands");
const tmpPath = path.join(app.getPath("userData"), "\\tmp\\");
// Prepare the renderer once the app is ready
let mainWindow;
@ -34,6 +36,8 @@ app.on("ready", async () => {
height: 700,
minHeight: 500,
minWidth: 500,
show: false,
backgroundColor: "#171717",
webPreferences: {
devTools: isDev,
autoHideMenuBar: true,
@ -59,6 +63,8 @@ app.on("ready", async () => {
return { action: "deny" };
});
mainWindow.once("ready-to-show", () => { mainWindow.show(); })
if (!isDev) {
autoUpdater.checkForUpdates();
}
@ -67,6 +73,16 @@ app.on("ready", async () => {
// Quit the app once all windows are closed
app.on("window-all-closed", app.quit);
// Fix file:// + ? by registering a new protocol
app.whenReady().then(() => {
const { protocol } = require("electron");
protocol.registerFileProtocol('local', (request, callback) => {
const pathname = decodeURIComponent(request.url.replace('local://', ''));
const parts = pathname.split('?');
callback(parts[0]);
});
});
// ! DONT FORGET TO RESTART THE APP WHEN YOU CHANGE CODE HERE
ipcMain.handle(commands.SELECT_FILE, async () => {
@ -79,21 +95,49 @@ ipcMain.handle(commands.SELECT_FILE, async () => {
return "cancelled";
} else {
console.log(filePaths[0]);
// CREATE input AND upscaled FOLDER
// CREATE original copy
if(!fs.existsSync(tmpPath)) {
fs.mkdirSync(tmpPath);
}
fs.copyFileSync(filePaths[0], path.join(tmpPath, "original" + parse(filePaths[0]).ext));
return filePaths[0];
}
});
ipcMain.handle(commands.SELECT_FOLDER, async (event, message) => {
const { canceled, filePaths } = await dialog.showOpenDialog({
properties: ["openDirectory"],
ipcMain.handle(commands.SET_FILE, async (event, payload) => {
const original = payload.original;
const fileExt = parse(original).ext;
// CREATE original copy
if(!fs.existsSync(tmpPath)) {
fs.mkdirSync(tmpPath);
}
fs.copyFileSync(original, path.join(tmpPath, "original" + fileExt));
})
ipcMain.handle(commands.SELECT_OUTPUT, async (event, payload) => {
const original = payload.original;
const fileExt = parse(original).ext;
const { canceled, filePath } = await dialog.showSaveDialog({
filters: [{name: fileExt, extensions: [fileExt.substring(1)]}]
});
if (canceled) {
console.log("operation cancelled");
return "cancelled";
} else {
console.log(filePaths[0]);
return filePaths[0];
console.log(filePath);
if(fs.existsSync(tmpPath + "scaled" + fileExt)) {
fs.copyFileSync(tmpPath + "scaled" + fileExt, filePath);
}
return filePath;
}
});
ipcMain.handle(commands.REPLACE_ORIGINAL, async (event, payload) => {
const original = payload.original;
const fileExt = parse(original).ext;
if(fs.existsSync(tmpPath + "scaled" + fileExt)) {
fs.copyFileSync(tmpPath + "scaled" + fileExt, original);
}
});
@ -102,10 +146,10 @@ ipcMain.on(commands.UPSCAYL, async (event, payload) => {
const scale = payload.scaleFactor;
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
let outputDir = payload.outputPath;
let outputDir = tmpPath
console.log("🚀 => ipcMain.on => outputDir", outputDir);
// COPY IMAGE TO upscaled FOLDER
// COPY IMAGE TO TMP FOLDER
const platform = getPlatform();
const fullfileName =
platform === "win"
@ -121,9 +165,9 @@ ipcMain.on(commands.UPSCAYL, async (event, payload) => {
execPath,
[
"-i",
inputDir + "/" + fullfileName,
tmpPath + "original" + fileExt,
"-o",
outputDir + "/" + fileName + "_upscayled_" + scale + "x" + fileExt,
tmpPath + "scaled" + fileExt,
"-s",
scale === 2 ? 4 : scale,
"-m",
@ -151,7 +195,7 @@ ipcMain.on(commands.UPSCAYL, async (event, payload) => {
console.log("Done upscaling");
mainWindow.webContents.send(
commands.UPSCAYL_DONE,
outputDir + "/" + fileName + "_upscayled_" + scale + "x" + fileExt
outputDir + "scaled" + fileExt
);
}
});

View File

@ -14,6 +14,7 @@ const Home = () => {
const [outputPath, SetOutputPath] = useState("");
const [scaleFactor, setScaleFactor] = useState(4);
const [progress, setProgress] = useState("");
const [curStep, setStep] = useState(1);
const [model, setModel] = useState("realesrgan-x4plus");
const [loaded, setLoaded] = useState(false);
const [version, setVersion] = useState("");
@ -22,8 +23,13 @@ const Home = () => {
setProgress("");
SetImagePath("");
setUpscaledImagePath("");
setStep(1);
};
const stepStyle = (thisStep) => {
return { display: (thisStep > curStep ? "none" : "block") };
}
useEffect(() => {
setVersion(navigator.userAgent.match(/Upscayl\/([\d\.]+\d+)/)[1]);
}, []);
@ -48,6 +54,7 @@ const Home = () => {
window.electron.on(commands.UPSCAYL_DONE, (_, data) => {
setProgress("");
setUpscaledImagePath(data);
setStep(4);
});
}, []);
@ -59,6 +66,7 @@ const Home = () => {
SetImagePath(path);
var dirname = path.match(/(.*)[\/\\]/)[1] || "";
SetOutputPath(dirname);
setStep(3);
}
};
@ -101,6 +109,8 @@ const Home = () => {
SetImagePath(filePath);
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
SetOutputPath(dirname);
setStep(3);
window.electron.invoke(commands.SET_FILE, {original: filePath});
}
};
@ -121,11 +131,21 @@ const Home = () => {
SetImagePath(filePath);
var dirname = filePath.match(/(.*)[\/\\]/)[1] || "";
SetOutputPath(dirname);
setStep(3);
}
};
const outputHandler = async () => {
var path = await window.electron.invoke(commands.SELECT_FOLDER);
var path = await window.electron.invoke(commands.SELECT_OUTPUT, { original: imagePath });
if (path !== "cancelled") {
SetOutputPath(path);
} else {
console.log("Getting output path from input file");
}
};
const replaceHandler = async () => {
var path = await window.electron.invoke(commands.REPLACE_ORIGINAL, { original: imagePath });
if (path !== "cancelled") {
SetOutputPath(path);
} else {
@ -169,17 +189,17 @@ const Home = () => {
{/* LEFT PANE */}
<div className="h-screen overflow-auto p-5">
{/* STEP 1 */}
<div className="mt-5">
<div className="mt-0">
<p className="mb-2 font-medium text-neutral-100">Step 1</p>
<button
className="rounded-lg bg-rose-400 p-3"
className="rounded-lg bg-rose-400 hover:bg-rose-300 transition-colors p-3 w-full font-semibold"
onClick={selectImageHandler}
>
Select Image
</button>
</div>
{/* STEP 2 */}
<div className="mt-10">
<div className="mt-5 animate-step-in" style={stepStyle(3)}>
<p className="font-medium text-neutral-100">Step 2</p>
<p className="mb-2 text-sm text-neutral-400">
Select Upscaling Type
@ -187,14 +207,26 @@ const Home = () => {
<select
name="select-model"
onDrop={(e) => handleDrop(e)}
className="rounded-lg bg-slate-300 p-3"
className="rounded-lg bg-slate-300 hover:bg-slate-200 p-3 w-full"
onChange={handleModelChange}
>
<option value="realesrgan-x4plus">General Photo</option>
<option value="realesrgan-x4plus-anime">Digital Art</option>
<option value="realesrgan-x4plus">Photos &amp; Realistic Art</option>
<option value="realesrgan-x4plus-anime">2D &amp; Simple Art</option>
</select>
</div>
{/* STEP 3 */}
<div className="mt-5 animate-step-in" style={stepStyle(3)}>
<p className="mb-2 font-medium text-neutral-100">Step 3</p>
<button
className="rounded-lg bg-sky-400 hover:bg-sky-300 transition-colors p-3 w-full font-semibold"
onClick={upscaylHandler}
disabled={progress.length > 0}
>
{progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
</button>
</div>
{/* STEP 3
<div className="mt-10">
<p className="font-medium text-neutral-100">Step 3</p>
@ -227,29 +259,23 @@ const Home = () => {
</div>
</div> */}
{/* STEP 3 */}
<div className="mt-10">
<p className="font-medium text-neutral-100">Step 3</p>
{/* STEP 4 */}
<div className="mt-5 animate-step-in" style={stepStyle(4)}>
<p className="font-medium text-neutral-100">Step 4</p>
<p className="mb-2 text-sm text-neutral-400">
Defaults to Image's path
Save file
</p>
<button
className="rounded-lg bg-teal-400 p-3"
className="rounded-lg bg-teal-400 hover:bg-teal-300 transition-colors p-3 w-full font-semibold"
onClick={replaceHandler}
>
Replace Original
</button>
<button
className="rounded-lg bg-teal-400 hover:bg-teal-300 transition-colors p-3 mt-1 w-full font-semibold"
onClick={outputHandler}
>
Set Output Folder
</button>
</div>
{/* STEP 4 */}
<div className="mt-10">
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
<button
className="rounded-lg bg-sky-400 p-3"
onClick={upscaylHandler}
disabled={progress.length > 0}
>
{progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
Save As
</button>
</div>
</div>
@ -295,8 +321,8 @@ const Home = () => {
onDragLeave={(e) => handleDragLeave(e)}
onPaste={(e) => handlePaste(e)}
>
{progress.length > 0 && upscaledImagePath.length === 0 && (
<div className="absolute flex h-full w-full flex-col items-center justify-center bg-black/50 backdrop-blur-lg">
{progress.length > 0 && (
<div className="absolute flex h-full w-full flex-col items-center justify-center bg-black/50 backdrop-blur-lg z-10">
<div className="flex flex-col items-center gap-2">
<Image src={Animated} />
<p className="font-bold text-neutral-50">{progress}</p>
@ -309,13 +335,13 @@ const Home = () => {
<p className="p-5 text-lg font-medium text-neutral-400">
Select an Image to Upscale
</p>
<p className="text-neutral-600">Upscale v{version}</p>
<p className="text-neutral-600">Upscayl v{version}</p>
</>
) : upscaledImagePath.length === 0 ? (
<img
className="h-full w-full object-contain"
src={
"file://" + `${upscaledImagePath ? upscaledImagePath : imagePath}`
"local://" + `${upscaledImagePath ? upscaledImagePath : imagePath}`
}
draggable="false"
alt=""
@ -324,7 +350,7 @@ const Home = () => {
<ReactCompareSlider
itemOne={
<ReactCompareSliderImage
src={"file://" + imagePath}
src={"local://" + imagePath + "?" + Date.now()}
alt="Original"
style={{
objectFit: "contain",
@ -333,7 +359,7 @@ const Home = () => {
}
itemTwo={
<ReactCompareSliderImage
src={"file://" + upscaledImagePath}
src={"local://" + upscaledImagePath + "?" + Date.now()}
alt="Upscayl"
style={{
objectFit: "contain",

View File

@ -26,3 +26,13 @@
@apply transition-all duration-300 ease-in-out;
}
}
.animate-step-in {
animation: animate-step-in 0.35s cubic-bezier(0.07, 0.43, 0.02, 1);
}
@keyframes animate-step-in {
0% { opacity: 0; transform: translateY(-10px); }
80% { opacity: 1; }
100% { opacity: 1; transform: translateY(0px); }
}