UNPKG

extract-colors

Version:

Extract color palettes from images

1 lines 9.13 kB
{"version":3,"file":"worker-wrapper.cjs","sources":["../src/workerWrapper.ts","../src/extract/cleanInputs.ts"],"sourcesContent":["import WorkerWrapper from \"./worker?worker&inline\";\nimport cleanInputs, { testInputs } from \"./extract/cleanInputs\";\nimport type { BrowserOptions, ImageDataAlt } from \"./types/Options\";\nimport type { FinalColor } from \"./types/Color\";\n\n/**\n * Extract colors from a picture with Web Worker support.\n *\n * @param picture image source or image data\n * @param options Process configuration\n * @param options.pixels Total pixel number of the resized picture for calculation\n * @param options.distance From 0 to 1 is the color distance to not have near colors (1 distance is between white and black)\n * @param options.colorValidator Test function to enable only some colors\n * @param options.saturationDistance Minimum saturation value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.lightnessDistance inimum lightness value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.hueDistance inimum hue value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.requestMode support for CORS (only for Web Workers in browser)\n *\n * @returns List of extracted colors\n */\nexport const extractColors = (\n picture: string | ImageData | ImageDataAlt,\n options?: BrowserOptions\n) => {\n if (__DEV__) {\n testInputs(options);\n }\n\n if (picture instanceof HTMLImageElement) {\n if (__DEV__) {\n console.warn(\n \"HTMLImageElement not enable on worker, please send 'src' or image data instead HTMLImageElement\"\n );\n }\n\n // HTMLImageElement not enable on Worker, switch to src fallback\n picture = picture.src;\n }\n\n const [_pixels, _distance, _colorValidator, ..._cleanInputsRest] =\n cleanInputs(options);\n\n // Wrap worker inside Promise\n return new Promise<FinalColor[]>((resolve, reject) => {\n try {\n const worker: Worker = new WorkerWrapper();\n worker.postMessage([\n picture,\n [_pixels, _distance, _colorValidator.toString(), ..._cleanInputsRest],\n ]);\n worker.addEventListener(\"message\", (message) => {\n resolve(message.data);\n worker.terminate();\n });\n worker.addEventListener(\"error\", (error) => {\n reject(error);\n worker.terminate();\n });\n } catch (error) {\n reject(error);\n }\n });\n};\n","import { BrowserOptions, OptionsCleaned } from \"../types/Options\";\n\n/**\n * Default extractor values\n */\nexport const EXTRACTOR_PIXELS_DEFAULT = 64000;\nexport const EXTRACTOR_DISTANCE_DEFAULT = 0.22;\n\n/**\n * Default average values\n */\nexport const AVERAGE_HUE_DEFAULT = 1 / 12;\nexport const AVERAGE_SATURATION_DEFAULT = 1 / 5;\nexport const AVERAGE_LIGHTNESS_DEFAULT = 1 / 5;\n\nexport function testInputs({\n pixels = EXTRACTOR_PIXELS_DEFAULT,\n distance = EXTRACTOR_DISTANCE_DEFAULT,\n colorValidator = (\n _red: number,\n _green: number,\n _blue: number,\n _alpha?: number\n ) => (_alpha ?? 255) > 250,\n hueDistance = AVERAGE_HUE_DEFAULT,\n saturationDistance = AVERAGE_LIGHTNESS_DEFAULT,\n lightnessDistance = AVERAGE_SATURATION_DEFAULT,\n crossOrigin = \"\",\n requestMode = \"cors\",\n}: BrowserOptions = {}) {\n /**\n * Test if value is an integer.\n */\n const testUint = (\n label: string,\n val: number,\n min = 0,\n max = Number.MAX_SAFE_INTEGER\n ) => {\n if (!Number.isInteger(val)) {\n throw new Error(`${label} is not a valid number (${val})`);\n }\n\n if (val < min) {\n console.warn(`${label} can not be less than ${min} (it's ${val})`);\n }\n\n if (val > max) {\n console.warn(`${label} can not be more than ${max} (it's ${val})`);\n }\n\n return Math.min(Math.max(val, min), max);\n };\n\n /**\n * Test if value is a number.\n */\n const testNumber = (\n label: string,\n val: number,\n min = 0,\n max = Number.MAX_VALUE\n ) => {\n if (Number(val) !== val) {\n throw new Error(`${label} is not a valid number (${val})`);\n }\n\n if (val < min) {\n console.warn(`${label} can not be less than ${min} (it's ${val})`);\n }\n\n if (val > max) {\n console.warn(`${label} can not be more than ${max} (it's ${val})`);\n }\n\n return Math.min(Math.max(val, min), max);\n };\n\n /**\n * Test if value is a function.\n */\n const testFunction = <T = () => void>(label: string, val: T) => {\n if (!val || {}.toString.call(val) !== \"[object Function]\") {\n throw new Error(`${label} is not a function (${val})`);\n }\n\n return val;\n };\n\n /**\n * Test if value is in the list of values\n */\n const testValueInList = <T>(label: string, val: T, list: T[]) => {\n if (list.indexOf(val) < 0) {\n console.warn(\n `${label} can be one of this values ${list\n .map((v) => `\"${v}\"`)\n .join(\", \")} (it's \"${val}\")`\n );\n }\n };\n\n testUint(\"pixels\", pixels || 0, 1);\n testNumber(\"distance\", distance, 0, 1);\n testFunction(\"colorValidator\", colorValidator);\n testNumber(\"hueDistance\", hueDistance, 0, 1);\n testNumber(\"saturationDistance\", saturationDistance, 0, 1);\n testNumber(\"lightnessDistance\", lightnessDistance, 0, 1);\n testValueInList(\"crossOrigin\", crossOrigin, [\n \"\",\n \"anonymous\",\n \"use-credentials\",\n ]);\n testValueInList(\"requestMode\", requestMode, [\n \"cors\",\n \"navigate\",\n \"no-cors\",\n \"same-origin\",\n ]);\n}\n\nexport default ({\n pixels = EXTRACTOR_PIXELS_DEFAULT,\n distance = EXTRACTOR_DISTANCE_DEFAULT,\n colorValidator = (\n _red: number,\n _green: number,\n _blue: number,\n _alpha?: number\n ) => (_alpha ?? 255) > 250,\n hueDistance = AVERAGE_HUE_DEFAULT,\n saturationDistance = AVERAGE_LIGHTNESS_DEFAULT,\n lightnessDistance = AVERAGE_SATURATION_DEFAULT,\n crossOrigin = \"\",\n requestMode = \"cors\",\n}: BrowserOptions = {}): OptionsCleaned => {\n return [\n Math.max(pixels, 1),\n Math.min(Math.max(distance, 0), 1),\n colorValidator,\n Math.min(Math.max(hueDistance, 0), 1),\n Math.min(Math.max(saturationDistance, 0), 1),\n Math.min(Math.max(lightnessDistance, 0), 1),\n crossOrigin,\n requestMode,\n ];\n};\n"],"names":["picture","options","__DEV__","pixels","distance","colorValidator","_red","_green","_blue","_alpha","hueDistance","AVERAGE_HUE_DEFAULT","saturationDistance","lightnessDistance","crossOrigin","requestMode","testNumber","label","val","min","max","Number","MAX_VALUE","Error","console","warn","Math","testValueInList","list","indexOf","map","v","join","MAX_SAFE_INTEGER","isInteger","testUint","toString","call","testFunction","testInputs","HTMLImageElement","src","_pixels","_distance","_colorValidator","_cleanInputsRest","cleanInputs","Promise","resolve","reject","worker","WorkerWrapper","postMessage","addEventListener","message","data","terminate","error"],"mappings":"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"}