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 { upscale } from "@stirling-image/ai";
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { autoOrient } from "../../lib/auto-orient.js";
|
||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||
import { createWorkspace } from "../../lib/workspace.js";
|
||||
import { updateSingleFileProgress } from "../progress.js";
|
||||
@@ -54,6 +55,9 @@ export function registerUpscale(app: FastifyInstance) {
|
||||
const settings = settingsRaw ? JSON.parse(settingsRaw) : {};
|
||||
const scale = Number(settings.scale) || 2;
|
||||
|
||||
// Auto-orient to fix EXIF rotation before upscaling
|
||||
fileBuffer = await autoOrient(fileBuffer);
|
||||
|
||||
const jobId = randomUUID();
|
||||
const workspacePath = await createWorkspace(jobId);
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { ProgressCard } from "@/components/common/progress-card";
|
||||
import { useToolProcessor } from "@/hooks/use-tool-processor";
|
||||
import { useFileStore } from "@/stores/file-store";
|
||||
|
||||
const QUICK_SCALES = [2, 3, 4, 6, 8];
|
||||
|
||||
export function UpscaleSettings() {
|
||||
const { files } = useFileStore();
|
||||
const { processFiles, processing, error, downloadUrl, originalSize, processedSize, progress } =
|
||||
@@ -21,9 +23,12 @@ export function UpscaleSettings() {
|
||||
<div className="space-y-4">
|
||||
{/* Scale factor */}
|
||||
<div>
|
||||
<p className="text-sm font-medium text-muted-foreground">Scale Factor</p>
|
||||
<div className="flex gap-1 mt-1">
|
||||
{[2, 4].map((s) => (
|
||||
<div className="flex justify-between items-center">
|
||||
<p className="text-sm font-medium text-muted-foreground">Scale Factor</p>
|
||||
<span className="text-sm font-mono font-medium">{scale}x</span>
|
||||
</div>
|
||||
<div className="flex gap-1 mt-1.5">
|
||||
{QUICK_SCALES.map((s) => (
|
||||
<button
|
||||
key={s}
|
||||
type="button"
|
||||
@@ -38,14 +43,17 @@ export function UpscaleSettings() {
|
||||
</button>
|
||||
))}
|
||||
</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>
|
||||
|
||||
{/* 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 && <p className="text-xs text-red-500">{error}</p>}
|
||||
|
||||
@@ -63,7 +71,6 @@ export function UpscaleSettings() {
|
||||
active={processing}
|
||||
phase={progress.phase === "idle" ? "uploading" : progress.phase}
|
||||
label="Upscaling image"
|
||||
stage={progress.stage}
|
||||
percent={progress.percent}
|
||||
elapsed={progress.elapsed}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user