feat(frame): give ROTATE quarter turns plus a fine straighten
This commit is contained in:
@@ -25,3 +25,44 @@ export function rotateSkImage90(image: SkImage | null): SkImage | null {
|
||||
canvas.drawImage(image, 0, 0);
|
||||
return surface.makeImageSnapshot() ?? image;
|
||||
}
|
||||
|
||||
// Fine rotation about the centre (the FRAME tab's STRAIGHTEN), keeping the
|
||||
// original pixel dimensions: the content is scaled up just enough that the
|
||||
// rotated rectangle still covers the frame, so no empty corner shows. The
|
||||
// scale is the axis-aligned wrap of the counter-rotated frame — slightly
|
||||
// conservative, which crops a hair more rather than leaking a corner.
|
||||
// ponytail: one offscreen surface per call, same trade as rotateSkImage90.
|
||||
export function rotateSkImageBy(image: SkImage | null, degrees: number): SkImage | null {
|
||||
if (!image) return null;
|
||||
const w = image.width();
|
||||
const h = image.height();
|
||||
if (!(w > 0 && h > 0)) return null;
|
||||
if (!degrees) return image;
|
||||
const rad = (degrees * Math.PI) / 180;
|
||||
const cos = Math.abs(Math.cos(rad));
|
||||
const sin = Math.abs(Math.sin(rad));
|
||||
const k = Math.max((w * cos + h * sin) / w, (w * sin + h * cos) / h);
|
||||
const surface = Skia.Surface.Make(w, h);
|
||||
if (!surface) return image; // keep the unrotated photo on allocation failure
|
||||
const canvas = surface.getCanvas();
|
||||
canvas.clear(Skia.Color('transparent'));
|
||||
canvas.translate(w / 2, h / 2);
|
||||
canvas.rotate(degrees, 0, 0);
|
||||
canvas.scale(k, k);
|
||||
canvas.drawImage(image, -w / 2, -h / 2);
|
||||
return surface.makeImageSnapshot() ?? image;
|
||||
}
|
||||
|
||||
// The whole FRAME-tab photo orientation in one call: the quarter turn first
|
||||
// (rotateSkImage90 swaps the pixel dimensions, which then propagates through
|
||||
// every consumer unchanged), then the fine STRAIGHTEN on top of it.
|
||||
export function applyPhotoRotation(
|
||||
image: SkImage | null,
|
||||
quarter = 0,
|
||||
straighten = 0
|
||||
): SkImage | null {
|
||||
let out = image;
|
||||
for (let i = 0; i < Math.round(quarter / 90) % 4; i++) out = rotateSkImage90(out);
|
||||
if (straighten) out = rotateSkImageBy(out, straighten);
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user