Rotate wall frame portrait, letterbox feed to frame window

This commit is contained in:
2026-09-08 18:14:25 +07:00
parent a1769e8c84
commit a16c8734a8
3 changed files with 73 additions and 47 deletions
+16 -10
View File
@@ -7,7 +7,7 @@ import { Recipe, GPSInfo, FrameId } from '../types';
import { getSkiaColorMatrix, applyExposureGain } from './colorUtils';
import { TONE_SKSL, getToneUniforms, toneIsActive } from './toneShader';
import { CINEMA_SKSL, getCinemaUniforms, cinemaIsActive } from './cinemaShader';
import { drawFrameOnCanvas, polaroidLayout, POLAROID_CARD, POLAROID_WIN_W, wallframeLayout, WALLFRAME_IMG_W, WALLFRAME_IMG_H } from './frameUtils';
import { drawFrameOnCanvas, polaroidLayout, POLAROID_CARD, POLAROID_WIN_W, wallframeLayout, WALLFRAME_W, WALLFRAME_H } from './frameUtils';
import { patchJpegDpi } from './jpegDpi';
export interface ExportResult {
@@ -260,10 +260,11 @@ export async function processAndExportPhoto(
// processed picture is composited, uncropped, into the window of a bigger
// off-white card (real print proportions, see frameUtils) — the export IS
// the card, with the photo scaled to the window so it keeps ~WIN_W of the
// card width. WALL FRAME: the export IS the frame PNG at native resolution,
// with the photo cover-cropped (center) into the fixed 3:2 window (the mat
// opening of a real frame). Other frames (classic white border, legacy
// cinematic bars) draw over the photo-sized canvas as before.
// card width. WALL FRAME: the export IS the ROTATED frame PNG at its native
// portrait size (WALLFRAME_W x WALLFRAME_H), with the photo cover-cropped
// (center) into the fixed 2:3 window (the mat opening of a real frame).
// Other frames (classic white border, legacy cinematic bars) draw over the
// photo-sized canvas as before.
let outputSurface: SkSurface = surface;
let stampCanvas = canvas;
let stampW = width;
@@ -306,13 +307,13 @@ export async function processAndExportPhoto(
stampH = outH;
framedWindow = win;
} else if (frameId === 'wallframe') {
// Export at the PNG's native resolution: the mat artwork stays crisp and
// the photo crop inside the window is as large as the asset allows.
// Export at the ROTATED frame's native size (the frame is the product, so
// the file is exactly frame-sized — never the photo's own dimensions).
const photoImg = surface.makeImageSnapshot();
const pw = photoImg.width();
const ph = photoImg.height();
const outW = WALLFRAME_IMG_W;
const outH = WALLFRAME_IMG_H;
const outW = WALLFRAME_W; // 3117
const outH = WALLFRAME_H; // 4000
const cardSurface = createSurface(outW, outH);
if (!cardSurface) {
console.error('Failed to create wallframe surface');
@@ -350,8 +351,13 @@ export async function processAndExportPhoto(
plainPaint
);
// Artwork over the crop: its transparent window reveals the photo, the
// mat covers the rest.
// mat covers the rest. The source PNG is landscape — rotate it 90° CW
// onto the portrait canvas (same affine as wallframeLayout.drawMatrix).
cardCanvas.save();
cardCanvas.translate(outW, 0);
cardCanvas.rotate(90, 0, 0);
cardCanvas.drawImage(wfImage, 0, 0, plainPaint);
cardCanvas.restore();
outputSurface = cardSurface;
stampCanvas = cardCanvas;
stampW = outW;