mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(upscale): auto-orient images before upscaling and improve UI
Fix rotated output by calling autoOrient() before passing images to the Python upscaler, correcting EXIF orientation metadata. Replace 2x/4x buttons with 2x-8x slider plus quick-select buttons (2x, 3x, 4x, 6x, 8x). Remove technical jargon about Real-ESRGAN/Lanczos from the UI and progress bar.
This commit is contained in:
@@ -3,6 +3,7 @@ import { writeFile } from "node:fs/promises";
|
|||||||
import { basename, join } from "node:path";
|
import { basename, join } from "node:path";
|
||||||
import { upscale } from "@stirling-image/ai";
|
import { upscale } from "@stirling-image/ai";
|
||||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||||
|
import { autoOrient } from "../../lib/auto-orient.js";
|
||||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||||
import { createWorkspace } from "../../lib/workspace.js";
|
import { createWorkspace } from "../../lib/workspace.js";
|
||||||
import { updateSingleFileProgress } from "../progress.js";
|
import { updateSingleFileProgress } from "../progress.js";
|
||||||
@@ -54,6 +55,9 @@ export function registerUpscale(app: FastifyInstance) {
|
|||||||
const settings = settingsRaw ? JSON.parse(settingsRaw) : {};
|
const settings = settingsRaw ? JSON.parse(settingsRaw) : {};
|
||||||
const scale = Number(settings.scale) || 2;
|
const scale = Number(settings.scale) || 2;
|
||||||
|
|
||||||
|
// Auto-orient to fix EXIF rotation before upscaling
|
||||||
|
fileBuffer = await autoOrient(fileBuffer);
|
||||||
|
|
||||||
const jobId = randomUUID();
|
const jobId = randomUUID();
|
||||||
const workspacePath = await createWorkspace(jobId);
|
const workspacePath = await createWorkspace(jobId);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { ProgressCard } from "@/components/common/progress-card";
|
|||||||
import { useToolProcessor } from "@/hooks/use-tool-processor";
|
import { useToolProcessor } from "@/hooks/use-tool-processor";
|
||||||
import { useFileStore } from "@/stores/file-store";
|
import { useFileStore } from "@/stores/file-store";
|
||||||
|
|
||||||
|
const QUICK_SCALES = [2, 3, 4, 6, 8];
|
||||||
|
|
||||||
export function UpscaleSettings() {
|
export function UpscaleSettings() {
|
||||||
const { files } = useFileStore();
|
const { files } = useFileStore();
|
||||||
const { processFiles, processing, error, downloadUrl, originalSize, processedSize, progress } =
|
const { processFiles, processing, error, downloadUrl, originalSize, processedSize, progress } =
|
||||||
@@ -21,9 +23,12 @@ export function UpscaleSettings() {
|
|||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Scale factor */}
|
{/* Scale factor */}
|
||||||
<div>
|
<div>
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
<p className="text-sm font-medium text-muted-foreground">Scale Factor</p>
|
<p className="text-sm font-medium text-muted-foreground">Scale Factor</p>
|
||||||
<div className="flex gap-1 mt-1">
|
<span className="text-sm font-mono font-medium">{scale}x</span>
|
||||||
{[2, 4].map((s) => (
|
</div>
|
||||||
|
<div className="flex gap-1 mt-1.5">
|
||||||
|
{QUICK_SCALES.map((s) => (
|
||||||
<button
|
<button
|
||||||
key={s}
|
key={s}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -38,14 +43,17 @@ export function UpscaleSettings() {
|
|||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min={2}
|
||||||
|
max={8}
|
||||||
|
step={1}
|
||||||
|
value={scale}
|
||||||
|
onChange={(e) => setScale(Number(e.target.value))}
|
||||||
|
className="w-full mt-2"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Info */}
|
|
||||||
<p className="text-[10px] text-muted-foreground">
|
|
||||||
Uses Real-ESRGAN for AI upscaling when available, otherwise falls back to high-quality
|
|
||||||
Lanczos interpolation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Error */}
|
{/* Error */}
|
||||||
{error && <p className="text-xs text-red-500">{error}</p>}
|
{error && <p className="text-xs text-red-500">{error}</p>}
|
||||||
|
|
||||||
@@ -63,7 +71,6 @@ export function UpscaleSettings() {
|
|||||||
active={processing}
|
active={processing}
|
||||||
phase={progress.phase === "idle" ? "uploading" : progress.phase}
|
phase={progress.phase === "idle" ? "uploading" : progress.phase}
|
||||||
label="Upscaling image"
|
label="Upscaling image"
|
||||||
stage={progress.stage}
|
|
||||||
percent={progress.percent}
|
percent={progress.percent}
|
||||||
elapsed={progress.elapsed}
|
elapsed={progress.elapsed}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user