From 2350d3525d77ae203a45039a42d2543ac455e60f Mon Sep 17 00:00:00 2001 From: Chung-il Jung Date: Sat, 23 Dec 2023 23:51:53 +0900 Subject: [PATCH 1/3] feat: add unique color option to extractRGBAs --- packages/image/src/extractRGBAs.ts | 55 ++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/packages/image/src/extractRGBAs.ts b/packages/image/src/extractRGBAs.ts index b1d6ca2..5e4710f 100644 --- a/packages/image/src/extractRGBAs.ts +++ b/packages/image/src/extractRGBAs.ts @@ -1,28 +1,26 @@ type RGBA = readonly [number, number, number, number]; -type ExtractRGBAsOptions = { quality: number }; -const initialOptions: ExtractRGBAsOptions = { quality: 100 }; +type RGBAProcessor = (rgbaArray: RGBA[]) => RGBA[]; +type ExtractRGBAsOptions = { quality?: number; unique?: boolean }; +const initialOptions: ExtractRGBAsOptions = { + quality: 100, + unique: false, +}; /** * Filters and extracts relevant pixels from image data based on quality setting. * @param image - The image data. * @param [options] - The options to define the quality of extraction. - * @throws Will throw an error if quality is not between 1 and 100. * @returns An array of RGBA values. */ export const extractRGBAs = ( image: HTMLImageElement, options = initialOptions, ) => { - if (options.quality < 1 || options.quality > 100) { - throw new Error("options.quality should be between 1 and 100"); - } const uint8ClampedArray = extractUint8ClampedArray(image); - const step = Math.ceil(100 / options.quality); - - return Array.from({ - length: Math.ceil(uint8ClampedArray.length / (4 * step)), + const rgbaArray = Array.from({ + length: Math.ceil(uint8ClampedArray.length / 4), }).map((_, index) => { - const rIndex = index * 4 * step; + const rIndex = index * 4; return [ uint8ClampedArray[rIndex], @@ -31,6 +29,15 @@ export const extractRGBAs = ( uint8ClampedArray[rIndex + 3], ] as RGBA; }); + + const pipelineFunctions = [ + ...((options.quality as number) < 100 + ? [applyQuality(options.quality as number)] + : []), + ...(options.unique ? [applyUnique] : []), + ]; + + return pipeline(...pipelineFunctions)(rgbaArray); }; /** @@ -56,3 +63,29 @@ const extractUint8ClampedArray = (image: HTMLImageElement) => { canvas.height, ).data; }; + +const pipeline = + (...functions: RGBAProcessor[]) => + (input: RGBA[]) => + functions.reduce((acc, func) => func(acc), input); + +const applyQuality = (quality: number) => (rgbaArray: RGBA[]) => { + const step = Math.ceil(100 / quality); + + return rgbaArray.filter((_, index) => index % step === 0); +}; + +const applyUnique = (rgbaArray: RGBA[]) => { + const uniqueSet = new Set(); + + return rgbaArray.filter((rgba) => { + const key = rgba.join(","); + if (!uniqueSet.has(key)) { + uniqueSet.add(key); + + return true; + } + + return false; + }); +}; From 0f072f0d0f4111d5619aa61af9523dc297690847 Mon Sep 17 00:00:00 2001 From: Chung-il Jung Date: Sun, 24 Dec 2023 00:09:06 +0900 Subject: [PATCH 2/3] fix: applyQuality function boundary --- packages/image/src/extractRGBAs.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/image/src/extractRGBAs.ts b/packages/image/src/extractRGBAs.ts index 5e4710f..c921418 100644 --- a/packages/image/src/extractRGBAs.ts +++ b/packages/image/src/extractRGBAs.ts @@ -30,12 +30,7 @@ export const extractRGBAs = ( ] as RGBA; }); - const pipelineFunctions = [ - ...((options.quality as number) < 100 - ? [applyQuality(options.quality as number)] - : []), - ...(options.unique ? [applyUnique] : []), - ]; + const pipelineFunctions = [applyQuality(options.quality), applyUnique]; return pipeline(...pipelineFunctions)(rgbaArray); }; @@ -69,11 +64,17 @@ const pipeline = (input: RGBA[]) => functions.reduce((acc, func) => func(acc), input); -const applyQuality = (quality: number) => (rgbaArray: RGBA[]) => { - const step = Math.ceil(100 / quality); +const applyQuality = + (quality = 100) => + (rgbaArray: RGBA[]) => { + if (quality < 1 || quality > 100) { + throw new Error("options.quality should be between 1 and 100"); + } - return rgbaArray.filter((_, index) => index % step === 0); -}; + const step = Math.ceil(100 / quality); + + return rgbaArray.filter((_, index) => index % step === 0); + }; const applyUnique = (rgbaArray: RGBA[]) => { const uniqueSet = new Set(); From 75690d31daaf4c52740456b8bd0fdea1a9877e79 Mon Sep 17 00:00:00 2001 From: Chung-il Jung Date: Sun, 24 Dec 2023 00:16:40 +0900 Subject: [PATCH 3/3] Create two-ladybugs-joke.md --- .changeset/two-ladybugs-joke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/two-ladybugs-joke.md diff --git a/.changeset/two-ladybugs-joke.md b/.changeset/two-ladybugs-joke.md new file mode 100644 index 0000000..526d76e --- /dev/null +++ b/.changeset/two-ladybugs-joke.md @@ -0,0 +1,5 @@ +--- +"@fepack/image": patch +--- + +feat(image): add unique color option to extractRGBAs