Skip to content

fit-screenshot

Fits a screenshot onto a canvas of a different aspect ratio without cropping it or distorting it, filling the leftover margins with a blurred, enlarged copy of the same image (the “pillarbox” treatment used by store listings).

The motivating case is a mobile store screenshot. The Android emulator’s framebuffer is whatever the AVD’s screen is — a Pixel 10 Pro XL is 1344x2992, roughly 9:20 — while the community store asks for 900x1600 (9:16). Cropping to 9:16 throws away a fifth of the frame, and stretching distorts the UI, so the image is scaled to fit the HEIGHT and the two side margins are filled.

The geometry is a pure function so it can be unit-tested; the pixel work needs sharp, which is an OPTIONAL peer dependency — declared rather than bundled because only screenshot capture needs it, and it ships platform-specific native binaries that every other consumer would pay for.

Interface Description
ComputeFitToCanvasParams Parameters for computeFitToCanvas.
FitScreenshotToCanvasOptions Options for fitScreenshotToCanvas.
FitToCanvasGeometry Where the scaled source image sits on the canvas.
Function Description
computeFitToCanvas Computes how a source image is scaled and placed to fill a canvas’s height, with equal margins on the left and right. The scaled width is rounded to the nearest integer that leaves an EVEN remainder, so the two margins are exactly equal — an asymmetric pillarbox is visible at a glance and looks like a mistake. Where both neighbors qualify, the one closer to the true scaled width wins, so the aspect error stays below one part in a thousand. Worked example, the mobile store case: a 1344x2992 frame onto a 900x1600 canvas scales by 1600/2992 to 718.72 wide. 719 would leave a 181px remainder, which cannot split evenly, so 718 is chosen (margin 91) over 720 (margin 90) because 718 is nearer 718.72.
fitScreenshotToCanvas Scales a screenshot to fill a canvas’s height and fills the side margins with a blurred, enlarged copy of the same image. Nothing is cropped and nothing is stretched: the visible screenshot keeps its aspect ratio to within a rounding pixel, and the margins are made of the image itself rather than a flat color, so the result reads as one frame.