Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: format, refactor, and update #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"]
}
}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules/
package-lock.json
4 changes: 4 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "none"
}
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
language: node_js
node_js:
- "10"
- "12"
- "14"
- '14'
- '16'
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# get-image-colors

Extract colors from images. Supports GIF, JPG, PNG, and even SVG!

![example color palette](https://cldup.com/-uw9Ub6L6s.png)

## Installation

```sh
npm install get-image-colors
```

This package is intended for use in node environments. It won't work in a browser because it has node-specific dependencies.

**Note:** when installing with webpack, if you get the error

```
Can't resolve 'fs' in '/node_modules/get-svg-colors'
```

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`:

```js
module.exports = {
...,
node: { fs: 'empty' }
};
```

## Usage

```js
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import getColors from 'get-image-colors';

getColors(
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.png')
).then((colors) => {
// `colors` is an array of color objects
});
```

You can also use a buffer as an input source.

```js
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { readFileSync } from 'node:fs';
import getColors from 'get-image-colors';

const buffer = readFileSync(
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.gif')
);

getColors(buffer, 'image/gif').then((colors) => {
// `colors` is an array of color objects
});
```

`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:

```js
colors.map((color) => color.hex());
// => ['#FFFFFF', '#123123', '#F0F0F0']

colors[0].alpha(0.5).css();
// => 'rgb(0,128,128)'
```

If you don't like promises, you can use node-style callbacks too:

```js
getColors(filename, (err, colors) => {
if (err != undefined) throw err;
// ...
});
```

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:

```js
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import getColors from 'get-image-colors';

const options = {
count: 10,
type: 'image/png'
};

getColors(
join(dirname(fileURLToPath(import.meta.url)), 'double-rainbow.png'),
options
).then((colors) => {
// `colors` is an array of 10 color objects
});
```

## How it Works

`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.

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].

## Tests

```sh
npm install
npm test
```

## Dependencies

- [chroma-js][chroma.js]: JavaScript library for color conversions
- [get-pixels][]: Reads the pixels of an image as an ndarray
- [get-rgba-palette][]: Gets a palette of prominent colors from an array of pixels
- [get-svg-colors](https://npmjs.com/package/get-svg-colors): Extract stroke and fill colors from SVG files

## Dev Dependencies

- [eslint](https://npmjs.com/package/eslint): ECMAScript/JavaScript linter
- [mocha](https://npmjs.com/package/mocha): Simple, flexible, fun test framework
- [prettier](https://npmjs.com/package/prettier): Opinionated code formatter

## License

MIT

[chroma.js]: https://npmjs.com/package/chroma-js
[get-pixels]: https://npmjs.com/package/get-pixels
[get-rgba-palette]: https://npmjs.com/package/get-rgba-palette
72 changes: 37 additions & 35 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
const getPixels = require('get-pixels')
const getRgbaPalette = require('get-rgba-palette')
const chroma = require('chroma-js')
const getSvgColors = require('get-svg-colors')
const pify = require('pify')
import getPixels from 'get-pixels';
import getRgbaPalette from 'get-rgba-palette';
import chroma from 'chroma-js';
import getSvgColors from 'get-svg-colors';
import pify from 'pify';

const patterns = {
image: /\.(gif|jpg|png|svg)$/i,
raster: /\.(gif|jpg|png)$/i,
svg: /svg$/i
}
image: /\.(?:gif|jpg|png|svg)$/i,
raster: /\.(?:gif|jpg|png)$/i,
svg: /\.svg$/i
};

function colorPalette (input, options, callback) {
function colorPalette(input, options, callback) {
if (typeof options === 'function') {
callback = options
callback = options;
options = {
type: undefined,
count: 5
}
} else if (typeof options === 'string') {
};
} else if (typeof options === 'string')
options = {
type: options,
count: 5
}
}
};

// SVG
if (!Buffer.isBuffer(input)) {
if (input.match(patterns.svg)) {
return callback(null, getSvgColors(input, { flat: true }))
}
} else if (options.type === 'image/svg+xml') {
return callback(null, getSvgColors(input, { flat: true }))
}
if (
(!Buffer.isBuffer(input) && patterns.svg.test(input)) ||
options.type === 'image/svg+xml'
)
return callback(null, getSvgColors(input, { flat: true }));

// PNG, GIF, JPG
return paletteFromBitmap(input, options, callback)
return paletteFromBitmap(input, options, callback);
}

function paletteFromBitmap (filename, options, callback) {
if (!callback) {
callback = options
function paletteFromBitmap(filename, options, callback) {
if (callback == undefined) {
callback = options;
options = {
type: undefined,
count: 5
}
};
}

getPixels(filename, options.type, function (err, pixels) {
if (err) return callback(err)
const palette = getRgbaPalette(pixels.data, options.count).map(function (rgba) {
return chroma(rgba)
})
getPixels(filename, options.type, (err, pixels) => {
if (err != undefined) {
callback(err);

return;
}

const palette = getRgbaPalette(pixels.data, options.count).map((rgba) =>
chroma(rgba)
);

return callback(null, palette)
})
callback(null, palette);
});
}

module.exports = pify(colorPalette)
export default pify(colorPalette);
23 changes: 10 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"version": "4.0.1",
"description": "Extract colors from images. Supports GIF, JPG, PNG, and even SVG!",
"main": "index.js",
"type": "module",
"scripts": {
"test": "mocha && standard && standard-markdown *.md",
"lint": "standard"
"test": "mocha && eslint .",
"lint": "eslint .",
"format": "prettier -w ."
},
"repository": "https://github.com/colorjs/get-image-colors",
"keywords": [
Expand All @@ -23,20 +25,15 @@
"author": "zeke",
"license": "MIT",
"devDependencies": {
"mocha": "^8.1.1",
"standard": "^14.3.4",
"standard-markdown": "^6.0.0"
"eslint": "^8.20.0",
"mocha": "^10.0.0",
"prettier": "^2.7.1"
},
"dependencies": {
"chroma-js": "^2.1.0",
"get-pixels": "^3.3.2",
"chroma-js": "^2.4.2",
"get-pixels": "^3.3.3",
"get-rgba-palette": "^2.0.1",
"get-svg-colors": "^2.0.0",
"pify": "^5.0.0"
},
"standard": {
"env": {
"mocha": true
}
"pify": "^6.0.0"
}
}
Loading