Skip to content
File

Blob: src/types.ts

typescript94 lines
1export type ExportFormat = "jpeg" | "webp" | "png" | "avif";
2 
3/** A rectangle in source-image pixel space (matches react-easy-crop's croppedAreaPixels). */
4export interface PixelRect {
5 x: number;
6 y: number;
7 width: number;
8 height: number;
9}
10 
11/** Color adjustments mapping 1:1 to CSS/canvas filter functions. */
12export interface Adjustments {
13 brightness: number; // 1 = neutral
14 contrast: number; // 1 = neutral
15 saturate: number; // 1 = neutral
16 grayscale: number; // 0 = off … 1 = full
17 sepia: number; // 0 = off … 1 = full
18 hueRotate: number; // degrees
19}
20 
21export const NEUTRAL_ADJUSTMENTS: Adjustments = {
22 brightness: 1,
23 contrast: 1,
24 saturate: 1,
25 grayscale: 0,
26 sepia: 0,
27 hueRotate: 0,
28};
29 
30/**
31 * A preset crop + output recipe. Templates are plain data: an aspect ratio for
32 * the crop UI, a fixed output size (or null to keep the cropped resolution), and
33 * encoder defaults. `framing` is reserved for face-aware identity photos (phase 2).
34 */
35export interface Template {
36 id: string;
37 name: string;
38 group: string;
39 description: string;
40 /** Crop aspect ratio (width / height). null = match the source image's ratio. */
41 aspect: number | null;
42 /** Fixed output dimensions, or null to export at the cropped native resolution. */
43 output: { width: number; height: number } | null;
44 encoder: { format: ExportFormat; quality: number };
45 framing?: { faceHeightRatio: [number, number]; eyeLineFromTop: number };
46}
47 
48/** Everything the worker needs to produce a final image. */
49export interface ExportRequest {
50 bytes: ArrayBuffer;
51 mime: string;
52 crop: PixelRect;
53 rotation: number;
54 flipH: boolean;
55 flipV: boolean;
56 adjustments: Adjustments;
57 output: { width: number; height: number } | null;
58 /** Optional cap on the longest output edge (px); scales down proportionally. */
59 maxEdge: number | null;
60 format: ExportFormat;
61 quality: number;
62}
63 
64export interface ExportResult {
65 ok: true;
66 blob: Blob;
67 width: number;
68 height: number;
69 bytes: number;
70 format: ExportFormat;
71 /** Which pixel engine produced the transform. */
72 engine: "vips" | "canvas";
73 /** Which encoder produced the final bytes. */
74 encoder: "jsquash" | "canvas";
75}
76 
77export interface ExportError {
78 ok: false;
79 error: string;
80}
81 
82export type ExportResponse = ExportResult | ExportError;
83 
84/** Worker message envelopes (id correlates concurrent requests). */
85export interface WorkerInbound {
86 id: number;
87 request: ExportRequest;
88}
89 
90export interface WorkerOutbound {
91 id: number;
92 response: ExportResponse;
93}