1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import { isNodePattern } from '@jimp/utils';
- /**
- * Get an image's histogram
- * @return {object} An object with an array of color occurrence counts for each channel (r,g,b)
- */
- function histogram() {
- const histogram = {
- r: new Array(256).fill(0),
- g: new Array(256).fill(0),
- b: new Array(256).fill(0)
- };
- this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function(
- x,
- y,
- index
- ) {
- histogram.r[this.bitmap.data[index + 0]]++;
- histogram.g[this.bitmap.data[index + 1]]++;
- histogram.b[this.bitmap.data[index + 2]]++;
- });
- return histogram;
- }
- /**
- * Normalize values
- * @param {integer} value Pixel channel value.
- * @param {integer} min Minimum value for channel
- * @param {integer} max Maximum value for channel
- * @return {integer} normalized values
- */
- const normalize = function(value, min, max) {
- return ((value - min) * 255) / (max - min);
- };
- const getBounds = function(histogramChannel) {
- return [
- histogramChannel.findIndex(value => value > 0),
- 255 -
- histogramChannel
- .slice()
- .reverse()
- .findIndex(value => value > 0)
- ];
- };
- /**
- * Normalizes the image
- * @param {function(Error, Jimp)} cb (optional) a callback for when complete
- * @returns {Jimp} this for chaining of methods
- */
- export default () => ({
- normalize(cb) {
- const h = histogram.call(this);
- // store bounds (minimum and maximum values)
- const bounds = {
- r: getBounds(h.r),
- g: getBounds(h.g),
- b: getBounds(h.b)
- };
- // apply value transformations
- this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function(
- x,
- y,
- idx
- ) {
- const r = this.bitmap.data[idx + 0];
- const g = this.bitmap.data[idx + 1];
- const b = this.bitmap.data[idx + 2];
- this.bitmap.data[idx + 0] = normalize(r, bounds.r[0], bounds.r[1]);
- this.bitmap.data[idx + 1] = normalize(g, bounds.g[0], bounds.g[1]);
- this.bitmap.data[idx + 2] = normalize(b, bounds.b[0], bounds.b[1]);
- });
- if (isNodePattern(cb)) {
- cb.call(this, null, this);
- }
- return this;
- }
- });
|