mirror of
https://github.com/upscayl/upscayl.git
synced 2024-11-27 17:00:52 +01:00
Added sharp
This commit is contained in:
parent
3f9e7b1be7
commit
3e9f790347
9
constants/commands.js
Normal file
9
constants/commands.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const commands = {
|
||||||
|
SELECT_FILE: "Select a File",
|
||||||
|
SELECT_FOLDER: "Select a Folder",
|
||||||
|
UPSCAYL: "Upscale the Image",
|
||||||
|
UPSCAYL_DONE: "Upscaling Done",
|
||||||
|
UPSCAYL_PROGRESS: "Send Progress from Main to Renderer",
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = commands;
|
0
constants/models.js
Normal file
0
constants/models.js
Normal file
@ -3,6 +3,7 @@ const { join, parse } = require("path");
|
|||||||
const { format } = require("url");
|
const { format } = require("url");
|
||||||
const { spawn } = require("child_process");
|
const { spawn } = require("child_process");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const sizeOf = require("image-size");
|
||||||
|
|
||||||
const { execPath, modelsPath } = require("./binaries");
|
const { execPath, modelsPath } = require("./binaries");
|
||||||
|
|
||||||
@ -13,9 +14,12 @@ const {
|
|||||||
ipcMain,
|
ipcMain,
|
||||||
dialog,
|
dialog,
|
||||||
ipcRenderer,
|
ipcRenderer,
|
||||||
|
shell,
|
||||||
} = require("electron");
|
} = require("electron");
|
||||||
const isDev = require("electron-is-dev");
|
const isDev = require("electron-is-dev");
|
||||||
const prepareNext = require("electron-next");
|
const prepareNext = require("electron-next");
|
||||||
|
const commands = require("../constants/commands");
|
||||||
|
const sharp = require("sharp");
|
||||||
|
|
||||||
// Prepare the renderer once the app is ready
|
// Prepare the renderer once the app is ready
|
||||||
let mainWindow;
|
let mainWindow;
|
||||||
@ -25,9 +29,12 @@ app.on("ready", async () => {
|
|||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1100,
|
width: 1100,
|
||||||
height: 700,
|
height: 700,
|
||||||
|
minHeight: 500,
|
||||||
|
minWidth: 500,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
|
webSecurity: false,
|
||||||
preload: join(__dirname, "preload.js"),
|
preload: join(__dirname, "preload.js"),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -42,17 +49,19 @@ app.on("ready", async () => {
|
|||||||
mainWindow.setMenuBarVisibility(false);
|
mainWindow.setMenuBarVisibility(false);
|
||||||
// mainWindow.maximize();
|
// mainWindow.maximize();
|
||||||
mainWindow.loadURL(url);
|
mainWindow.loadURL(url);
|
||||||
|
|
||||||
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
|
shell.openExternal(url);
|
||||||
|
return { action: "deny" };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Quit the app once all windows are closed
|
// Quit the app once all windows are closed
|
||||||
app.on("window-all-closed", app.quit);
|
app.on("window-all-closed", app.quit);
|
||||||
|
|
||||||
// ! DONT FORGET TO RESTART THE APP WHEN YOU CHANGE CODE HERE
|
// ! DONT FORGET TO RESTART THE APP WHEN YOU CHANGE CODE HERE
|
||||||
ipcMain.on("sendMessage", (_, message) => {
|
|
||||||
console.log(message);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle("open", async () => {
|
ipcMain.handle(commands.SELECT_FILE, async () => {
|
||||||
const { canceled, filePaths } = await dialog.showOpenDialog({
|
const { canceled, filePaths } = await dialog.showOpenDialog({
|
||||||
properties: ["openFile", "multiSelections"],
|
properties: ["openFile", "multiSelections"],
|
||||||
});
|
});
|
||||||
@ -62,37 +71,40 @@ ipcMain.handle("open", async () => {
|
|||||||
return "cancelled";
|
return "cancelled";
|
||||||
} else {
|
} else {
|
||||||
console.log(filePaths[0]);
|
console.log(filePaths[0]);
|
||||||
// CREATE input AND upscaled FOLDER
|
// CREATE input AND upscaled FOLDER
|
||||||
return filePaths[0];
|
return filePaths[0];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
ipcMain.handle("output", async (event, message) => {
|
|
||||||
|
ipcMain.handle(commands.SELECT_FOLDER, async (event, message) => {
|
||||||
const { canceled, filePaths } = await dialog.showOpenDialog({
|
const { canceled, filePaths } = await dialog.showOpenDialog({
|
||||||
properties: ["openDirectory"],
|
properties: ["openDirectory"],
|
||||||
});
|
});
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
console.log("operation cancelled");
|
console.log("operation cancelled");
|
||||||
return "cancelled";
|
return "cancelled";
|
||||||
}
|
} else {
|
||||||
else {
|
console.log(filePaths[0]);
|
||||||
console.log(filePaths[0])
|
|
||||||
return filePaths[0];
|
return filePaths[0];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
ipcMain.on("upscayl", async (event, paths) => {
|
ipcMain.on(commands.UPSCAYL, async (event, payload) => {
|
||||||
const scale = "4";
|
console.log(payload);
|
||||||
let inputDir = paths[0].match(/(.*)[\/\\]/)[1]||'';
|
const model = payload.model;
|
||||||
|
const scale = payload.scaleFactor;
|
||||||
|
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
||||||
/*if (!fs.existsSync(inputDir)) {
|
/*if (!fs.existsSync(inputDir)) {
|
||||||
fs.mkdirSync(inputDir);
|
fs.mkdirSync(inputDir);
|
||||||
}*/
|
}*/
|
||||||
let outputDir = paths[1];
|
let outputDir = payload.outputPath;
|
||||||
/*if (!fs.existsSync(outputDir)) {
|
|
||||||
fs.mkdirSync(outputDir);
|
// if (!fs.existsSync(outputDir)) {
|
||||||
}*/
|
// fs.mkdirSync(outputDir);
|
||||||
|
// }
|
||||||
|
|
||||||
// COPY IMAGE TO upscaled FOLDER
|
// COPY IMAGE TO upscaled FOLDER
|
||||||
const fullfileName = paths[0].split("/").slice(-1)[0];
|
const fullfileName = payload.imagePath.split("/").slice(-1)[0];
|
||||||
const fileName = parse(fullfileName).name;
|
const fileName = parse(fullfileName).name;
|
||||||
const fileExt = parse(fullfileName).ext;
|
const fileExt = parse(fullfileName).ext;
|
||||||
|
|
||||||
@ -101,15 +113,17 @@ ipcMain.on("upscayl", async (event, paths) => {
|
|||||||
execPath,
|
execPath,
|
||||||
[
|
[
|
||||||
"-i",
|
"-i",
|
||||||
inputDir+'/'+fullfileName,
|
inputDir + "/" + fullfileName,
|
||||||
"-o",
|
"-o",
|
||||||
outputDir+'/'+fileName+"_upscaled_"+scale+'x'+fileExt,
|
outputDir + "/" + fileName + "_upscayled_" + scale + "x" + fileExt,
|
||||||
"-s",
|
"-s",
|
||||||
scale,
|
scale === 2 ? 4 : scale,
|
||||||
"-m",
|
"-m",
|
||||||
modelsPath,
|
modelsPath, // if (!fs.existsSync(outputDir)) {
|
||||||
|
// fs.mkdirSync(outputDir);
|
||||||
|
// }
|
||||||
"-n",
|
"-n",
|
||||||
"realesrgan-x4plus",
|
model,
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
cwd: null,
|
cwd: null,
|
||||||
@ -120,11 +134,14 @@ ipcMain.on("upscayl", async (event, paths) => {
|
|||||||
upscayl.stderr.on("data", (stderr) => {
|
upscayl.stderr.on("data", (stderr) => {
|
||||||
console.log(stderr.toString());
|
console.log(stderr.toString());
|
||||||
stderr = stderr.toString();
|
stderr = stderr.toString();
|
||||||
mainWindow.webContents.send("output", stderr.toString());
|
mainWindow.webContents.send(commands.UPSCAYL_PROGRESS, stderr.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
upscayl.on("close", (code) => {
|
upscayl.on("close", (code) => {
|
||||||
console.log("Done upscaling");
|
console.log("Done upscaling");
|
||||||
mainWindow.webContents.send("done");
|
mainWindow.webContents.send(
|
||||||
|
commands.UPSCAYL_DONE,
|
||||||
|
outputDir + "/" + fileName + "_upscayled_" + scale + "x" + fileExt
|
||||||
|
);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
@ -8,10 +8,4 @@ contextBridge.exposeInMainWorld("electron", {
|
|||||||
func(event, args);
|
func(event, args);
|
||||||
}),
|
}),
|
||||||
invoke: (command, payload) => ipcRenderer.invoke(command, payload),
|
invoke: (command, payload) => ipcRenderer.invoke(command, payload),
|
||||||
startListen: (func) => {
|
|
||||||
ipcRenderer.addListener("stdout",func)
|
|
||||||
},
|
|
||||||
stopListen: (func) => {
|
|
||||||
ipcRenderer.removeListener("stdout",func)
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
7236
package-lock.json
generated
Normal file
7236
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -67,6 +67,10 @@
|
|||||||
"electron-is-dev": "^2.0.0",
|
"electron-is-dev": "^2.0.0",
|
||||||
"electron-is-packaged": "^1.0.2",
|
"electron-is-packaged": "^1.0.2",
|
||||||
"electron-next": "^3.1.5",
|
"electron-next": "^3.1.5",
|
||||||
"electron-root-path": "^1.0.16"
|
"electron-root-path": "^1.0.16",
|
||||||
|
"image-size": "^1.0.2",
|
||||||
|
"react-compare-slider": "^2.2.0",
|
||||||
|
"sharp": "^0.30.7",
|
||||||
|
"tailwind-scrollbar": "^1.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,84 +1,219 @@
|
|||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
|
import commands from "../../constants/commands";
|
||||||
|
import {
|
||||||
|
ReactCompareSlider,
|
||||||
|
ReactCompareSliderImage,
|
||||||
|
} from "react-compare-slider";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const [imagePath, SetImagePath] = useState();
|
const [imagePath, SetImagePath] = useState("");
|
||||||
const [outputPath, SetOutputPath] = useState();
|
const [upscaledImagePath, setUpscaledImagePath] = useState("");
|
||||||
|
const [outputPath, SetOutputPath] = useState("");
|
||||||
|
const [scaleFactor, setScaleFactor] = useState(4);
|
||||||
|
const [progress, setProgress] = useState("");
|
||||||
|
const [model, setModel] = useState("realesrgan-x4plus");
|
||||||
const [loaded, setLoaded] = useState(false);
|
const [loaded, setLoaded] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMessage = (_event, args) => console.log(args)
|
|
||||||
window.electron.startListen(handleMessage)
|
|
||||||
// send(command, payload)
|
|
||||||
window.electron.send("sendMessage", { message: "Hello!" });
|
|
||||||
setLoaded(true);
|
setLoaded(true);
|
||||||
|
|
||||||
window.electron.on("output", (_, data) => {
|
window.electron.on(commands.UPSCAYL_PROGRESS, (_, data) => {
|
||||||
if (data.length > 0 && data.length < 10) console.log(data);
|
if (data.length > 0 && data.length < 10) setProgress(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.electron.on("done", (_, data) => {
|
window.electron.on(commands.UPSCAYL_DONE, (_, data) => {
|
||||||
console.log("DONE!");
|
setUpscaledImagePath(data);
|
||||||
});
|
});
|
||||||
return () => {
|
|
||||||
window.electron.stopListen(handleMessage)
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const imageHandler = async () => {
|
const selectImageHandler = async () => {
|
||||||
var path = await window.electron.invoke("open");
|
SetImagePath("");
|
||||||
if (path != "cancelled") {
|
setUpscaledImagePath("");
|
||||||
|
setProgress("");
|
||||||
|
var path = await window.electron.invoke(commands.SELECT_FILE);
|
||||||
|
|
||||||
|
if (path !== "cancelled") {
|
||||||
SetImagePath(path);
|
SetImagePath(path);
|
||||||
var dirname = path.match(/(.*)[\/\\]/)[1]||''
|
var dirname = path.match(/(.*)[\/\\]/)[1] || "";
|
||||||
SetOutputPath(dirname)
|
SetOutputPath(dirname);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const outputHandler = async () => {
|
|
||||||
var path = await window.electron.invoke("output");
|
const outputHandler = async () => {
|
||||||
if (path != "cancelled") {
|
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
||||||
SetOutputPath(path)
|
if (path !== "cancelled") {
|
||||||
}
|
SetOutputPath(path);
|
||||||
else{
|
} else {
|
||||||
console.log("Getting output path from input file")
|
console.log("Getting output path from input file");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const upscaylHandler = async () => {
|
|
||||||
window.electron.send("upscayl", [imagePath, outputPath]);
|
const upscaylHandler = async () => {
|
||||||
};
|
setProgress("0.00%");
|
||||||
|
await window.electron.send(commands.UPSCAYL, {
|
||||||
|
scaleFactor,
|
||||||
|
imagePath,
|
||||||
|
outputPath,
|
||||||
|
model,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(progress);
|
||||||
|
}, [progress]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-screen flex-row bg-neutral-900">
|
<div className="flex h-screen w-screen flex-row overflow-hidden bg-neutral-900">
|
||||||
<div className="flex h-screen w-96 flex-col bg-neutral-800 p-5">
|
<div className="flex h-screen w-96 flex-col bg-neutral-800">
|
||||||
<h1 className="text-3xl font-bold text-neutral-50">Upscayl</h1>
|
{/* HEADER */}
|
||||||
<div className="mt-10">
|
<h1 className="pl-5 pt-5 text-3xl font-bold text-neutral-50">
|
||||||
<p className="mb-2 font-medium text-neutral-100">Step 1</p>
|
Upscayl
|
||||||
<button className="rounded-lg bg-sky-400 p-3" onClick={imageHandler}>
|
</h1>
|
||||||
Select Image
|
<p className="mb-2 pl-5 text-neutral-400">AI Image Upscaler</p>
|
||||||
</button>
|
|
||||||
</div>
|
{/* LEFT PANE */}
|
||||||
<div className="mt-10">
|
<div className="h-screen overflow-auto p-5">
|
||||||
<p className="mb-2 font-medium text-neutral-100">Step 2</p>
|
{/* STEP 1 */}
|
||||||
<p className="mb-1 text-neutral-300">Select Scale Factor:</p>
|
<div className="mt-5">
|
||||||
<div className="flex flex-row gap-2">
|
<p className="mb-2 font-medium text-neutral-100">Step 1</p>
|
||||||
<button className="rounded-lg bg-red-400 p-3">2x</button>
|
<button
|
||||||
<button className="rounded-lg bg-red-400 p-3">4x</button>
|
className="rounded-lg bg-rose-400 p-3"
|
||||||
<button className="rounded-lg bg-red-400 p-3">6x</button>
|
onClick={selectImageHandler}
|
||||||
|
>
|
||||||
|
Select Image
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* STEP 2 */}
|
||||||
|
<div className="mt-10">
|
||||||
|
<p className="font-medium text-neutral-100">Step 2</p>
|
||||||
|
<p className="mb-2 text-sm text-neutral-400">Select Scale Factor</p>
|
||||||
|
<div className="animate flex flex-row gap-2">
|
||||||
|
<button
|
||||||
|
className={`h-12 w-12 rounded-lg ${
|
||||||
|
scaleFactor === 2 ? "bg-yellow-400" : "bg-neutral-400"
|
||||||
|
}`}
|
||||||
|
onClick={() => setScaleFactor(2)}
|
||||||
|
>
|
||||||
|
2x
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`h-12 w-12 rounded-lg ${
|
||||||
|
scaleFactor === 3 ? "bg-yellow-400" : "bg-neutral-400"
|
||||||
|
}`}
|
||||||
|
onClick={() => setScaleFactor(3)}
|
||||||
|
>
|
||||||
|
3x
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`h-12 w-12 rounded-lg ${
|
||||||
|
scaleFactor === 4 ? "bg-yellow-400" : "bg-neutral-400"
|
||||||
|
}`}
|
||||||
|
onClick={() => setScaleFactor(6)}
|
||||||
|
>
|
||||||
|
4x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* STEP 3 */}
|
||||||
|
<div className="mt-10">
|
||||||
|
<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="rounded-lg bg-teal-400 p-3"
|
||||||
|
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}
|
||||||
|
>
|
||||||
|
Upscayl
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-10">
|
|
||||||
<p className="mb-2 font-medium text-neutral-100">Step 3</p>
|
<div className="p-2 text-center text-sm text-neutral-500">
|
||||||
<button className="rounded-lg bg-violet-400 p-3" onClick={outputHandler}>
|
<p>
|
||||||
Set Output Folder
|
Copyright © 2022 -{" "}
|
||||||
</button>
|
<a
|
||||||
</div>
|
className="font-bold"
|
||||||
<div className="mt-10">
|
href="https://github.com/TGS963/upscayl"
|
||||||
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
target="_blank"
|
||||||
<button className="rounded-lg bg-green-400 p-3" onClick={upscaylHandler}>Upscayl</button>
|
>
|
||||||
|
Upscayl
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Made by{" "}
|
||||||
|
<a
|
||||||
|
href="https://github.com/TGS963"
|
||||||
|
className="font-bold"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
TGS963
|
||||||
|
</a>{" "}
|
||||||
|
and{" "}
|
||||||
|
<a
|
||||||
|
href="https://github.com/NayamAmarshe"
|
||||||
|
className="font-bold"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Nayam Amarshe
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex h-screen w-full flex-col items-center justify-center p-5">
|
|
||||||
<p className="text-lg font-medium text-neutral-400">
|
{/* RIGHT PANE */}
|
||||||
Select an Image to Upscale
|
<div className="relative flex h-screen w-full flex-col items-center justify-center">
|
||||||
</p>
|
{progress.length > 0 && (
|
||||||
|
<div className="absolute flex h-full w-full flex-col items-center justify-center bg-black/50 backdrop-blur-lg">
|
||||||
|
<div className="flex flex-col items-center gap-2">
|
||||||
|
<img src="/loading.svg" className="w-10" alt="Loading" />
|
||||||
|
<p className="font-bold text-neutral-50">{progress}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{imagePath.length === 0 ? (
|
||||||
|
<p className="p-5 text-lg font-medium text-neutral-400">
|
||||||
|
Select an Image to Upscale
|
||||||
|
</p>
|
||||||
|
) : upscaledImagePath.length === 0 ? (
|
||||||
|
<img
|
||||||
|
className="h-full w-full object-contain"
|
||||||
|
src={
|
||||||
|
"file://" + `${upscaledImagePath ? upscaledImagePath : imagePath}`
|
||||||
|
}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ReactCompareSlider
|
||||||
|
itemOne={
|
||||||
|
<ReactCompareSliderImage
|
||||||
|
src={"file://" + imagePath}
|
||||||
|
alt="Original"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
itemTwo={
|
||||||
|
<ReactCompareSliderImage
|
||||||
|
src={"file://" + upscaledImagePath}
|
||||||
|
alt="Upscayl"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
className="h-full"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
55
renderer/public/loading.svg
Normal file
55
renderer/public/loading.svg
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||||
|
<svg width="58" height="58" viewBox="0 0 58 58" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<g transform="translate(2 1)" stroke="#FFF" stroke-width="1.5">
|
||||||
|
<circle cx="42.601" cy="11.462" r="5" fill-opacity="1" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="1;0;0;0;0;0;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="49.063" cy="27.063" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;1;0;0;0;0;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="42.601" cy="42.663" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;1;0;0;0;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="27" cy="49.125" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;0;1;0;0;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="11.399" cy="42.663" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;0;0;1;0;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="4.938" cy="27.063" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;0;0;0;1;0;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="11.399" cy="11.462" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;0;0;0;0;1;0" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle cx="27" cy="5" r="5" fill-opacity="0" fill="#fff">
|
||||||
|
<animate attributeName="fill-opacity"
|
||||||
|
begin="0s" dur="1.3s"
|
||||||
|
values="0;0;0;0;0;0;0;1" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
@ -3,6 +3,21 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
@apply w-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
@apply rounded-full bg-neutral-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
@apply rounded-full bg-neutral-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
@apply rounded-full bg-neutral-400;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10,5 +25,4 @@
|
|||||||
.animate {
|
.animate {
|
||||||
@apply transition-all duration-300 ease-in-out;
|
@apply transition-all duration-300 ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
BIN
resources/linux/bin/models/df2k.bin
Normal file
BIN
resources/linux/bin/models/df2k.bin
Normal file
Binary file not shown.
1001
resources/linux/bin/models/df2k.param
Normal file
1001
resources/linux/bin/models/df2k.param
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,5 +7,5 @@ module.exports = {
|
|||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
darkMode: "class",
|
darkMode: "class",
|
||||||
plugins: [],
|
plugins: [require("tailwind-scrollbar")],
|
||||||
};
|
};
|
||||||
|
BIN
to_upscale_upscayled_2x.jpeg
Normal file
BIN
to_upscale_upscayled_2x.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
BIN
to_upscale_upscayled_4x.jpeg
Normal file
BIN
to_upscale_upscayled_4x.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 934 KiB |
Loading…
Reference in New Issue
Block a user