web: the eyedropper reads a colour and the mixer moves that hue band
This commit is contained in:
@@ -31,6 +31,25 @@ export async function resizedJpeg(bytes: Uint8Array, maxDim: number, quality = 0
|
||||
}
|
||||
}
|
||||
|
||||
// The colour under one point of a photo, for the HSL mixer's eyedropper.
|
||||
// `fx`/`fy` are fractions of the photo (0..1, from the click position over the
|
||||
// <img>), so the caller needs no knowledge of the stage's zoom, pan or box.
|
||||
// One pixel, read straight off the RENDER — the swatch then shows the colour
|
||||
// the user is actually looking at, grade and all, which is what makes the
|
||||
// band the eyedropper lands on the one they meant.
|
||||
export function samplePixel(bitmap: ImageBitmap, fx: number, fy: number): { r: number; g: number; b: number } {
|
||||
const sx = Math.min(bitmap.width - 1, Math.max(0, Math.floor(fx * bitmap.width)));
|
||||
const sy = Math.min(bitmap.height - 1, Math.max(0, Math.floor(fy * bitmap.height)));
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 1;
|
||||
canvas.height = 1;
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
if (!ctx) return { r: 0, g: 0, b: 0 };
|
||||
ctx.drawImage(bitmap, sx, sy, 1, 1, 0, 0, 1, 1);
|
||||
const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
||||
return { r, g, b };
|
||||
}
|
||||
|
||||
// Uploads are capped by the API (and by nginx in front of it), so a phone's
|
||||
// 12MP JPEG has to shrink before it goes up — the same downscale the preview
|
||||
// uses. The ORIGINAL bytes come back untouched (same reference) when the photo
|
||||
|
||||
Reference in New Issue
Block a user