Druckfertig: 4× hochskalieren, auf Seitenverhältnis beschneiden, herunterrechnen
Beispiel für ein Werkzeug-Plugin. mlcupscale vergrößert das Foto vierfach mit einem eingebetteten Real-ESRGAN-Modell, danach beschneidet das Skript auf das gewünschte Seitenverhältnis und rechnet auf die Zielgröße herunter — erst vergrößern hält die Kanten sauber.
INPUT
OUTPUT
JavaScript
// Print-ready upscale via mlcupscale (4× Real-ESRGAN) + crop-to-aspect + downscale
// tool_upscale_print.js
//!INPUT: INPUT
//!OUTPUT: OUTPUT
//!PARAM: ASPECT:enum(source|3:2|2:3|4:3|3:4|16:9|9:16|1:1)=3:2
//!PARAM: TARGET_MIN:integer=2048,min=1024,max=4096,step=256
// Goal: turn any reasonably-sized source photo into a print-ready
// asset. mlcupscale is hard-coded to 4× (embedded Real-ESRGAN model),
// so the pipeline goes:
//
// 1. Center-crop to ASPECT (so we don't waste neural-net cycles on
// pixels we'd throw away later).
// 2. 4× AI upscale.
// 3. Downscale to TARGET_MIN px on the shorter side (with Lanczos
// for clean print edges).
//
// Typical settings:
// - 3:2, TARGET_MIN=2048 → 3072×2048 (~6 MP, A4 @ 300dpi prints ~6.8")
// - 3:2, TARGET_MIN=3000 → 4500×3000 (~13.5 MP, A4 @ 300dpi prints ~10")
// - 1:1, TARGET_MIN=2048 → 2048×2048 (square, Instagram-style print)
const src = Engine.loadImage(INPUT);
const startMs = Engine.elapsed();
Engine.log(`source: ${src.width}×${src.height}`);
// ── 1. Center-crop to ASPECT (skipped when ASPECT="source") ─────────
let cw = src.width;
let ch = src.height;
if (ASPECT !== 'source') {
const [aw, ah] = ASPECT.split(':').map(Number);
const targetRatio = aw / ah;
const srcRatio = cw / ch;
if (srcRatio > targetRatio) {
// source is wider → trim sides
cw = Math.round(ch * targetRatio);
} else {
// source is taller → trim top/bottom
ch = Math.round(cw / targetRatio);
}
}
const cx = Math.round((src.width - cw) / 2);
const cy = Math.round((src.height - ch) / 2);
const cropped = src.clone().crop(cx, cy, cw, ch);
Engine.log(`cropped (${ASPECT}): ${cropped.width}×${cropped.height}`);
// ── 2. 4× AI upscale via mlcupscale ─────────────────────────────────
// First run takes ~2–5 s on a typical CPU (model init is hot the
// second time). Output is exactly 4× the input dims.
const x4 = Engine.tool('mlcupscale').apply(cropped, {});
Engine.log(`upscaled 4×: ${x4.width}×${x4.height}`);
// ── 3. Downscale to TARGET_MIN on the shorter side ──────────────────
const minSide = Math.min(x4.width, x4.height);
const factor = TARGET_MIN / minSide;
const finalW = Math.round(x4.width * factor);
const finalH = Math.round(x4.height * factor);
// Lanczos for print — sharper edges than Bicubic at the cost of
// occasional ringing on hard contrast (worth it for 300 dpi output).
const out = x4.clone().resize(finalW, finalH, Interp.Lanczos);
Engine.log(`final: ${finalW}×${finalH} (${(finalW * finalH / 1e6).toFixed(1)} MP)`);
Engine.log(`pipeline took ${Math.round(Engine.elapsed() - startMs)} ms`);
out.save(OUTPUT);
src.free();
cropped.free();
x4.free();
out.free();