feat: image cropping / resizing T0

This commit is contained in:
fsylvain committed 2026-09-28 07:46:12 +02:00
1 parent cb05b38f36
commit e15f444603
18 files changed
+1869 -46

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
import { describe, expect, it } from 'vitest'
import {
computeOutputSize,
estimateOutputBytes,
formatEstimatedSize,
rectForRatio,
rotateRectBySteps,
rotatedDimensions,
wholeRect,
} from '../imageCrop'
describe('rectForRatio', () => {
it('centers a 16:9 crop inside a 4032x3024 image', () => {
const rect = rectForRatio('16:9', 4032, 3024)
expect(rect).toEqual({ x: 0, y: 378, width: 4032, height: 2268 })
})
it('centers a 1:1 crop inside a 4032x3024 image', () => {
const rect = rectForRatio('1:1', 4032, 3024)
expect(rect).toEqual({ x: 504, y: 0, width: 3024, height: 3024 })
})
it('returns the whole image for Original', () => {
expect(rectForRatio('Original', 4032, 3024)).toEqual(wholeRect(4032, 3024))
})
})
describe('computeOutputSize', () => {
it('never upscales past the crop width', () => {
expect(computeOutputSize(640, 640, 1600)).toEqual({ width: 640, height: 640 })
})
it('caps to the width preset when the crop is larger', () => {
expect(computeOutputSize(4032, 3024, 1600)).toEqual({ width: 1600, height: 1200 })
})
})
describe('estimateOutputBytes', () => {
it('estimates 420 KB for the default 1600x1200 output', () => {
expect(formatEstimatedSize(estimateOutputBytes(1600, 1200))).toBe('420 KB')
})
})
describe('rotateRectBySteps', () => {
it('rotates a whole-image rect 90deg clockwise into the new bounds', () => {
const rotated = rotateRectBySteps(wholeRect(4032, 3024), 4032, 3024, 1)
expect(rotated).toEqual({ x: 0, y: 0, width: 3024, height: 4032 })
})
it('round-trips back to the original after four steps', () => {
const rect = { x: 42, y: 34, width: 500, height: 300 }
const rotated = rotateRectBySteps(rect, 4032, 3024, 4)
expect(rotated).toEqual(rect)
})
})
describe('rotatedDimensions', () => {
it('swaps dimensions for a 90deg rotation', () => {
expect(rotatedDimensions(4032, 3024, 90)).toEqual({ width: 3024, height: 4032 })
})
it('keeps dimensions for a 180deg rotation', () => {
expect(rotatedDimensions(4032, 3024, 180)).toEqual({ width: 4032, height: 3024 })
})
})