Path: blob/master/node_modules/@jimp/plugin-gaussian/src/index.js
1126 views
import { isNodePattern, throwError } from '@jimp/utils';12/**3* Applies a true Gaussian blur to the image (warning: this is VERY slow)4* @param {number} r the pixel radius of the blur5* @param {function(Error, Jimp)} cb (optional) a callback for when complete6* @returns {Jimp} this for chaining of methods7*/8export default () => ({9gaussian(r, cb) {10// http://blog.ivank.net/fastest-gaussian-blur.html11if (typeof r !== 'number') {12return throwError.call(this, 'r must be a number', cb);13}1415if (r < 1) {16return throwError.call(this, 'r must be greater than 0', cb);17}1819const rs = Math.ceil(r * 2.57); // significant radius20const range = rs * 2 + 1;21const rr2 = r * r * 2;22const rr2pi = rr2 * Math.PI;2324const weights = [];2526for (let y = 0; y < range; y++) {27weights[y] = [];28for (let x = 0; x < range; x++) {29const dsq = (x - rs) ** 2 + (y - rs) ** 2 ;30weights[y][x] = Math.exp(-dsq / rr2) / rr2pi;31}32}3334for (let y = 0; y < this.bitmap.height; y++) {35for (let x = 0; x < this.bitmap.width; x++) {36let red = 0;37let green = 0;38let blue = 0;39let alpha = 0;40let wsum = 0;4142for (let iy = 0; iy < range; iy++) {43for (let ix = 0; ix < range; ix++) {44const x1 = Math.min(this.bitmap.width - 1, Math.max(0, ix + x - rs ));45const y1 = Math.min(this.bitmap.height - 1, Math.max(0, iy + y - rs));46const weight = weights[iy][ix];47const idx = (y1 * this.bitmap.width + x1) << 2;4849red += this.bitmap.data[idx] * weight;50green += this.bitmap.data[idx + 1] * weight;51blue += this.bitmap.data[idx + 2] * weight;52alpha += this.bitmap.data[idx + 3] * weight;53wsum += weight;54}5556const idx = (y * this.bitmap.width + x) << 2;5758this.bitmap.data[idx] = Math.round(red / wsum);59this.bitmap.data[idx + 1] = Math.round(green / wsum);60this.bitmap.data[idx + 2] = Math.round(blue / wsum);61this.bitmap.data[idx + 3] = Math.round(alpha / wsum);62}63}64}6566if (isNodePattern(cb)) {67cb.call(this, null, this);68}6970return this;71}72});737475