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;
|
const model = payload.model;
|
||||||
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
let inputDir = payload.imagePath.match(/(.*)[\/\\]/)[1] || "";
|
||||||
let outputDir = payload.outputPath;
|
let outputDir = payload.outputPath;
|
||||||
console.log(outputDir);
|
|
||||||
|
|
||||||
// COPY IMAGE TO TMP FOLDER
|
// COPY IMAGE TO TMP FOLDER
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
|
@ -143,5 +143,8 @@
|
|||||||
"react-dropzone": "^14.2.2",
|
"react-dropzone": "^14.2.2",
|
||||||
"react-tooltip": "^4.2.21",
|
"react-tooltip": "^4.2.21",
|
||||||
"tailwind-scrollbar": "^1.3.1"
|
"tailwind-scrollbar": "^1.3.1"
|
||||||
|
},
|
||||||
|
"volta": {
|
||||||
|
"node": "16.17.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,18 @@ import React from "react";
|
|||||||
export default function Header() {
|
export default function Header() {
|
||||||
return (
|
return (
|
||||||
<a href="https://github.com/upscayl/upscayl" target="_blank">
|
<a href="https://github.com/upscayl/upscayl" target="_blank">
|
||||||
<h1 className="pl-5 pt-5 text-3xl font-bold text-neutral-50">Upscayl</h1>
|
<div className="flex items-center gap-3 px-5 py-5">
|
||||||
<p className="mb-2 pl-5 text-neutral-400">AI Image Upscaler</p>
|
<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>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -30,150 +30,92 @@ function LeftPaneSteps(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!props.batchMode ? (
|
{/* STEP 1 */}
|
||||||
<>
|
<div data-tip={props.imagePath}>
|
||||||
{/* STEP 1 */}
|
<p className="mb-2 font-medium text-white/70">Step 1</p>
|
||||||
<div data-tip={props.imagePath}>
|
<button
|
||||||
<p className="mb-2 font-medium text-white/70">Step 1</p>
|
className="bg-gradient-red rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||||
<button
|
onClick={
|
||||||
className="bg-gradient-red rounded-lg p-3 font-medium text-white/90 transition-colors"
|
!props.batchMode
|
||||||
onClick={props.selectImageHandler}
|
? props.selectImageHandler
|
||||||
>
|
: props.selectFolderHandler
|
||||||
Select Image
|
}
|
||||||
</button>
|
>
|
||||||
</div>
|
Select {props.batchMode ? "Folder" : "Image"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* STEP 2 */}
|
{/* STEP 2 */}
|
||||||
<div className="animate-step-in">
|
<div className="animate-step-in">
|
||||||
<p className="font-medium text-neutral-100">Step 2</p>
|
<p className="font-medium text-neutral-100">Step 2</p>
|
||||||
<p className="mb-2 text-sm text-neutral-400">
|
<p className="mb-2 text-sm text-neutral-400">Select Upscaling Type</p>
|
||||||
Select Upscaling Type
|
{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>
|
</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>
|
</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 */}
|
{/* STEP 3 */}
|
||||||
<div className="animate-step-in" data-tip={props.outputPath}>
|
<div className="animate-step-in" data-tip={props.outputPath}>
|
||||||
<p className="font-medium text-neutral-100">Step 3</p>
|
<p className="font-medium text-neutral-100">Step 3</p>
|
||||||
<p className="mb-2 text-sm text-neutral-400">
|
<p className="mb-2 text-sm text-neutral-400">
|
||||||
Defaults to Image's path
|
Defaults to Image's path
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
className="bg-gradient mt-1 rounded-lg p-3 font-medium text-black/90 transition-colors hover:bg-teal-300"
|
className="bg-gradient mt-1 rounded-lg p-3 font-medium text-black/90 transition-colors hover:bg-teal-300"
|
||||||
onClick={props.outputHandler}
|
onClick={props.outputHandler}
|
||||||
>
|
>
|
||||||
Set Output Folder
|
Set Output Folder
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* STEP 4 */}
|
{/* STEP 4 */}
|
||||||
<div className="animate-step-in">
|
<div className="animate-step-in">
|
||||||
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
<p className="mb-2 font-medium text-neutral-100">Step 4</p>
|
||||||
<button
|
<button
|
||||||
className="bg-gradient-upscayl rounded-lg p-3 font-medium text-white/90 transition-colors"
|
className="bg-gradient-upscayl rounded-lg p-3 font-medium text-white/90 transition-colors"
|
||||||
onClick={props.upscaylHandler}
|
onClick={props.upscaylHandler}
|
||||||
disabled={props.progress.length > 0}
|
disabled={props.progress.length > 0}
|
||||||
>
|
>
|
||||||
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
{props.progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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 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
|
<ReactTooltip
|
||||||
className="max-w-72 break-words bg-neutral-900 text-neutral-50"
|
className="max-w-72 break-words bg-neutral-900 text-neutral-50"
|
||||||
place="top"
|
place="top"
|
||||||
|
@ -3,7 +3,7 @@ import React from "react";
|
|||||||
function ResetButton(props) {
|
function ResetButton(props) {
|
||||||
return (
|
return (
|
||||||
<button
|
<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}
|
onClick={props.resetImagePaths}
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
function RightPaneInfo({ version }) {
|
function RightPaneInfo({ version, batchMode }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className="p-5 text-lg font-medium text-neutral-400">
|
<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>
|
||||||
<p className="text-neutral-600">Upscayl v{version}</p>
|
<p className="text-neutral-600">Upscayl v{version}</p>
|
||||||
</>
|
</>
|
||||||
|
@ -27,8 +27,12 @@ const Home = () => {
|
|||||||
|
|
||||||
const resetImagePaths = () => {
|
const resetImagePaths = () => {
|
||||||
setProgress("");
|
setProgress("");
|
||||||
|
|
||||||
SetImagePath("");
|
SetImagePath("");
|
||||||
setUpscaledImagePath("");
|
setUpscaledImagePath("");
|
||||||
|
|
||||||
|
setBatchFolderPath("");
|
||||||
|
setUpscaledBatchFolderPath("");
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -44,6 +48,7 @@ const Home = () => {
|
|||||||
);
|
);
|
||||||
resetImagePaths();
|
resetImagePaths();
|
||||||
} else if (data.includes("failed")) {
|
} else if (data.includes("failed")) {
|
||||||
|
if (batchMode) return;
|
||||||
alert(
|
alert(
|
||||||
data.includes("encode") ? "ENCODING ERROR => " : "DECODING ERROR => ",
|
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."
|
"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 () => {
|
const selectImageHandler = async () => {
|
||||||
resetImagePaths();
|
resetImagePaths();
|
||||||
|
|
||||||
var path = await window.electron.invoke(commands.SELECT_FILE);
|
var path = await window.electron.invoke(commands.SELECT_FILE);
|
||||||
|
|
||||||
if (path !== "cancelled") {
|
if (path !== "cancelled") {
|
||||||
@ -110,7 +116,10 @@ const Home = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectFolderHandler = async () => {
|
const selectFolderHandler = async () => {
|
||||||
|
resetImagePaths();
|
||||||
|
|
||||||
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
var path = await window.electron.invoke(commands.SELECT_FOLDER);
|
||||||
|
|
||||||
if (path !== "cancelled") {
|
if (path !== "cancelled") {
|
||||||
setBatchFolderPath(path);
|
setBatchFolderPath(path);
|
||||||
SetOutputPath(path + "_upscayled");
|
SetOutputPath(path + "_upscayled");
|
||||||
@ -271,11 +280,18 @@ const Home = () => {
|
|||||||
<ProgressBar progress={progress} />
|
<ProgressBar progress={progress} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{imagePath.length === 0 && batchFolderPath.length === 0 ? (
|
{((!batchMode &&
|
||||||
<RightPaneInfo version={version} />
|
imagePath.length === 0 &&
|
||||||
) : upscaledImagePath.length === 0 &&
|
upscaledImagePath.length === 0) ||
|
||||||
upscaledBatchFolderPath.length === 0 ? (
|
(batchMode &&
|
||||||
!batchMode ? (
|
batchFolderPath.length === 0 &&
|
||||||
|
upscaledBatchFolderPath.length === 0)) && (
|
||||||
|
<RightPaneInfo version={version} batchMode={batchMode} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!batchMode &&
|
||||||
|
upscaledImagePath.length === 0 &&
|
||||||
|
imagePath.length > 0 && (
|
||||||
<img
|
<img
|
||||||
className="h-full w-full object-contain"
|
className="h-full w-full object-contain"
|
||||||
src={
|
src={
|
||||||
@ -285,46 +301,78 @@ const Home = () => {
|
|||||||
draggable="false"
|
draggable="false"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
) : (
|
)}
|
||||||
|
|
||||||
|
{batchMode &&
|
||||||
|
upscaledBatchFolderPath.length === 0 &&
|
||||||
|
batchFolderPath.length > 0 && (
|
||||||
<p className="select-none font-bold text-neutral-50">
|
<p className="select-none font-bold text-neutral-50">
|
||||||
Selected folder: {batchFolderPath}
|
Selected folder: {batchFolderPath}
|
||||||
</p>
|
</p>
|
||||||
)
|
)}
|
||||||
) : !batchMode ? (
|
|
||||||
<ReactCompareSlider
|
{batchMode && upscaledBatchFolderPath.length > 0 && (
|
||||||
itemOne={
|
|
||||||
<ReactCompareSliderImage
|
|
||||||
src={"file://" + imagePath}
|
|
||||||
alt="Original"
|
|
||||||
style={{
|
|
||||||
objectFit: "contain",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
itemTwo={
|
|
||||||
<ReactCompareSliderImage
|
|
||||||
src={"file://" + upscaledImagePath}
|
|
||||||
alt="Upscayl"
|
|
||||||
style={{
|
|
||||||
objectFit: "contain",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
className="h-screen"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<>
|
<>
|
||||||
<p className="select-none py-4 font-bold text-neutral-50">
|
<p className="select-none py-4 font-bold text-neutral-50">
|
||||||
Finished Upscaling Folder!
|
All done!
|
||||||
</p>
|
</p>
|
||||||
<button
|
<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}
|
onClick={openFolderHandler}
|
||||||
>
|
>
|
||||||
Open Upscayled Folder
|
Open Upscayled Folder
|
||||||
</button>
|
</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>
|
||||||
</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 {
|
.bg-gradient {
|
||||||
@apply bg-gradient-to-br from-green-500 to-lime-300 hover:from-lime-300 hover:to-green-500;
|
@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 {
|
.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 |