|
|
import { isNodePattern } from "@jimp/utils"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)]; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default (() => ({ |
|
|
normalize(cb) { |
|
|
const h = histogram.call(this); |
|
|
|
|
|
|
|
|
const bounds = { |
|
|
r: getBounds(h.r), |
|
|
g: getBounds(h.g), |
|
|
b: getBounds(h.b) |
|
|
}; |
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
})); |
|
|
|