image-palette
Advanced tools
Comparing version 1.0.3 to 2.0.0
@@ -0,1 +1,8 @@ | ||
2.0.0 / 2018-11-11 | ||
================== | ||
* Direct buffer arg, no readimage anymore | ||
* Direct palette calculator | ||
* Mapping pixels to palette ids | ||
1.0.0 / 2015-06-02 | ||
@@ -8,5 +15,5 @@ ================== | ||
0.0.1 / 2011-12-18 | ||
0.0.1 / 2011-12-18 | ||
================== | ||
* Initial release |
158
index.js
/*! | ||
* @module image-palette | ||
*/ | ||
'use strict' | ||
/** | ||
* Module dependencies. | ||
*/ | ||
var cid = require('color-id') | ||
var u8 = require('to-uint8') | ||
var quantize = require('quantize') | ||
var quantize = require('quantize'); | ||
var readimage = require('readimage'); | ||
var fs = require('fs'); | ||
module.exports = palette | ||
module.exports.quantized = quantized | ||
module.exports.average = quantized | ||
// return directly counted colors, if src contains less than maxCount of them | ||
function palette(src, maxCount) { | ||
if (maxCount == null) maxCount = 5 | ||
/** | ||
* Expose `palette`. | ||
*/ | ||
if (!maxCount) return {colors: [], ids: [], amount: []} | ||
if (maxCount === 1) return average(src) | ||
module.exports = palette; | ||
var pixels = u8(src) | ||
var total = pixels.length >> 2 | ||
var colorIds = {} | ||
var colors = [] | ||
var count = [] | ||
var ids = Array(total) | ||
/** | ||
* Library version. | ||
*/ | ||
for (var i = 0; i < pixels.length; i += 4) { | ||
var rgb = pixels.subarray(i, i + 3) | ||
var irgb = cid(rgb, false) | ||
exports.version = require('./package').version; | ||
// register new color | ||
if (colorIds[irgb] == null) { | ||
// if palette goes over the indicated maxColors, use quantization | ||
if (colors.length >= maxCount) { | ||
return quantized(src, maxCount) | ||
} | ||
colorIds[irgb] = colors.length | ||
colors.push(pixels.subarray(i, i + 4)) | ||
} | ||
/** | ||
* Return the color palette for the file given in `path` | ||
* consisting of `n` RGB color values, defaulting to 5. | ||
* Returning value is passed to a callback | ||
* | ||
* @param {String} path | ||
* @param {Function} cb | ||
* @param {Number} n | ||
* @api public | ||
*/ | ||
count[colorIds[irgb]] = (count[colorIds[irgb]] || 0) + 1 | ||
function palette(path, cb, n) { | ||
var file = fs.readFileSync(path); | ||
ids[i >> 2] = colorIds[irgb] | ||
} | ||
n = n || 5; | ||
return { | ||
colors: colors, | ||
ids: ids, | ||
amount: count.map(function (v) { return v / total }) | ||
} | ||
} | ||
return readimage(file, function (err, image) { | ||
//transform image data for quantization | ||
var rawData = image.frames[0].data; | ||
var len = rawData.length; | ||
var data = []; | ||
for (var i = 0; i < len; i += 4) { | ||
// semi-transparent | ||
if (rawData[i + 3] < 0xaa) continue; | ||
data.push([rawData[i], rawData[i + 1], rawData[i + 2]]); | ||
} | ||
// return quantized palette colors | ||
function quantized (src, count) { | ||
if (count == null) count = 5 | ||
var colors = quantize(data, n).palette(); | ||
if (!count) return {colors: [], ids: [], amount: []} | ||
if (count === 1) return average(src) | ||
cb(colors); | ||
}); | ||
} | ||
var pixels = u8(src) | ||
var total = src.length >> 2 | ||
var pixelArray = [] | ||
for (var i=0, len=pixels.length; i<len; i+=4) { | ||
var r = pixels[i + 0], | ||
g = pixels[i + 1], | ||
b = pixels[i + 2], | ||
a = pixels[i + 3] | ||
pixelArray.push([ r, g, b ]) | ||
} | ||
// fix because quantize breaks on < 2 | ||
var cluster = quantize(pixelArray, count) | ||
var vboxes = cluster.vboxes.map(function (vb) { | ||
vb.size = vb.vbox.count() * vb.vbox.volume() | ||
return vb | ||
}).slice(0, count) | ||
var colorIds = {} | ||
var colors = [] | ||
var ids = Array(total) | ||
var sum = 0 | ||
for (var i = 0; i < vboxes.length; i++) { | ||
var vbox = vboxes[i] | ||
var color = vbox.color | ||
color.push(255) | ||
var colorId = cid(color, false) | ||
colorIds[colorId] = colors.length | ||
colors.push(color) | ||
sum += vbox.size | ||
} | ||
// generate ids | ||
for (var i = 0; i < total; i++) { | ||
var color = cluster.map(pixelArray[i]) | ||
var colorId = cid(color, false) | ||
ids[i] = colorIds[colorId] | ||
} | ||
return { | ||
colors: colors, | ||
ids: ids, | ||
amount: vboxes.map(function (vb) { | ||
return vb.size / sum | ||
}) | ||
} | ||
} | ||
// single-color calc | ||
function average (src) { | ||
var pixels = u8(src) | ||
var total = pixels.length >> 2 | ||
var sum = [0,0,0,0] | ||
for (let i = 0; i < src.length; i+=4) { | ||
sum[0] += src[i] | ||
sum[1] += src[i + 1] | ||
sum[2] += src[i + 2] | ||
sum[3] += src[i + 3] | ||
} | ||
var avg = new Uint8Array([sum[0] / total, sum[1] / total, sum[2] / total, sum[3] / total]) | ||
var ids = new Uint8Array(total) | ||
return { | ||
colors: [avg], | ||
amount: [1], | ||
ids: ids | ||
} | ||
} |
{ | ||
"name": "image-palette", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"description": "Get palette for any image file, no node-canvas", | ||
@@ -11,3 +11,8 @@ "keywords": [ | ||
"canvas", | ||
"photo" | ||
"photo", | ||
"quantize", | ||
"image-pixels", | ||
"pixels", | ||
"gif", | ||
"image-encode" | ||
], | ||
@@ -17,13 +22,19 @@ "scripts": { | ||
}, | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
"devDependencies": {}, | ||
"author": "Dmitry Yv <df.creative@gmail.com>", | ||
"devDependencies": { | ||
"almost-equal": "^1.1.0", | ||
"array-range": "^1.0.1", | ||
"image-pixels": "^2.0.2", | ||
"tape": "^4.9.1" | ||
}, | ||
"main": "index", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/dfcreative/palette.git" | ||
"url": "https://github.com/dy/image-palette.git" | ||
}, | ||
"dependencies": { | ||
"quantize": "^1.0.1", | ||
"readimage": "^1.1.1" | ||
"color-id": "^1.1.0", | ||
"quantize": "^1.0.2", | ||
"to-uint8": "^1.3.1" | ||
} | ||
} |
@@ -1,25 +0,37 @@ | ||
# Image-palette | ||
# image-palette [![Build Status](https://travis-ci.org/dy/image-palette.svg?branch=master)](https://travis-ci.org/dy/image-palette) [![unstable](https://img.shields.io/badge/stability-unstable-green.svg)](http://github.com/badges/stability-badges) | ||
Image color palette extraction. Fork of [palette](http://github.com/tj/palette) without node-canvas dependency and async result. | ||
Extract palette from pixels array, return pixels mapped to palette. Useful for organizing [palette-based encoding](https://ghub.io/image-encode), like GIF, or various limited colors renderers, like [gl-scatter2d](https://ghub.io/gl-scatter2d). | ||
## Installation | ||
Inspired by [get-rgba-palette](https://github.com/mattdesl/get-rgba-palette). | ||
## Usage | ||
[![$ npm install image-palette](http://nodei.co/npm/image-palette.png?mini=true)](http://npmjs.org/package/image-palette) | ||
```javascript | ||
var palette = require('image-palette') | ||
var pixels = require('image-pixels') | ||
var {ids, colors} = palette(await pixels('./image.png')) | ||
``` | ||
$ npm install image-palette | ||
``` | ||
## API | ||
Palette's public API consists of a single function, the one returned by `require()`. This function accepts the `filepath` you wish to compute a color palette for, a callback and an optional number of samples defaulting to `5`. | ||
### `var {ids, colors, amount} = palette(pixels, count=5)` | ||
Extract palette from the input `pixels` array with `rgba` pixels sequence, whether flat or nested. | ||
```js | ||
var palette = require('image-palette'); | ||
var Color = require('color'); | ||
* `colors` is a list of extracted colors `[[r, g, b, a], [r, g, b, a], ...]`. | ||
* `ids` is an array of input pixels mapped to extracted `colors`. | ||
* `amount` is an array with amounts corresponding to the extracted colors, from `0..1` range. | ||
* `count` is max number of colors to extract. | ||
var colors = palette('./image.jpg', function (colors) { | ||
Color().rgb(colors[0]); | ||
}); | ||
``` | ||
## Related | ||
[![NPM](https://nodei.co/npm/image-palette.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/image-palette/) | ||
* [image-pixels](https://ghub.io/image-pixels) − load pixels data from any image source. | ||
* [image-save](https://ghub.io/image-save) − save image/pixel data to a file, canvas or array. | ||
* [image-equal](https://ghub.io/image-equal) − test if two images are equal, based on fuzzy comparison. | ||
## License | ||
© 2018 Dmitry Yv. MIT License. |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
5972
109
38
0
3
4
+ Addedcolor-id@^1.1.0
+ Addedto-uint8@^1.3.1
+ Addedarr-flatten@1.1.0(transitive)
+ Addedatob-lite@2.0.0(transitive)
+ Addedclamp@1.0.1(transitive)
+ Addedcolor-id@1.1.0(transitive)
+ Addeddtype@2.0.0(transitive)
+ Addedflatten-vertex-data@1.0.2(transitive)
+ Addedis-base64@0.1.0(transitive)
+ Addedis-blob@2.1.0(transitive)
+ Addedis-float-array@1.0.0(transitive)
+ Addedstring-to-arraybuffer@1.0.2(transitive)
+ Addedto-array-buffer@3.2.0(transitive)
+ Addedto-uint8@1.4.1(transitive)
- Removedreadimage@^1.1.1
- Removedbuffer-equal@0.0.1(transitive)
- Removedisnumber@1.0.0(transitive)
- Removedjpeg-js@0.0.4(transitive)
- Removedomggif@1.0.10(transitive)
- Removedpngparse@2.0.1(transitive)
- Removedreadimage@1.1.1(transitive)
Updatedquantize@^1.0.2