Skip to content

Commit cbf9a56

Browse files
committed
*: format, refactor, and update
- Change code style from [StandardJS](https://standardjs.com/) to [Prettier](https://prettier.io/)-like style. - Format all the code. - Use [ESLint](https://eslint.org/) for linting JavaScript code. - Add `package-lock.json` file to `.gitignore`. - Refactor code and tests. - Add `format` NPM script to format code (`npm run format`). - Update dependencies to their latest version. - Rename `readme.md` to `README.md` to assert convention consistency. BREAKING: - Drop support for Node.js v10 and v12. - Move to pure ESM.
1 parent 1590030 commit cbf9a56

File tree

9 files changed

+327
-265
lines changed

9 files changed

+327
-265
lines changed

.eslintrc.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"env": {
3+
"es2021": true,
4+
"node": true
5+
},
6+
"extends": "eslint:recommended",
7+
"parserOptions": {
8+
"ecmaVersion": "latest",
9+
"sourceType": "module"
10+
},
11+
"rules": {
12+
"indent": ["error", 2],
13+
"linebreak-style": ["error", "unix"],
14+
"quotes": ["error", "single"],
15+
"semi": ["error", "always"]
16+
}
17+
}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
node_modules
1+
node_modules/
2+
package-lock.json

.prettierrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "none"
4+
}

.travis.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
language: node_js
22
node_js:
3-
- "10"
4-
- "12"
5-
- "14"
3+
- '14'
4+
- '16'

README.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# get-image-colors
2+
3+
Extract colors from images. Supports GIF, JPG, PNG, and even SVG!
4+
5+
![example color palette](https://cldup.com/-uw9Ub6L6s.png)
6+
7+
## Installation
8+
9+
```sh
10+
npm install get-image-colors
11+
```
12+
13+
This package is intended for use in node environments. It won't work in a browser because it has node-specific dependencies.
14+
15+
**Note:** when installing with webpack, if you get the error
16+
17+
```
18+
Can't resolve 'fs' in '/node_modules/get-svg-colors'
19+
```
20+
21+
as per an [open issue in webpack-contrib](https://github.com/webpack-contrib/css-loader/issues/447), you will need to add `node: { fs: 'empty' }` to your `webpack.base.config`:
22+
23+
```js
24+
module.exports = {
25+
...,
26+
node: { fs: 'empty' }
27+
};
28+
```
29+
30+
## Usage
31+
32+
```js
33+
import { join, dirname } from 'node:path';
34+
import { fileURLToPath } from 'node:url';
35+
import getColors from 'get-image-colors';
36+
37+
getColors(
38+
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.png')
39+
).then((colors) => {
40+
// `colors` is an array of color objects
41+
});
42+
```
43+
44+
You can also use a buffer as an input source.
45+
46+
```js
47+
import { join, dirname } from 'node:path';
48+
import { fileURLToPath } from 'node:url';
49+
import { readFileSync } from 'node:fs';
50+
import getColors from 'get-image-colors';
51+
52+
const buffer = readFileSync(
53+
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.gif')
54+
);
55+
56+
getColors(buffer, 'image/gif').then((colors) => {
57+
// `colors` is an array of color objects
58+
});
59+
```
60+
61+
`colors` is an array of [chroma.js][] color objects. chroma.js objects have methods that lets you pick the color format you want (RGB hex, HSL, etc), and give you access to powerful color manipulation features:
62+
63+
```js
64+
colors.map((color) => color.hex());
65+
// => ['#FFFFFF', '#123123', '#F0F0F0']
66+
67+
colors[0].alpha(0.5).css();
68+
// => 'rgb(0,128,128)'
69+
```
70+
71+
If you don't like promises, you can use node-style callbacks too:
72+
73+
```js
74+
getColors(filename, (err, colors) => {
75+
if (err != undefined) throw err;
76+
// ...
77+
});
78+
```
79+
80+
The default number of colors returned is 5. You can specify a different number of colors by passing an options object into the call to getColors:
81+
82+
```js
83+
import { join, dirname } from 'node:path';
84+
import { fileURLToPath } from 'node:url';
85+
import getColors from 'get-image-colors';
86+
87+
const options = {
88+
count: 10,
89+
type: 'image/png'
90+
};
91+
92+
getColors(
93+
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.png'),
94+
options
95+
).then((colors) => {
96+
// `colors` is an array of 10 color objects
97+
});
98+
```
99+
100+
## How it Works
101+
102+
`get-image-colors` uses [get-pixels][] to create a pixel array, then extracts a color palette with [get-rgba-palette][], which uses [quantize](http://npmjs.com/package/quantize) under the hood.
103+
104+
Colors are converted from [get-rgba-palette's flat array format](https://github.com/mattdesl/get-rgba-palette#palettepixels-count-quality-filter) into [chroma.js color instances][chroma.js].
105+
106+
## Tests
107+
108+
```sh
109+
npm install
110+
npm test
111+
```
112+
113+
## Dependencies
114+
115+
- [chroma-js][chroma.js]: JavaScript library for color conversions
116+
- [get-pixels][]: Reads the pixels of an image as an ndarray
117+
- [get-rgba-palette][]: Gets a palette of prominent colors from an array of pixels
118+
- [get-svg-colors](https://npmjs.com/package/get-svg-colors): Extract stroke and fill colors from SVG files
119+
120+
## Dev Dependencies
121+
122+
- [eslint](https://npmjs.com/package/eslint): ECMAScript/JavaScript linter
123+
- [mocha](https://npmjs.com/package/mocha): Simple, flexible, fun test framework
124+
- [prettier](https://npmjs.com/package/prettier): Opinionated code formatter
125+
126+
## License
127+
128+
MIT
129+
130+
[chroma.js]: https://npmjs.com/package/chroma-js
131+
[get-pixels]: https://npmjs.com/package/get-pixels
132+
[get-rgba-palette]: https://npmjs.com/package/get-rgba-palette

index.js

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,61 @@
1-
const getPixels = require('get-pixels')
2-
const getRgbaPalette = require('get-rgba-palette')
3-
const chroma = require('chroma-js')
4-
const getSvgColors = require('get-svg-colors')
5-
const pify = require('pify')
1+
import getPixels from 'get-pixels';
2+
import getRgbaPalette from 'get-rgba-palette';
3+
import chroma from 'chroma-js';
4+
import getSvgColors from 'get-svg-colors';
5+
import pify from 'pify';
66

77
const patterns = {
8-
image: /\.(gif|jpg|png|svg)$/i,
9-
raster: /\.(gif|jpg|png)$/i,
10-
svg: /svg$/i
11-
}
8+
image: /\.(?:gif|jpg|png|svg)$/i,
9+
raster: /\.(?:gif|jpg|png)$/i,
10+
svg: /\.svg$/i
11+
};
1212

13-
function colorPalette (input, options, callback) {
13+
function colorPalette(input, options, callback) {
1414
if (typeof options === 'function') {
15-
callback = options
15+
callback = options;
1616
options = {
1717
type: undefined,
1818
count: 5
19-
}
20-
} else if (typeof options === 'string') {
19+
};
20+
} else if (typeof options === 'string')
2121
options = {
2222
type: options,
2323
count: 5
24-
}
25-
}
24+
};
2625

2726
// SVG
28-
if (!Buffer.isBuffer(input)) {
29-
if (input.match(patterns.svg)) {
30-
return callback(null, getSvgColors(input, { flat: true }))
31-
}
32-
} else if (options.type === 'image/svg+xml') {
33-
return callback(null, getSvgColors(input, { flat: true }))
34-
}
27+
if (
28+
(!Buffer.isBuffer(input) && patterns.svg.test(input)) ||
29+
options.type === 'image/svg+xml'
30+
)
31+
return callback(null, getSvgColors(input, { flat: true }));
3532

3633
// PNG, GIF, JPG
37-
return paletteFromBitmap(input, options, callback)
34+
return paletteFromBitmap(input, options, callback);
3835
}
3936

40-
function paletteFromBitmap (filename, options, callback) {
41-
if (!callback) {
42-
callback = options
37+
function paletteFromBitmap(filename, options, callback) {
38+
if (callback == undefined) {
39+
callback = options;
4340
options = {
4441
type: undefined,
4542
count: 5
46-
}
43+
};
4744
}
4845

49-
getPixels(filename, options.type, function (err, pixels) {
50-
if (err) return callback(err)
51-
const palette = getRgbaPalette(pixels.data, options.count).map(function (rgba) {
52-
return chroma(rgba)
53-
})
46+
getPixels(filename, options.type, (err, pixels) => {
47+
if (err != undefined) {
48+
callback(err);
49+
50+
return;
51+
}
52+
53+
const palette = getRgbaPalette(pixels.data, options.count).map((rgba) =>
54+
chroma(rgba)
55+
);
5456

55-
return callback(null, palette)
56-
})
57+
callback(null, palette);
58+
});
5759
}
5860

59-
module.exports = pify(colorPalette)
61+
export default pify(colorPalette);

package.json

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
"version": "4.0.1",
44
"description": "Extract colors from images. Supports GIF, JPG, PNG, and even SVG!",
55
"main": "index.js",
6+
"type": "module",
67
"scripts": {
7-
"test": "mocha && standard && standard-markdown *.md",
8-
"lint": "standard"
8+
"test": "mocha && eslint .",
9+
"lint": "eslint .",
10+
"format": "prettier -w ."
911
},
1012
"repository": "https://github.com/colorjs/get-image-colors",
1113
"keywords": [
@@ -23,20 +25,15 @@
2325
"author": "zeke",
2426
"license": "MIT",
2527
"devDependencies": {
26-
"mocha": "^8.1.1",
27-
"standard": "^14.3.4",
28-
"standard-markdown": "^6.0.0"
28+
"eslint": "^8.17.0",
29+
"mocha": "^10.0.0",
30+
"prettier": "^2.6.2"
2931
},
3032
"dependencies": {
31-
"chroma-js": "^2.1.0",
32-
"get-pixels": "^3.3.2",
33+
"chroma-js": "^2.4.2",
34+
"get-pixels": "^3.3.3",
3335
"get-rgba-palette": "^2.0.1",
3436
"get-svg-colors": "^2.0.0",
35-
"pify": "^5.0.0"
36-
},
37-
"standard": {
38-
"env": {
39-
"mocha": true
40-
}
37+
"pify": "^6.0.0"
4138
}
4239
}

0 commit comments

Comments
 (0)