colorlip 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.ja.md +394 -0
- package/README.md +324 -84
- package/dist/adapters/canvas.cjs +518 -176
- package/dist/adapters/canvas.cjs.map +1 -1
- package/dist/adapters/canvas.d.cts +15 -5
- package/dist/adapters/canvas.d.ts +15 -5
- package/dist/adapters/canvas.js +31 -7
- package/dist/adapters/canvas.js.map +1 -1
- package/dist/adapters/chunk-RJEBQW5Y.js +696 -0
- package/dist/adapters/chunk-RJEBQW5Y.js.map +1 -0
- package/dist/adapters/{core-B093HNj1.d.cts → core-RJ20zx2h.d.cts} +15 -5
- package/dist/adapters/{core-B093HNj1.d.ts → core-RJ20zx2h.d.ts} +15 -5
- package/dist/adapters/sharp.cjs +515 -185
- package/dist/adapters/sharp.cjs.map +1 -1
- package/dist/adapters/sharp.d.cts +11 -6
- package/dist/adapters/sharp.d.ts +11 -6
- package/dist/adapters/sharp.js +30 -16
- package/dist/adapters/sharp.js.map +1 -1
- package/dist/index.cjs +488 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -25
- package/dist/index.d.ts +34 -25
- package/dist/index.js +486 -170
- package/dist/index.js.map +1 -1
- package/package.json +35 -6
- package/dist/adapters/chunk-4M6GQB6M.js +0 -380
- package/dist/adapters/chunk-4M6GQB6M.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,154 +1,394 @@
|
|
|
1
1
|
# colorlip
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Perceptually tuned dominant color and palette extraction for Node.js and the browser.
|
|
4
|
+
|
|
5
|
+
`colorlip` is a lightweight, fast, TypeScript-first library for extracting dominant colors and compact palettes from images. It is tuned to pick colors that feel more visually representative, especially for illustrations, artwork, and product images where impression matters more than raw pixel counts. It is designed with visually driven use cases in mind, including illustration communities, social platforms, and commerce experiences.
|
|
6
|
+
|
|
7
|
+
[日本語版 README](./README.ja.md)
|
|
8
|
+
|
|
9
|
+

|
|
4
10
|
|
|
5
11
|
## Features
|
|
6
12
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
+
- Perceptually tuned color extraction for visually representative results
|
|
14
|
+
- Composition-aware weighting with center/border and edge-aware heuristics
|
|
15
|
+
- Adaptive palette extraction based on image statistics
|
|
16
|
+
- Natural merging of nearby colors using CIELAB Delta E
|
|
17
|
+
- Practical palette API with role-based `dominant`, `accent`, and `swatches`
|
|
18
|
+
- Rich color output: `hex`, `HSL`, `Lab`, `LCH`, `OKLab`, `OKLCH`, CSS color strings, and hue category
|
|
19
|
+
- Platform-agnostic core for raw pixel data
|
|
20
|
+
- Built-in adapters for `sharp` and Canvas
|
|
21
|
+
- Zero runtime dependencies in the core package
|
|
22
|
+
|
|
23
|
+
## Why colorlip
|
|
24
|
+
|
|
25
|
+
`colorlip` is not just a color quantizer.
|
|
26
|
+
|
|
27
|
+
Many palette extractors mainly summarize image-wide color distribution. `colorlip` is tuned to choose colors that feel important in the image, using lightweight composition-aware heuristics and perceptual color spaces.
|
|
28
|
+
|
|
29
|
+
- It adapts thresholds from the image itself instead of relying only on fixed cutoffs
|
|
30
|
+
- It uses center/border and edge-aware weighting so large background areas do not always win
|
|
31
|
+
- It merges nearby colors perceptually in Lab, then picks `dominant` and `accent` for different roles
|
|
32
|
+
- It is especially tuned for illustrations, artwork, thumbnails, and visually curated image sets
|
|
13
33
|
|
|
14
34
|
## Install
|
|
15
35
|
|
|
36
|
+
Core only:
|
|
37
|
+
|
|
16
38
|
```bash
|
|
17
39
|
npm install colorlip
|
|
18
40
|
```
|
|
19
41
|
|
|
20
|
-
|
|
42
|
+
Node.js with the `sharp` adapter:
|
|
21
43
|
|
|
22
44
|
```bash
|
|
23
45
|
npm install colorlip sharp
|
|
24
46
|
```
|
|
25
47
|
|
|
48
|
+
`sharp` is an optional peer dependency and is only required when you use `colorlip/sharp`.
|
|
49
|
+
|
|
26
50
|
## Quick Start
|
|
27
51
|
|
|
28
|
-
### Node.js
|
|
52
|
+
### Node.js
|
|
29
53
|
|
|
30
54
|
```ts
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
const colors = await
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// lch: { L: 41.2, C: 40.2, H: 266.7 },
|
|
41
|
-
// oklab: { L: 0.49, a: -0.03, b: -0.12 },
|
|
42
|
-
// oklch: { L: 0.49, C: 0.12, H: 256.7 },
|
|
43
|
-
// css: { rgb: 'rgb(42 98 168)', hsl: 'hsl(213 60% 41%)', ... }
|
|
44
|
-
// }
|
|
55
|
+
import { getColors, getPalette } from "colorlip/sharp";
|
|
56
|
+
|
|
57
|
+
const colors = await getColors("photo.jpg");
|
|
58
|
+
const palette = await getPalette("photo.jpg");
|
|
59
|
+
|
|
60
|
+
console.log(colors[0]?.hex);
|
|
61
|
+
console.log(palette.dominant?.hex);
|
|
62
|
+
console.log(palette.accent?.hex);
|
|
63
|
+
console.log(palette.swatches);
|
|
45
64
|
```
|
|
46
65
|
|
|
47
|
-
### Browser
|
|
66
|
+
### Browser
|
|
48
67
|
|
|
49
68
|
```ts
|
|
50
|
-
import {
|
|
69
|
+
import { getColors, getPalette } from "colorlip/canvas";
|
|
51
70
|
|
|
52
|
-
const colors = await
|
|
71
|
+
const colors = await getColors(imgElement);
|
|
72
|
+
const palette = await getPalette(imgElement);
|
|
53
73
|
```
|
|
54
74
|
|
|
55
|
-
### Raw
|
|
75
|
+
### Raw Pixels
|
|
56
76
|
|
|
57
77
|
```ts
|
|
58
|
-
import {
|
|
78
|
+
import { getColors, getPalette } from "colorlip";
|
|
59
79
|
|
|
60
|
-
const colors =
|
|
80
|
+
const colors = getColors(pixelData, width, height, channels);
|
|
81
|
+
const palette = getPalette(pixelData, width, height, channels);
|
|
61
82
|
```
|
|
62
83
|
|
|
84
|
+
## Package Entry Points
|
|
85
|
+
|
|
86
|
+
### `colorlip`
|
|
87
|
+
|
|
88
|
+
Core API for raw pixel buffers.
|
|
89
|
+
|
|
90
|
+
### `colorlip/sharp`
|
|
91
|
+
|
|
92
|
+
Node.js adapter backed by `sharp`. It loads the image, downsizes it, and passes raw pixels to the core.
|
|
93
|
+
|
|
94
|
+
### `colorlip/canvas`
|
|
95
|
+
|
|
96
|
+
Browser adapter backed by the Canvas API. It accepts browser image sources, draws them to a canvas, and passes `ImageData` to the core.
|
|
97
|
+
|
|
63
98
|
## API
|
|
64
99
|
|
|
65
|
-
###
|
|
100
|
+
### Core
|
|
66
101
|
|
|
67
|
-
|
|
102
|
+
```ts
|
|
103
|
+
import {
|
|
104
|
+
aggregateColors,
|
|
105
|
+
colorlip,
|
|
106
|
+
createDominantColor,
|
|
107
|
+
extractFallbackPalette,
|
|
108
|
+
getColors,
|
|
109
|
+
getHueCategory,
|
|
110
|
+
getPalette,
|
|
111
|
+
rgbToHex,
|
|
112
|
+
rgbToHsl,
|
|
113
|
+
} from "colorlip";
|
|
114
|
+
```
|
|
68
115
|
|
|
69
|
-
|
|
116
|
+
#### `getColors(data, width, height, channels, options?)`
|
|
70
117
|
|
|
71
|
-
|
|
118
|
+
Extract dominant colors from raw pixel data.
|
|
72
119
|
|
|
73
|
-
|
|
120
|
+
- `data`: `Uint8Array | Uint8ClampedArray`
|
|
121
|
+
- `width`: image width
|
|
122
|
+
- `height`: image height
|
|
123
|
+
- `channels`: typically `3` or `4`
|
|
74
124
|
|
|
75
|
-
|
|
125
|
+
Returns `ColorlipColor[]`.
|
|
76
126
|
|
|
77
|
-
|
|
127
|
+
#### `getPalette(data, width, height, channels, options?)`
|
|
78
128
|
|
|
79
|
-
|
|
129
|
+
Extract a structured palette from raw pixel data.
|
|
80
130
|
|
|
81
|
-
|
|
131
|
+
Returns:
|
|
82
132
|
|
|
83
|
-
|
|
133
|
+
```ts
|
|
134
|
+
interface ColorlipPalette {
|
|
135
|
+
dominant: ColorlipColor | null;
|
|
136
|
+
accent: ColorlipColor | null;
|
|
137
|
+
swatches: ColorlipColor[];
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### `colorlip(...)`
|
|
142
|
+
|
|
143
|
+
Compatibility alias of `getColors(...)`.
|
|
84
144
|
|
|
85
|
-
###
|
|
145
|
+
### Node.js Adapter
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import {
|
|
149
|
+
colorlip,
|
|
150
|
+
colorlipFromBuffer,
|
|
151
|
+
colorlipFromFile,
|
|
152
|
+
getColors,
|
|
153
|
+
getColorsFromPixels,
|
|
154
|
+
getPalette,
|
|
155
|
+
getPaletteFromPixels,
|
|
156
|
+
} from "colorlip/sharp";
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### `getColors(source, options?)`
|
|
160
|
+
|
|
161
|
+
- `source`: `string | Buffer | Uint8Array`
|
|
162
|
+
|
|
163
|
+
Loads an image through `sharp` and returns `Promise<ColorlipColor[]>`.
|
|
164
|
+
|
|
165
|
+
#### `getPalette(source, options?)`
|
|
166
|
+
|
|
167
|
+
- `source`: `string | Buffer | Uint8Array`
|
|
168
|
+
|
|
169
|
+
Loads an image through `sharp` and returns `Promise<ColorlipPalette>`.
|
|
170
|
+
|
|
171
|
+
#### `getColorsFromPixels(...)`
|
|
172
|
+
|
|
173
|
+
Re-export of the raw-pixel core API.
|
|
174
|
+
|
|
175
|
+
#### `getPaletteFromPixels(...)`
|
|
176
|
+
|
|
177
|
+
Re-export of the raw-pixel core palette API.
|
|
178
|
+
|
|
179
|
+
#### Legacy aliases
|
|
180
|
+
|
|
181
|
+
- `colorlipFromFile(...)`
|
|
182
|
+
- `colorlipFromBuffer(...)`
|
|
183
|
+
|
|
184
|
+
### Browser Adapter
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import {
|
|
188
|
+
colorlip,
|
|
189
|
+
colorlipFromImage,
|
|
190
|
+
colorlipFromImageData,
|
|
191
|
+
getColors,
|
|
192
|
+
getColorsFromImageData,
|
|
193
|
+
getColorsFromPixels,
|
|
194
|
+
getPalette,
|
|
195
|
+
getPaletteFromImageData,
|
|
196
|
+
getPaletteFromPixels,
|
|
197
|
+
} from "colorlip/canvas";
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `getColors(source, options?)`
|
|
201
|
+
|
|
202
|
+
- `source`: `HTMLImageElement | ImageBitmap | Blob | string`
|
|
203
|
+
|
|
204
|
+
Returns `Promise<ColorlipColor[]>`.
|
|
205
|
+
|
|
206
|
+
#### `getPalette(source, options?)`
|
|
207
|
+
|
|
208
|
+
- `source`: `HTMLImageElement | ImageBitmap | Blob | string`
|
|
209
|
+
|
|
210
|
+
Returns `Promise<ColorlipPalette>`.
|
|
211
|
+
|
|
212
|
+
#### `getColorsFromImageData(imageData, options?)`
|
|
213
|
+
|
|
214
|
+
Extract colors directly from `ImageData`.
|
|
215
|
+
|
|
216
|
+
#### `getPaletteFromImageData(imageData, options?)`
|
|
217
|
+
|
|
218
|
+
Extract a palette directly from `ImageData`.
|
|
219
|
+
|
|
220
|
+
#### `getColorsFromPixels(...)`
|
|
221
|
+
|
|
222
|
+
Re-export of the raw-pixel core API.
|
|
223
|
+
|
|
224
|
+
#### `getPaletteFromPixels(...)`
|
|
225
|
+
|
|
226
|
+
Re-export of the raw-pixel core palette API.
|
|
227
|
+
|
|
228
|
+
#### Legacy aliases
|
|
229
|
+
|
|
230
|
+
- `colorlipFromImage(...)`
|
|
231
|
+
- `colorlipFromImageData(...)`
|
|
232
|
+
|
|
233
|
+
## Options
|
|
86
234
|
|
|
87
235
|
```ts
|
|
88
236
|
interface ExtractOptions {
|
|
89
|
-
numColors?: number;
|
|
90
|
-
saturationThreshold?: number;
|
|
91
|
-
brightnessMin?: number;
|
|
92
|
-
brightnessMax?: number;
|
|
93
|
-
quantizationStep?: number;
|
|
237
|
+
numColors?: number; // default: 3
|
|
238
|
+
saturationThreshold?: number; // default: 0.15
|
|
239
|
+
brightnessMin?: number; // default: 20
|
|
240
|
+
brightnessMax?: number; // default: 235
|
|
241
|
+
quantizationStep?: number; // default: 12
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Default values:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
{
|
|
249
|
+
numColors: 3,
|
|
250
|
+
saturationThreshold: 0.15,
|
|
251
|
+
brightnessMin: 20,
|
|
252
|
+
brightnessMax: 235,
|
|
253
|
+
quantizationStep: 12,
|
|
94
254
|
}
|
|
95
255
|
```
|
|
96
256
|
|
|
97
|
-
|
|
257
|
+
## Output
|
|
98
258
|
|
|
99
|
-
Each color
|
|
259
|
+
Each extracted color is returned as a `ColorlipColor`:
|
|
100
260
|
|
|
101
261
|
```ts
|
|
102
|
-
interface
|
|
103
|
-
r: number;
|
|
104
|
-
g: number;
|
|
105
|
-
b: number;
|
|
106
|
-
hex: string;
|
|
107
|
-
percentage: number;
|
|
108
|
-
hue: number;
|
|
109
|
-
saturation: number;
|
|
110
|
-
lightness: number;
|
|
111
|
-
hueCategory: HueCategory;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
262
|
+
interface ColorlipColor {
|
|
263
|
+
r: number;
|
|
264
|
+
g: number;
|
|
265
|
+
b: number;
|
|
266
|
+
hex: string;
|
|
267
|
+
percentage: number;
|
|
268
|
+
hue: number;
|
|
269
|
+
saturation: number;
|
|
270
|
+
lightness: number;
|
|
271
|
+
hueCategory: HueCategory;
|
|
272
|
+
lab: { L: number; a: number; b: number };
|
|
273
|
+
lch: { L: number; C: number; H: number };
|
|
274
|
+
oklab: { L: number; a: number; b: number };
|
|
275
|
+
oklch: { L: number; C: number; H: number };
|
|
276
|
+
css: {
|
|
277
|
+
rgb: string;
|
|
278
|
+
hsl: string;
|
|
279
|
+
lab: string;
|
|
280
|
+
lch: string;
|
|
281
|
+
oklab: string;
|
|
282
|
+
oklch: string;
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Example:
|
|
117
288
|
|
|
289
|
+
```ts
|
|
290
|
+
{
|
|
291
|
+
r: 42,
|
|
292
|
+
g: 98,
|
|
293
|
+
b: 168,
|
|
294
|
+
hex: "#2A62A8",
|
|
295
|
+
percentage: 0.34,
|
|
296
|
+
hue: 213,
|
|
297
|
+
saturation: 60,
|
|
298
|
+
lightness: 41,
|
|
299
|
+
hueCategory: "blue",
|
|
300
|
+
lab: { L: 41.2, a: -2.3, b: -40.1 },
|
|
301
|
+
lch: { L: 41.2, C: 40.2, H: 266.7 },
|
|
302
|
+
oklab: { L: 0.49, a: -0.03, b: -0.12 },
|
|
303
|
+
oklch: { L: 0.49, C: 0.12, H: 256.7 },
|
|
118
304
|
css: {
|
|
119
|
-
rgb:
|
|
120
|
-
hsl:
|
|
121
|
-
lab:
|
|
122
|
-
lch:
|
|
123
|
-
oklab:
|
|
124
|
-
oklch:
|
|
125
|
-
}
|
|
305
|
+
rgb: "rgb(42 98 168)",
|
|
306
|
+
hsl: "hsl(213 60% 41%)",
|
|
307
|
+
lab: "lab(41.2 -2.3 -40.1)",
|
|
308
|
+
lch: "lch(41.2 40.2 266.7)",
|
|
309
|
+
oklab: "oklab(0.49 -0.03 -0.12)",
|
|
310
|
+
oklch: "oklch(0.49 0.12 256.7)",
|
|
311
|
+
},
|
|
126
312
|
}
|
|
127
313
|
```
|
|
128
314
|
|
|
129
|
-
|
|
315
|
+
## Utility Functions
|
|
130
316
|
|
|
131
317
|
```ts
|
|
132
|
-
import {
|
|
318
|
+
import {
|
|
319
|
+
aggregateColors,
|
|
320
|
+
createDominantColor,
|
|
321
|
+
getHueCategory,
|
|
322
|
+
rgbToHex,
|
|
323
|
+
rgbToHsl,
|
|
324
|
+
} from "colorlip";
|
|
133
325
|
```
|
|
134
326
|
|
|
135
327
|
| Function | Description |
|
|
136
|
-
|
|
137
|
-
| `rgbToHex(r, g, b)` | RGB
|
|
138
|
-
| `rgbToHsl(r, g, b)` | RGB
|
|
139
|
-
| `getHueCategory(hue)` |
|
|
140
|
-
| `createDominantColor(r, g, b, percentage)` | Build a full `
|
|
141
|
-
| `aggregateColors(colorSets, numColors?)` | Merge multiple extraction results into top
|
|
328
|
+
| --- | --- |
|
|
329
|
+
| `rgbToHex(r, g, b)` | Convert RGB to `#RRGGBB` |
|
|
330
|
+
| `rgbToHsl(r, g, b)` | Convert RGB to `{ h, s, l }` |
|
|
331
|
+
| `getHueCategory(hue)` | Convert hue to `"red" \| "orange" \| ... \| "gray"` |
|
|
332
|
+
| `createDominantColor(r, g, b, percentage)` | Build a full `ColorlipColor` |
|
|
333
|
+
| `aggregateColors(colorSets, numColors?)` | Merge multiple extraction results into top colors |
|
|
334
|
+
| `extractFallbackPalette(...)` | Run the simplified fallback extractor directly |
|
|
142
335
|
|
|
143
336
|
## How It Works
|
|
144
337
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
338
|
+
The extraction pipeline is:
|
|
339
|
+
|
|
340
|
+
1. Adapter input is resized to a maximum of `150x150` pixels. Raw-pixel core calls skip this step.
|
|
341
|
+
2. A sampling pass estimates median saturation, saturation spread, and how centrally edges are concentrated.
|
|
342
|
+
3. Pixels with `alpha < 0.5` are ignored. Remaining pixels are included with alpha-based weighting.
|
|
343
|
+
4. Pixels are filtered by adaptive saturation floor and configured brightness range.
|
|
344
|
+
5. Surviving pixels are quantized into bins and weighted by center bias, edge strength, saturation, and alpha.
|
|
345
|
+
6. Nearby bins are pre-merged in Lab space using an adaptive Delta E threshold.
|
|
346
|
+
7. Clusters are scored from weighted presence, then adjusted by spatial distribution, center/border bias, centroid position, spread, and accent preference in OKLCH space.
|
|
347
|
+
8. Final swatches are selected with another adaptive Delta E merge pass.
|
|
348
|
+
9. `dominant` is chosen from the leading swatches, not only by raw rank but also by a dominant-preference pass in OKLCH space. This helps promote colors that feel more representative and visually salient, instead of always keeping the darkest or heaviest cluster at the top.
|
|
349
|
+
10. `accent` is chosen from perceptually distant candidates or swatches.
|
|
350
|
+
11. If the main path produces no candidates, a simpler histogram-based fallback extractor is used.
|
|
351
|
+
|
|
352
|
+
## Dominant Selection
|
|
353
|
+
|
|
354
|
+
`palette.dominant` is selected in two stages:
|
|
355
|
+
|
|
356
|
+
1. `colorlip` first builds and scores cluster candidates from weighted image regions.
|
|
357
|
+
2. After final swatches are decided, the leading swatches are re-ranked for `dominant` selection using:
|
|
358
|
+
- the original extraction score
|
|
359
|
+
- weighted presence
|
|
360
|
+
- a perceptual preference in OKLCH space
|
|
361
|
+
|
|
362
|
+
This extra pass keeps `dominant` closer to the color that feels like the image's representative color, especially for photos where a large dark area might otherwise win by area alone.
|
|
363
|
+
|
|
364
|
+
## Alpha Handling
|
|
365
|
+
|
|
366
|
+
When the input has an alpha channel:
|
|
367
|
+
|
|
368
|
+
- Pixels with `alpha < 128` are ignored
|
|
369
|
+
- Pixels with `alpha >= 128` are kept
|
|
370
|
+
- Their contribution is weighted by `(alpha / 255) ** 2`
|
|
371
|
+
|
|
372
|
+
This reduces semi-transparent edge noise while still allowing partially visible colors to contribute.
|
|
373
|
+
|
|
374
|
+
## Notes
|
|
375
|
+
|
|
376
|
+
- The core accepts both `Uint8Array` and `Uint8ClampedArray`
|
|
377
|
+
- `channels` is expected to be `3` or `4`
|
|
378
|
+
- Browser string sources are fetched with `fetch(...)`
|
|
379
|
+
- Browser adapter resizing happens through `OffscreenCanvas`
|
|
380
|
+
- Grayscale or heavily filtered inputs may fall back to the simpler histogram path
|
|
381
|
+
|
|
382
|
+
## Compatibility Aliases
|
|
383
|
+
|
|
384
|
+
These names remain available for compatibility:
|
|
385
|
+
|
|
386
|
+
- `DominantColor` as a type alias of `ColorlipColor`
|
|
387
|
+
- `colorlip(...)`
|
|
388
|
+
- `colorlipFromFile(...)`
|
|
389
|
+
- `colorlipFromBuffer(...)`
|
|
390
|
+
- `colorlipFromImage(...)`
|
|
391
|
+
- `colorlipFromImageData(...)`
|
|
152
392
|
|
|
153
393
|
## License
|
|
154
394
|
|