From 387f5389edb22fddfe1654b36c63d88aaac7d7c9 Mon Sep 17 00:00:00 2001 From: easylogic Date: Sat, 4 Aug 2018 15:22:00 +0900 Subject: [PATCH] Refactoring filter functions --- addon/codemirror-colorpicker.js | 2488 +++++++++--------- dist/codemirror-colorpicker.js | 2527 ++++++++++--------- dist/codemirror-colorpicker.min.js | 2 +- package.json | 2 +- src/util/ImageFilter.js | 1025 +------- src/util/filter/functions.js | 274 ++ src/util/filter/image/crop.js | 16 + src/util/filter/image/flipH.js | 23 + src/util/filter/image/flipV.js | 25 + src/util/filter/image/index.js | 16 + src/util/filter/image/resize.js | 18 + src/util/filter/image/rotate.js | 46 + src/util/filter/image/rotateDegree.js | 53 + src/util/filter/index.js | 9 + src/util/filter/matrix/blur.js | 12 + src/util/filter/matrix/emboss.js | 17 + src/util/filter/matrix/gaussian-blur-5x.js | 17 + src/util/filter/matrix/gaussian-blur.js | 16 + src/util/filter/matrix/grayscale2.js | 16 + src/util/filter/matrix/identity.js | 11 + src/util/filter/matrix/index.js | 60 + src/util/filter/matrix/kirsch-horizontal.js | 13 + src/util/filter/matrix/kirsch-vertical.js | 13 + src/util/filter/matrix/laplacian-5x.js | 16 + src/util/filter/matrix/laplacian.js | 14 + src/util/filter/matrix/motion-blur-2.js | 18 + src/util/filter/matrix/motion-blur-3.js | 19 + src/util/filter/matrix/motion-blur.js | 18 + src/util/filter/matrix/negative.js | 16 + src/util/filter/matrix/random.js | 14 + src/util/filter/matrix/sepia2.js | 16 + src/util/filter/matrix/sharpen.js | 14 + src/util/filter/matrix/sobel-horizontal.js | 11 + src/util/filter/matrix/sobel-vertical.js | 11 + src/util/filter/matrix/stack-blur.js | 13 + src/util/filter/matrix/transparency.js | 16 + src/util/filter/matrix/unsharp-masking.js | 16 + src/util/filter/pixel/bitonal.js | 20 + src/util/filter/pixel/brightness.js | 18 + src/util/filter/pixel/clip.js | 25 + src/util/filter/pixel/contrast.js | 18 + src/util/filter/pixel/gamma.js | 13 + src/util/filter/pixel/gradient.js | 49 + src/util/filter/pixel/grayscale.js | 22 + src/util/filter/pixel/hue.js | 29 + src/util/filter/pixel/index.js | 38 + src/util/filter/pixel/invert.js | 16 + src/util/filter/pixel/noise.js | 21 + src/util/filter/pixel/opacity.js | 14 + src/util/filter/pixel/saturation.js | 24 + src/util/filter/pixel/sepia.js | 24 + src/util/filter/pixel/shade.js | 16 + src/util/filter/pixel/solarize.js | 21 + src/util/filter/pixel/threshold-color.js | 27 + src/util/filter/pixel/threshold.js | 7 + src/util/filter/pixel/tint.js | 13 + 56 files changed, 3847 insertions(+), 3479 deletions(-) create mode 100644 src/util/filter/functions.js create mode 100644 src/util/filter/image/crop.js create mode 100644 src/util/filter/image/flipH.js create mode 100644 src/util/filter/image/flipV.js create mode 100644 src/util/filter/image/index.js create mode 100644 src/util/filter/image/resize.js create mode 100644 src/util/filter/image/rotate.js create mode 100644 src/util/filter/image/rotateDegree.js create mode 100644 src/util/filter/index.js create mode 100644 src/util/filter/matrix/blur.js create mode 100644 src/util/filter/matrix/emboss.js create mode 100644 src/util/filter/matrix/gaussian-blur-5x.js create mode 100644 src/util/filter/matrix/gaussian-blur.js create mode 100644 src/util/filter/matrix/grayscale2.js create mode 100644 src/util/filter/matrix/identity.js create mode 100644 src/util/filter/matrix/index.js create mode 100644 src/util/filter/matrix/kirsch-horizontal.js create mode 100644 src/util/filter/matrix/kirsch-vertical.js create mode 100644 src/util/filter/matrix/laplacian-5x.js create mode 100644 src/util/filter/matrix/laplacian.js create mode 100644 src/util/filter/matrix/motion-blur-2.js create mode 100644 src/util/filter/matrix/motion-blur-3.js create mode 100644 src/util/filter/matrix/motion-blur.js create mode 100644 src/util/filter/matrix/negative.js create mode 100644 src/util/filter/matrix/random.js create mode 100644 src/util/filter/matrix/sepia2.js create mode 100644 src/util/filter/matrix/sharpen.js create mode 100644 src/util/filter/matrix/sobel-horizontal.js create mode 100644 src/util/filter/matrix/sobel-vertical.js create mode 100644 src/util/filter/matrix/stack-blur.js create mode 100644 src/util/filter/matrix/transparency.js create mode 100644 src/util/filter/matrix/unsharp-masking.js create mode 100644 src/util/filter/pixel/bitonal.js create mode 100644 src/util/filter/pixel/brightness.js create mode 100644 src/util/filter/pixel/clip.js create mode 100644 src/util/filter/pixel/contrast.js create mode 100644 src/util/filter/pixel/gamma.js create mode 100644 src/util/filter/pixel/gradient.js create mode 100644 src/util/filter/pixel/grayscale.js create mode 100644 src/util/filter/pixel/hue.js create mode 100644 src/util/filter/pixel/index.js create mode 100644 src/util/filter/pixel/invert.js create mode 100644 src/util/filter/pixel/noise.js create mode 100644 src/util/filter/pixel/opacity.js create mode 100644 src/util/filter/pixel/saturation.js create mode 100644 src/util/filter/pixel/sepia.js create mode 100644 src/util/filter/pixel/shade.js create mode 100644 src/util/filter/pixel/solarize.js create mode 100644 src/util/filter/pixel/threshold-color.js create mode 100644 src/util/filter/pixel/threshold.js create mode 100644 src/util/filter/pixel/tint.js diff --git a/addon/codemirror-colorpicker.js b/addon/codemirror-colorpicker.js index f59b59e..7570c29 100644 --- a/addon/codemirror-colorpicker.js +++ b/addon/codemirror-colorpicker.js @@ -441,6 +441,20 @@ var defineProperty = function (obj, key, value) { return obj; }; +var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; + var get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); @@ -1770,1599 +1784,1619 @@ var HueColor = { checkHueColor: checkHueColor }; -/* +var CONSTANT = { + identity: function identity() { + return [1, 0, 0, 0, 1, 0, 0, 0, 1]; + }, + stretching: function stretching(k) { + return [k, 0, 0, 0, 1, 0, 0, 0, 1]; + }, + squeezing: function squeezing(k) { + return [k, 0, 0, 0, 1 / k, 0, 0, 0, 1]; + }, + scale: function scale() { + var sx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var sy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; -StackBlur - a fast almost Gaussian Blur For Canvas + sx = sx || sx === 0 ? sx : 1; + sy = sy || sy === 0 ? sy : 1; + return [sx, 0, 0, 0, sy, 0, 0, 0, 1]; + }, + scaleX: function scaleX(sx) { + return this.scale(sx); + }, + scaleY: function scaleY(sy) { + return this.scale(1, sy); + }, + translate: function translate(tx, ty) { + return [1, 0, tx, 0, 1, ty, 0, 0, 1]; + }, + rotate: function rotate(angle) { + var r = this.radian(angle); + return [Math.cos(r), -Math.sin(r), 0, Math.sin(r), Math.cos(r), 0, 0, 0, 1]; + }, + rotate90: function rotate90() { + return [0, -1, 0, 1, 0, 0, 0, 0, 1]; + }, + rotate180: function rotate180() { + return [-1, 0, 0, 0, -1, 0, 0, 0, 1]; + }, + rotate270: function rotate270() { + return [0, 1, 0, -1, 0, 0, 0, 0, 1]; + }, + radian: function radian(degree) { + return degree * Math.PI / 180; + }, + skew: function skew(degreeX, degreeY) { + var radianX = this.radian(degreeX); + var radianY = this.radian(degreeY); + return [1, Math.tan(radianX), 0, Math.tan(radianY), 1, 0, 0, 0, 1]; + }, + skewX: function skewX(degreeX) { + var radianX = this.radian(degreeX); -Version: 0.5 -Author: Mario Klingemann -Contact: mario@quasimondo.com -Website: http://www.quasimondo.com/StackBlurForCanvas -Twitter: @quasimondo + return [1, Math.tan(radianX), 0, 0, 1, 0, 0, 0, 1]; + }, + skewY: function skewY(degreeY) { + var radianY = this.radian(degreeY); -In case you find this class useful - especially in commercial projects - -I am not totally unhappy for a small donation to my PayPal account -mario@quasimondo.de + return [1, 0, 0, Math.tan(radianY), 1, 0, 0, 0, 1]; + }, + shear1: function shear1(angle) { + return [1, -Math.tan(this.radian(angle) / 2), 0, 0, 1, 0, 0, 0, 1]; + }, + shear2: function shear2(angle) { + return [1, 0, 0, Math.sin(this.radian(angle)), 1, 0, 0, 0, 1]; + } +}; -Or support me on flattr: -https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript +var Matrix = { + CONSTANT: CONSTANT, -Copyright (c) 2010 Mario Klingemann + radian: function radian(angle) { + return CONSTANT.radian(angle); + }, + multiply: function multiply(A, C) { + // console.log(JSON.stringify(A), JSON.stringify(C)) + return [A[0] * C[0] + A[1] * C[1] + A[2] * C[2], A[3] * C[0] + A[4] * C[1] + A[5] * C[2], A[6] * C[0] + A[7] * C[1] + A[8] * C[2]]; + }, + identity: function identity(B) { + return this.multiply(CONSTANT.identity(), B); + }, + translate: function translate(x, y, B) { + return this.multiply(CONSTANT.translate(x, y), B); + }, + rotate: function rotate(angle, B) { + return this.multiply(CONSTANT.rotate(angle), B); + }, + shear1: function shear1(angle, B) { + return this.multiply(CONSTANT.shear1(angle), B); + }, + shear2: function shear2(angle, B) { + return this.multiply(CONSTANT.shear2(angle), B); + }, + rotateShear: function rotateShear(angle, B) { -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: + var arr = B; -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. + arr = this.shear1(angle, arr); + arr = this.shear2(angle, arr); + arr = this.shear1(angle, arr); -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ + return arr; + } +}; -var mul_table = [512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; +function weight(arr) { + var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; -var shg_table = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; + return arr.map(function (i) { + return i * num; + }); +} -function BlurStack() { - this.r = 0; - this.g = 0; - this.b = 0; - this.a = 0; - this.next = null; +function repeat(value, num) { + var arr = new Array(num); + for (var i = 0; i < num; i++) { + arr[i] = value; + } + return arr; } -function stackBlurImage(bitmap, radius, blurAlphaChannel) { +function colorMatrix(pixels, i, matrix) { + var r = pixels[i], + g = pixels[i + 1], + b = pixels[i + 2], + a = pixels[i + 3]; - if (blurAlphaChannel) return stackBlurCanvasRGBA(bitmap, 0, 0, radius);else return stackBlurCanvasRGB(bitmap, 0, 0, radius); + pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; + pixels[i + 1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; + pixels[i + 2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; + pixels[i + 3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; } -function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { - if (isNaN(radius) || radius < 1) return bitmap; - radius |= 0; +function makeFilter(filter, F) { - var pixels = bitmap.pixels, - width = bitmap.width, - height = bitmap.height; + if (typeof filter == 'function') { + return filter; + } - var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, r_out_sum, g_out_sum, b_out_sum, a_out_sum, r_in_sum, g_in_sum, b_in_sum, a_in_sum, pr, pg, pb, pa, rbs; + if (typeof filter == 'string') { + filter = [filter]; + } - var div = radius + radius + 1; - var widthMinus1 = width - 1; - var heightMinus1 = height - 1; - var radiusPlus1 = radius + 1; - var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var filterName = filter.shift(); - var stackStart = new BlurStack(); - var stack = stackStart; - for (i = 1; i < div; i++) { - stack = stack.next = new BlurStack(); - if (i == radiusPlus1) var stackEnd = stack; + if (typeof filterName == 'function') { + return filterName; } - stack.next = stackStart; - var stackIn = null; - var stackOut = null; - - yw = yi = 0; - var mul_sum = mul_table[radius]; - var shg_sum = shg_table[radius]; + var params = filter; - for (y = 0; y < height; y++) { - r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; + var filterFunction = F[filterName]; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); + if (!filterFunction) { + throw new Error(filterName + ' is not filter. please check filter name.'); + } + return filterFunction.apply(filterFunction, params); +} - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - a_sum += sumFactor * pa; +function each$1(len, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex); + } +} - stack = stackStart; +function eachXY(len, width, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex % width, Math.floor(xyIndex / width)); + } +} - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack.a = pa; - stack = stack.next; - } +function createRandRange(min, max, count) { + var result = []; - for (i = 1; i < radiusPlus1; i++) { - p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); - r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[p + 1]) * rbs; - b_sum += (stack.b = pb = pixels[p + 2]) * rbs; - a_sum += (stack.a = pa = pixels[p + 3]) * rbs; + for (var i = 1; i <= count; i++) { + var num = Math.random() * (max - min) + min; + var sign = Math.floor(Math.random() * 10) % 2 == 0 ? -1 : 1; + result.push(sign * num); + } - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; - a_in_sum += pa; + result.sort(); - stack = stack.next; - } + var centerIndex = Math.floor(count / 2); + var a = result[centerIndex]; + result[centerIndex] = result[0]; + result[0] = a; - stackIn = stackStart; - stackOut = stackEnd; - for (x = 0; x < width; x++) { - pixels[yi + 3] = pa = a_sum * mul_sum >> shg_sum; - if (pa != 0) { - pa = 255 / pa; - pixels[yi] = (r_sum * mul_sum >> shg_sum) * pa; - pixels[yi + 1] = (g_sum * mul_sum >> shg_sum) * pa; - pixels[yi + 2] = (b_sum * mul_sum >> shg_sum) * pa; - } else { - pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; - } + return result; +} - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; - a_sum -= a_out_sum; +function createRandomCount() { + return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { + return 0.5 - Math.random(); + })[0]; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; - a_out_sum -= stackIn.a; +function createBitmap(length, width, height) { + return { pixels: new Uint8ClampedArray(length), width: width, height: height }; +} - p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; +function getBitmap(bitmap, area) { + return Canvas.getBitmap(bitmap, area); +} - r_in_sum += stackIn.r = pixels[p]; - g_in_sum += stackIn.g = pixels[p + 1]; - b_in_sum += stackIn.b = pixels[p + 2]; - a_in_sum += stackIn.a = pixels[p + 3]; +function putBitmap(bitmap, subBitmap, area) { + return Canvas.putBitmap(bitmap, subBitmap, area); +} - r_sum += r_in_sum; - g_sum += g_in_sum; - b_sum += b_in_sum; - a_sum += a_in_sum; +function parseParamNumber(param) { + if (typeof param === 'string') { + param = param.replace(/deg/, ''); + param = param.replace(/px/, ''); + } + return +param; +} - stackIn = stackIn.next; +var filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; +function pack$1(callback) { + return function (bitmap) { + each$1(bitmap.pixels.length, function (i, xyIndex) { + callback(bitmap.pixels, i, xyIndex); + }); + return bitmap; + }; +} - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; - a_out_sum += pa = stackOut.a; +var ColorListIndex = [0, 1, 2, 3]; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; - a_in_sum -= pa; +function swapColor(pixels, startIndex, endIndex) { - stackOut = stackOut.next; + ColorListIndex.forEach(function (i) { + var temp = pixels[startIndex + i]; + pixels[startIndex + i] = pixels[endIndex + i]; + pixels[endIndex + i] = temp; + }); +} - yi += 4; - } - yw += width; - } +function packXY(callback) { + return function (bitmap) { + eachXY(bitmap.pixels.length, bitmap.width, function (i, x, y) { + callback(bitmap.pixels, i, x, y); + }); + return bitmap; + }; +} - for (x = 0; x < width; x++) { - g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; - yi = x << 2; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - a_sum += sumFactor * pa; +function createBlurMatrix() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - stack = stackStart; + var count = Math.pow(amount, 2); + var value = 1 / count; + return repeat(value, count); +} - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack.a = pa; - stack = stack.next; - } +function convolution(weights) { + var opaque = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - yp = width; + return function (_ref) { + var pixels = _ref.pixels, + width = _ref.width, + height = _ref.height; - for (i = 1; i <= radius; i++) { - yi = yp + x << 2; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); - r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; - b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; - a_sum += (stack.a = pa = pixels[yi + 3]) * rbs; + var w = width; + var h = height; + var sw = w; + var sh = h; + var dst = new Uint8ClampedArray(pixels.length); + var alphaFac = opaque ? 1 : 0; - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; - a_in_sum += pa; + for (var y = 0; y < h; y++) { + for (var x = 0; x < w; x++) { + var sy = y; + var sx = x; + var dstIndex = (y * w + x) * 4; - stack = stack.next; + var r = 0, + g = 0, + b = 0, + a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { - if (i < heightMinus1) { - yp += width; + var scy = sy + cy - halfSide; + var scx = sx + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + var srcIndex = (scy * sw + scx) * 4; + var wt = weights[cy * side + cx]; + r += pixels[srcIndex] * wt; + g += pixels[srcIndex + 1] * wt; + b += pixels[srcIndex + 2] * wt; + a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. + } + } + } + + dst[dstIndex] = r; + dst[dstIndex + 1] = g; + dst[dstIndex + 2] = b; + dst[dstIndex + 3] = a + alphaFac * (255 - a); } } - yi = x; - stackIn = stackStart; - stackOut = stackEnd; - for (y = 0; y < height; y++) { - p = yi << 2; - pixels[p + 3] = pa = a_sum * mul_sum >> shg_sum; - if (pa > 0) { - pa = 255 / pa; - pixels[p] = (r_sum * mul_sum >> shg_sum) * pa; - pixels[p + 1] = (g_sum * mul_sum >> shg_sum) * pa; - pixels[p + 2] = (b_sum * mul_sum >> shg_sum) * pa; - } else { - pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; - } + return { pixels: dst, width: sw, height: sh }; + }; +} - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; - a_sum -= a_out_sum; +function matches(str) { + var ret = Color.convertMatches(str); + var matches = ret.str.match(filter_regexp); + var result = []; - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; - a_out_sum -= stackIn.a; + if (!matches) { + return result; + } - p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; + result = matches.map(function (it) { + return { filter: it, origin: Color.reverseMatches(it, ret.matches) }; + }); - r_sum += r_in_sum += stackIn.r = pixels[p]; - g_sum += g_in_sum += stackIn.g = pixels[p + 1]; - b_sum += b_in_sum += stackIn.b = pixels[p + 2]; - a_sum += a_in_sum += stackIn.a = pixels[p + 3]; + var pos = { next: 0 }; + result = result.map(function (item) { - stackIn = stackIn.next; + var startIndex = str.indexOf(item.origin, pos.next); - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; - a_out_sum += pa = stackOut.a; + item.startIndex = startIndex; + item.endIndex = startIndex + item.origin.length; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; - a_in_sum -= pa; + item.arr = parseFilter(item.origin); - stackOut = stackOut.next; + pos.next = item.endIndex; - yi += width; - } - } + return item; + }).filter(function (it) { + if (!it.arr.length) return false; + return true; + }); - return bitmap; + return result; } -function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { - if (isNaN(radius) || radius < 1) return bitmap; - radius |= 0; +/** + * Filter Parser + * + * F.parseFilter('blur(30)') == ['blue', '30'] + * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] + * + * @param {String} filterString + */ +function parseFilter(filterString) { - var pixels = bitmap.pixels, - width = bitmap.width, - height = bitmap.height; + var ret = Color.convertMatches(filterString); + var matches = ret.str.match(filter_regexp); - var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, r_out_sum, g_out_sum, b_out_sum, r_in_sum, g_in_sum, b_in_sum, pr, pg, pb, rbs; + if (!matches[0]) { + return []; + } - var div = radius + radius + 1; - var widthMinus1 = width - 1; - var heightMinus1 = height - 1; - var radiusPlus1 = radius + 1; - var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var arr = matches[0].split('('); - var stackStart = new BlurStack(); - var stack = stackStart; - for (i = 1; i < div; i++) { - stack = stack.next = new BlurStack(); - if (i == radiusPlus1) var stackEnd = stack; + var filterName = arr.shift(); + var filterParams = []; + + if (arr.length) { + filterParams = arr.shift().split(')')[0].split(',').map(function (f) { + return Color.reverseMatches(f, ret.matches); + }); } - stack.next = stackStart; - var stackIn = null; - var stackOut = null; - yw = yi = 0; + var result = [filterName].concat(toConsumableArray(filterParams)).map(Color.trim); - var mul_sum = mul_table[radius]; - var shg_sum = shg_table[radius]; + return result; +} - for (y = 0; y < height; y++) { - r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0; +function clamp(num) { + return Math.min(255, num); +} - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); +function crop() { + var startX = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var startY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var width = arguments[2]; + var height = arguments[3]; - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - stack = stackStart; + var newBitmap = createBitmap(width * height * 4, width, height); - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack = stack.next; + return function (bitmap) { + for (var y = startY, realY = 0; y < height; y++, realY++) { + for (var x = startX, realX = 0; x < width; x++, realX++) { + newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x]; + } } - for (i = 1; i < radiusPlus1; i++) { - p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); - r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[p + 1]) * rbs; - b_sum += (stack.b = pb = pixels[p + 2]) * rbs; + return newBitmap; + }; +} - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; +function resize(dstWidth, dstHeight) { + return function (bitmap) { - stack = stack.next; - } + var c = Canvas.drawPixels(bitmap); + var context = c.getContext('2d'); - stackIn = stackStart; - stackOut = stackEnd; - for (x = 0; x < width; x++) { - pixels[yi] = r_sum * mul_sum >> shg_sum; - pixels[yi + 1] = g_sum * mul_sum >> shg_sum; - pixels[yi + 2] = b_sum * mul_sum >> shg_sum; + c.width = dstWidth; + c.height = dstHeight; - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; + return { + pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), + width: dstWidth, + height: dstHeight + }; + }; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; +function flipV() { + return function (bitmap) { - p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; + var width = bitmap.width; + var height = bitmap.height; + var isCenter = height % 2 == 1 ? 1 : 0; - r_in_sum += stackIn.r = pixels[p]; - g_in_sum += stackIn.g = pixels[p + 1]; - b_in_sum += stackIn.b = pixels[p + 2]; + var halfHeight = isCenter ? Math.floor(height / 2) : height / 2; - r_sum += r_in_sum; - g_sum += g_in_sum; - b_sum += b_in_sum; + for (var y = 0; y < halfHeight; y++) { + for (var x = 0; x < width; x++) { - stackIn = stackIn.next; + var startIndex = (y * width + x) * 4; + var endIndex = ((height - 1 - y) * width + x) * 4; + swapColor(bitmap.pixels, startIndex, endIndex); + } + } - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; + return bitmap; + }; +} - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; +function flipH() { + return function (bitmap) { - stackOut = stackOut.next; + var width = bitmap.width; + var height = bitmap.height; + var isCenter = width % 2 == 1 ? 1 : 0; - yi += 4; + var halfWidth = isCenter ? Math.floor(width / 2) : width / 2; + + for (var y = 0; y < height; y++) { + for (var x = 0; x < halfWidth; x++) { + + var startIndex = (y * width + x) * 4; + var endIndex = (y * width + (width - 1 - x)) * 4; + swapColor(bitmap.pixels, startIndex, endIndex); + } } - yw += width; - } - for (x = 0; x < width; x++) { - g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0; + return bitmap; + }; +} - yi = x << 2; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); +function rotateDegree(angle) { + var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'center'; + var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'center'; - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; + // const r = F.radian(angle) - stack = stackStart; + return function (bitmap) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); + var width = bitmap.width; + var height = bitmap.height; - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack = stack.next; + if (cx == 'center') { + cx = Math.floor(width / 2); } - yp = width; + if (cy == 'center') { + cy = Math.floor(height / 2); + } - for (i = 1; i <= radius; i++) { - yi = yp + x << 2; + var translateMatrix = Matrix.CONSTANT.translate(-cx, -cy); + var translateMatrix2 = Matrix.CONSTANT.translate(cx, cy); + var shear1Matrix = Matrix.CONSTANT.shear1(angle); + var shear2Matrix = Matrix.CONSTANT.shear2(angle); - r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; - b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; + return packXY(function (pixels, i, x, y) { + // console.log(x, y, i) + var arr = Matrix.multiply(translateMatrix, [x, y, 1]); - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); + arr = Matrix.multiply(shear2Matrix, arr).map(Math.round); + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); + arr = Matrix.multiply(translateMatrix2, arr); - stack = stack.next; + var _arr = arr, + _arr2 = slicedToArray(_arr, 2), + x1 = _arr2[0], + y1 = _arr2[1]; - if (i < heightMinus1) { - yp += width; - } - } + if (x1 < 0) return; + if (y1 < 0) return; + if (x1 > width - 1) return; + if (y1 > height - 1) return; - yi = x; - stackIn = stackStart; - stackOut = stackEnd; - for (y = 0; y < height; y++) { - p = yi << 2; - pixels[p] = r_sum * mul_sum >> shg_sum; - pixels[p + 1] = g_sum * mul_sum >> shg_sum; - pixels[p + 2] = b_sum * mul_sum >> shg_sum; + var endIndex = (y1 * width + x1) * 4; - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; + pixels[endIndex] = bitmap.pixels[i]; + pixels[endIndex + 1] = bitmap.pixels[i + 1]; + pixels[endIndex + 2] = bitmap.pixels[i + 2]; + pixels[endIndex + 3] = bitmap.pixels[i + 3]; + })(newBitmap); + }; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; +function rotate() { + var degree = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; + degree = parseParamNumber(degree); + degree = degree % 360; + return function (bitmap) { - r_sum += r_in_sum += stackIn.r = pixels[p]; - g_sum += g_in_sum += stackIn.g = pixels[p + 1]; - b_sum += b_in_sum += stackIn.b = pixels[p + 2]; + if (degree == 0) return bitmap; - stackIn = stackIn.next; + if (degree == 90 || degree == 270) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width); + } else if (degree == 180) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); + } else { + return rotateDegree(degree)(bitmap); + } - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; + var width = bitmap.width; + var height = bitmap.height; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; + packXY(function (pixels, i, x, y) { - stackOut = stackOut.next; + if (degree == 90) { + var endIndex = (x * newBitmap.width + (newBitmap.width - 1 - y)) * 4; + } else if (degree == 270) { + var endIndex = ((newBitmap.height - 1 - x) * newBitmap.width + y) * 4; + } else if (degree == 180) { + var endIndex = ((newBitmap.height - 1 - y) * newBitmap.width + (newBitmap.width - 1 - x)) * 4; + } - yi += width; - } - } + newBitmap.pixels[endIndex] = bitmap.pixels[i]; + newBitmap.pixels[endIndex + 1] = bitmap.pixels[i + 1]; + newBitmap.pixels[endIndex + 2] = bitmap.pixels[i + 2]; + newBitmap.pixels[endIndex + 3] = bitmap.pixels[i + 3]; + })(bitmap); - return bitmap; -} + return newBitmap; + }; +} -var CONSTANT = { - identity: function identity() { - return [1, 0, 0, 0, 1, 0, 0, 0, 1]; - }, - stretching: function stretching(k) { - return [k, 0, 0, 0, 1, 0, 0, 0, 1]; - }, - squeezing: function squeezing(k) { - return [k, 0, 0, 0, 1 / k, 0, 0, 0, 1]; - }, - scale: function scale() { - var sx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var sy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; +var image = { + crop: crop, + resize: resize, + flipH: flipH, + flipV: flipV, + rotate: rotate, + rotateDegree: rotateDegree, + 'rotate-degree': rotateDegree +}; - sx = sx || sx === 0 ? sx : 1; - sy = sy || sy === 0 ? sy : 1; - return [sx, 0, 0, 0, sy, 0, 0, 0, 1]; - }, - scaleX: function scaleX(sx) { - return this.scale(sx); - }, - scaleY: function scaleY(sy) { - return this.scale(1, sy); - }, - translate: function translate(tx, ty) { - return [1, 0, tx, 0, 1, ty, 0, 0, 1]; - }, - rotate: function rotate(angle) { - var r = this.radian(angle); - return [Math.cos(r), -Math.sin(r), 0, Math.sin(r), Math.cos(r), 0, 0, 0, 1]; - }, - rotate90: function rotate90() { - return [0, -1, 0, 1, 0, 0, 0, 0, 1]; - }, - rotate180: function rotate180() { - return [-1, 0, 0, 0, -1, 0, 0, 0, 1]; - }, - rotate270: function rotate270() { - return [0, 1, 0, -1, 0, 0, 0, 0, 1]; - }, - radian: function radian(degree) { - return degree * Math.PI / 180; - }, - skew: function skew(degreeX, degreeY) { - var radianX = this.radian(degreeX); - var radianY = this.radian(degreeY); - return [1, Math.tan(radianX), 0, Math.tan(radianY), 1, 0, 0, 0, 1]; - }, - skewX: function skewX(degreeX) { - var radianX = this.radian(degreeX); +function bitonal(darkColor, lightColor) { + var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100; - return [1, Math.tan(radianX), 0, 0, 1, 0, 0, 0, 1]; - }, - skewY: function skewY(degreeY) { - var radianY = this.radian(degreeY); + darkColor = color.parse(darkColor); + lightColor = color.parse(lightColor); + return pack$1(function (pixels, i) { - return [1, 0, 0, Math.tan(radianY), 1, 0, 0, 0, 1]; - }, - shear1: function shear1(angle) { - return [1, -Math.tan(this.radian(angle) / 2), 0, 0, 1, 0, 0, 0, 1]; - }, - shear2: function shear2(angle) { - return [1, 0, 0, Math.sin(this.radian(angle)), 1, 0, 0, 0, 1]; - } -}; + if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { + pixels[i] = darkColor.r; + pixels[i + 1] = darkColor.g; + pixels[i + 2] = darkColor.b; + } else { + pixels[i] = lightColor.r; + pixels[i + 1] = lightColor.g; + pixels[i + 2] = lightColor.b; + } + }); +} -var Matrix = { - CONSTANT: CONSTANT, +function brightness() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - radian: function radian(angle) { - return CONSTANT.radian(angle); - }, - multiply: function multiply(A, C) { - // console.log(JSON.stringify(A), JSON.stringify(C)) - return [A[0] * C[0] + A[1] * C[1] + A[2] * C[2], A[3] * C[0] + A[4] * C[1] + A[5] * C[2], A[6] * C[0] + A[7] * C[1] + A[8] * C[2]]; - }, - identity: function identity(B) { - return this.multiply(CONSTANT.identity(), B); - }, - translate: function translate(x, y, B) { - return this.multiply(CONSTANT.translate(x, y), B); - }, - rotate: function rotate(angle, B) { - return this.multiply(CONSTANT.rotate(angle), B); - }, - shear1: function shear1(angle, B) { - return this.multiply(CONSTANT.shear1(angle), B); - }, - shear2: function shear2(angle, B) { - return this.multiply(CONSTANT.shear2(angle), B); - }, - rotateShear: function rotateShear(angle, B) { + amount = parseParamNumber(amount); + var C = Math.floor(255 * (amount / 100)); - var arr = B; + return pack$1(function (pixels, i) { + pixels[i] += C; + pixels[i + 1] += C; + pixels[i + 2] += C; + }); +} - arr = this.shear1(angle, arr); - arr = this.shear2(angle, arr); - arr = this.shear1(angle, arr); +function clip() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - return arr; - } -}; + amount = parseParamNumber(amount); + var C = Math.abs(amount) * 2.55; -// TODO: worker run -function weight(arr) { - var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return pack$1(function (pixels, i) { - return arr.map(function (i) { - return i * num; + for (var start = i, end = i + 2; start <= end; start++) { + if (pixels[start] > 255 - C) { + pixels[start] = 255; + } else if (pixels[start] < C) { + pixels[start] = 0; + } + } }); } -function repeat(value, num) { - var arr = new Array(num); - for (var i = 0; i < num; i++) { - arr[i] = value; - } - return arr; +function contrast() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + + amount = parseParamNumber(amount); + var C = Math.max((128 + amount) / 128, 0); + + return pack$1(function (pixels, i) { + pixels[i] = pixels[i] * C; + pixels[i + 1] = pixels[i + 1] * C; + pixels[i + 2] = pixels[i + 2] * C; + }); } -function colorMatrix(pixels, i, matrix) { - var r = pixels[i], - g = pixels[i + 1], - b = pixels[i + 2], - a = pixels[i + 3]; +function gamma() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; - pixels[i + 1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; - pixels[i + 2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; - pixels[i + 3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + pixels[i] = Math.pow(pixels[i] / 255, amount) * 255; + pixels[i + 1] = Math.pow(pixels[i + 1] / 255, amount) * 255; + pixels[i + 2] = Math.pow(pixels[i + 2] / 255, amount) * 255; + }); } -function makeFilter(filter) { +function gradient() { + // 전체 매개변수 기준으로 파싱 + // 색이 아닌 것 기준으로 scale 변수로 인식 - if (typeof filter == 'function') { - return filter; - } + var params = [].concat(Array.prototype.slice.call(arguments)); - if (typeof filter == 'string') { - filter = [filter]; + if (params.length === 1 && typeof params[0] === 'string') { + params = color.convertMatchesArray(params[0]); } - var filterName = filter.shift(); + params = params.map(function (arg) { + var res = color.matches(arg); - if (typeof filterName == 'function') { - return filterName; - } + if (!res.length) { + return { type: 'scale', value: arg }; + } - var params = filter; + return { type: 'param', value: arg }; + }); - var filterFunction = F[filterName]; + var scale = params.filter(function (it) { + return it.type == 'scale'; + })[0]; + scale = scale ? +scale.value : 256; - if (!filterFunction) { - throw new Error(filterName + ' is not filter. please check filter name.'); - } - return filterFunction.apply(filterFunction, params); -} + params = params.filter(function (it) { + return it.type == 'param'; + }).map(function (it) { + return it.value; + }).join(','); -function each$1(len, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex); - } + var colors = color.gradient(params, scale).map(function (c) { + return color.parse(c); + }); + + return pack$1(function (pixels, i) { + var colorIndex = clamp(color.brightness(pixels[i], pixels[i + 1], pixels[i + 2])); + var newColorIndex = clamp(Math.floor(colorIndex * (scale / 256))); + var color$$1 = colors[newColorIndex]; + + pixels[i] = color$$1.r; + pixels[i + 1] = color$$1.g; + pixels[i + 2] = color$$1.b; + pixels[i + 3] = clamp(Math.floor(color$$1.a * 256)); + }); } -function eachXY(len, width, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex % width, Math.floor(xyIndex / width)); - } +function grayscale(amount) { + amount = parseParamNumber(amount); + var C = amount / 100; + + if (C > 1) C = 1; + + return pack$1(function (pixels, i) { + + colorMatrix(pixels, i, [0.2126 + 0.7874 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 + 0.2848 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 + 0.9278 * (1 - C), 0, 0, 0, 0, 1]); + }); } -function createRandRange(min, max, count) { - var result = []; +function hue() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 360; - for (var i = 1; i <= count; i++) { - var num = Math.random() * (max - min) + min; - var sign = Math.floor(Math.random() * 10) % 2 == 0 ? -1 : 1; - result.push(sign * num); - } + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + var r = pixels[i], + g = pixels[i + 1], + b = pixels[i + 2]; - result.sort(); + var hsv = Color.RGBtoHSV(r, g, b); - var centerIndex = Math.floor(count / 2); - var a = result[centerIndex]; - result[centerIndex] = result[0]; - result[0] = a; + // 0 ~ 360 + var h = hsv.h; + h += Math.abs(amount); + h = h % 360; + hsv.h = h; - return result; -} + var rgb = Color.HSVtoRGB(hsv); -function createRandomCount() { - return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { - return 0.5 - Math.random(); - })[0]; + pixels[i] = rgb.r; + pixels[i + 1] = rgb.g; + pixels[i + 2] = rgb.b; + }); } -function createBitmap(length, width, height) { - return { pixels: new Uint8ClampedArray(length), width: width, height: height }; -} +function invert() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -function getBitmap(bitmap, area) { - return Canvas.getBitmap(bitmap, area); -} + amount = parseParamNumber(amount); + var C = amount / 100; -function putBitmap(bitmap, subBitmap, area) { - return Canvas.putBitmap(bitmap, subBitmap, area); + return pack$1(function (pixels, i) { + + pixels[i] = (255 - pixels[i]) * C; + pixels[i + 1] = (255 - pixels[i + 1]) * C; + pixels[i + 2] = (255 - pixels[i + 2]) * C; + }); } -function parseParamNumber(param) { - if (typeof param === 'string') { - param = param.replace(/deg/, ''); - param = param.replace(/px/, ''); - } - return +param; +function noise() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + var C = Math.abs(amount) * 5; + var min = -C; + var max = C; + var noiseValue = Math.round(min + Math.random() * (max - min)); + pixels[i] += noiseValue; + pixels[i + 1] += noiseValue; + pixels[i + 2] += noiseValue; + }); } -var F = {}; -var ImageFilter = F; +function opacity() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -var filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; -var pack$1 = F.pack = function pack(callback) { - return function (bitmap) { - each$1(bitmap.pixels.length, function (i, xyIndex) { - callback(bitmap.pixels, i, xyIndex); - }); - return bitmap; - }; -}; + amount = parseParamNumber(amount); + var C = amount / 100; -var ColorListIndex = [0, 1, 2, 3]; + return pack$1(function (pixels, i) { + pixels[i + 3] *= C; + }); +} -var swapColor = F.swapColor = function swapColor(pixels, startIndex, endIndex) { +function saturation() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - ColorListIndex.forEach(function (i) { - var temp = pixels[startIndex + i]; - pixels[startIndex + i] = pixels[endIndex + i]; - pixels[endIndex + i] = temp; + amount = parseParamNumber(amount); + var C = amount / 100; + var L = 1 - Math.abs(C); + return pack$1(function (pixels, i) { + + colorMatrix(pixels, i, [L, 0, 0, 0, 0, L, 0, 0, 0, 0, L, 0, 0, 0, 0, L]); }); -}; +} -var packXY = F.packXY = function packXY(callback) { - return function (bitmap) { - eachXY(bitmap.pixels.length, bitmap.width, function (i, x, y) { - callback(bitmap.pixels, i, x, y); - }); - return bitmap; - }; -}; +function sepia() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.matches = function (str) { - var _this = this; + amount = parseParamNumber(amount); + var C = amount / 100; + if (C > 1) C = 1; - var ret = color.convertMatches(str); - var matches = ret.str.match(filter_regexp); - var result = []; + return pack$1(function (pixels, i) { - if (!matches) { - return result; - } + colorMatrix(pixels, i, [0.393 + 0.607 * (1 - C), 0.769 - 0.769 * (1 - C), 0.189 - 0.189 * (1 - C), 0, 0.349 - 0.349 * (1 - C), 0.686 + 0.314 * (1 - C), 0.168 - 0.168 * (1 - C), 0, 0.272 - 0.272 * (1 - C), 0.534 - 0.534 * (1 - C), 0.131 + 0.869 * (1 - C), 0, 0, 0, 0, 1]); + }); +} - result = matches.map(function (it) { - return { filter: it, origin: color.reverseMatches(it, ret.matches) }; +function shade() { + var r = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var g = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + var b = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + + r = parseParamNumber(r); + g = parseParamNumber(g); + b = parseParamNumber(b); + return pack$1(function (pixels, i) { + pixels[i] *= r; + pixels[i + 1] *= g; + pixels[i + 2] *= b; }); +} - var pos = { next: 0 }; - result = result.map(function (item) { +function solarize(r, g, b) { + r = parseParamNumber(r); + g = parseParamNumber(g); + b = parseParamNumber(b); + return pack$1(function (pixels, i) { + if (pixels[i] < r) pixels[i] = 255 - pixels[i]; + if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; + if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; + }); +} - var startIndex = str.indexOf(item.origin, pos.next); +function thresholdColor() { + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; + var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + var hasColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - item.startIndex = startIndex; - item.endIndex = startIndex + item.origin.length; + scale = parseParamNumber(scale); + amount = parseParamNumber(amount); + var C = amount / 100; + return pack$1(function (pixels, i) { + var v = C * color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) >= scale ? 255 : 0; + + if (hasColor) { - item.arr = _this.parseFilter(item.origin); + if (v == 0) { + pixels[i] = pixels[i + 1] = pixels[i + 2] = 0; + } + } else { + pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v); + } + }); +} - pos.next = item.endIndex; +function threshold() { + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; + var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; - return item; - }).filter(function (it) { - if (!it.arr.length) return false; - return !!F[it.arr[0]]; - }); + return thresholdColor(scale, amount, false); +} - return result; +var pixel = { + bitonal: bitonal, + brightness: brightness, + clip: clip, + contrast: contrast, + gamma: gamma, + gradient: gradient, + grayscale: grayscale, + hue: hue, + invert: invert, + noise: noise, + opacity: opacity, + saturation: saturation, + sepia: sepia, + shade: shade, + solarize: solarize, + threshold: threshold, + 'threshold-color': thresholdColor }; -/** - * Filter Parser - * - * F.parseFilter('blur(30)') == ['blue', '30'] - * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] - * - * @param {String} filterString - */ -F.parseFilter = function (filterString) { - - var ret = color.convertMatches(filterString); - var matches = ret.str.match(filter_regexp); +function blur () { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; + amount = parseParamNumber(amount); - if (!matches[0]) { - return []; - } + return convolution(createBlurMatrix(amount)); +} - var arr = matches[0].split('('); +function emboss() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4; - var filterName = arr.shift(); - var filterParams = []; + amount = parseParamNumber(amount); + return convolution([amount * -2.0, -amount, 0.0, -amount, 1.0, amount, 0.0, amount, amount * 2.0]); +} - if (!F[filterName.toLowerCase()]) { - return []; - } +function gaussianBlur() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - if (arr.length) { - filterParams = arr.shift().split(')')[0].split(',').map(function (f) { - return color.reverseMatches(f, ret.matches); - }); - } + amount = parseParamNumber(amount); + var C = amount / 100; - var result = [filterName].concat(toConsumableArray(filterParams)).map(color.trim); + return convolution(weight([1, 2, 1, 2, 4, 2, 1, 2, 1], 1 / 16 * C)); +} - return result; -}; +function gaussianBlur5x() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.filter = function (str) { - return F.merge(F.matches(str).map(function (it) { - return it.arr; - })); -}; + amount = parseParamNumber(amount); + var C = amount / 100; + return convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, 36, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], 1 / 256 * C)); +} -/** - * - * multiply filters - * - * ImageFilter.multi('blur', 'grayscale', 'sharpen', ['blur', 3], function (bitmap) { return bitmap }); - * - */ -F.multi = function () { - for (var _len = arguments.length, filters = Array(_len), _key = 0; _key < _len; _key++) { - filters[_key] = arguments[_key]; - } +function grayscale2() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - filters = filters.map(function (f) { - return makeFilter(f); - }); + amount = parseParamNumber(amount); + return convolution(weight([0.3, 0.3, 0.3, 0, 0, 0.59, 0.59, 0.59, 0, 0, 0.11, 0.11, 0.11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); +} - return function (bitmap) { - return filters.reduce(function (bitmap, f) { - return f(bitmap); - }, bitmap); - }; -}; +function identity() { + return convolution([0, 0, 0, 0, 1, 0, 0, 0, 0]); +} -F.merge = function (filters) { - return F.multi.apply(F, toConsumableArray(filters)); -}; +function kirschHorizontal() { + var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; -/** - * apply filter into special area - * - * F.partial({x,y,width,height}, filter, filter, filter ) - * F.partial({x,y,width,height}, 'filter' ) - * - * @param {{x, y, width, height}} area - * @param {*} filters - */ -F.partial = function (area) { - var allFilter = null; + count = parseParamNumber(count); + return convolution([5, 5, 5, -3, 0, -3, -3, -3, -3]); +} - for (var _len2 = arguments.length, filters = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - filters[_key2 - 1] = arguments[_key2]; - } +function kirschVertical() { + var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - if (filters.length == 1 && typeof filters[0] === 'string') { - allFilter = F.filter(filters[0]); - } else { - allFilter = F.merge(filters); - } + count = parseParamNumber(count); + return convolution([5, -3, -3, 5, 0, -3, 5, -3, -3]); +} - return function (bitmap) { - return putBitmap(bitmap, allFilter(getBitmap(bitmap, area)), area); - }; -}; +function laplacian() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.counter = function (filter) { - var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + amount = parseParamNumber(amount); + return convolution(weight([-1, -1, -1, -1, 8, -1, -1, -1, -1], amount / 100)); +} - var filters = []; +function laplacian5x() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - for (var i = 0; i < count; i++) { - filters.push(filter); - } + amount = parseParamNumber(amount); + return convolution(weight([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], amount / 100)); +} - return F.multi.apply(F, filters); -}; +function motionBlur() { + return convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); +} -// Image manupulate -F.resize = function (dstWidth, dstHeight) { - return function (bitmap) { +function motionBlur2() { + return convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); +} - var c = Canvas.drawPixels(bitmap); - var context = c.getContext('2d'); +function motionBlur3() { + return convolution(weight([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], 1 / 9)); +} - c.width = dstWidth; - c.height = dstHeight; +function negative() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - return { - pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), - width: dstWidth, - height: dstHeight - }; - }; -}; + amount = parseParamNumber(amount); + return convolution(weight([-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1], amount / 100)); +} -F.crop = function () { - var startX = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var startY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var width = arguments[2]; - var height = arguments[3]; +function random() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; + var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createRandomCount(); + amount = parseParamNumber(amount); + return function (pixels, width, height) { + var rand = createRandRange(-1, 5, count); + return convolution(rand)(pixels, width, height); + }; +} - var newBitmap = createBitmap(width * height * 4, width, height); +function sepia2() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - return function (bitmap) { - for (var y = startY, realY = 0; y < height; y++, realY++) { - for (var x = startX, realX = 0; x < width; x++, realX++) { - newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x]; - } - } + amount = parseParamNumber(amount); + return convolution(weight([0.393, 0.349, 0.272, 0, 0, 0.769, 0.686, 0.534, 0, 0, 0.189, 0.168, 0.131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); +} - return newBitmap; - }; -}; +function sharpen() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.flipH = function flipH() { - return function (bitmap) { + amount = parseParamNumber(amount); + return convolution(weight([0, -1, 0, -1, 5, -1, 0, -1, 0], amount / 100)); +} - var width = bitmap.width; - var height = bitmap.height; - var isCenter = width % 2 == 1 ? 1 : 0; +function sobelHorizontal() { + return convolution([-1, -2, -1, 0, 0, 0, 1, 2, 1]); +} - var halfWidth = isCenter ? Math.floor(width / 2) : width / 2; +function sobelVertical() { + return convolution([-1, 0, 1, -2, 0, 2, -1, 0, 1]); +} - for (var y = 0; y < height; y++) { - for (var x = 0; x < halfWidth; x++) { +/* - var startIndex = (y * width + x) * 4; - var endIndex = (y * width + (width - 1 - x)) * 4; - swapColor(bitmap.pixels, startIndex, endIndex); - } - } +StackBlur - a fast almost Gaussian Blur For Canvas - return bitmap; - }; -}; +Version: 0.5 +Author: Mario Klingemann +Contact: mario@quasimondo.com +Website: http://www.quasimondo.com/StackBlurForCanvas +Twitter: @quasimondo -F.flipV = function flipV() { - return function (bitmap) { +In case you find this class useful - especially in commercial projects - +I am not totally unhappy for a small donation to my PayPal account +mario@quasimondo.de - var width = bitmap.width; - var height = bitmap.height; - var isCenter = height % 2 == 1 ? 1 : 0; +Or support me on flattr: +https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript - var halfHeight = isCenter ? Math.floor(height / 2) : height / 2; +Copyright (c) 2010 Mario Klingemann - for (var y = 0; y < halfHeight; y++) { - for (var x = 0; x < width; x++) { +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: - var startIndex = (y * width + x) * 4; - var endIndex = ((height - 1 - y) * width + x) * 4; - swapColor(bitmap.pixels, startIndex, endIndex); - } - } +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. - return bitmap; - }; -}; +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +*/ -F.radian = function (degree) { - return Matrix.CONSTANT.radian(degree); -}; +var mul_table = [512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; -F['rotate-degree'] = F.rotateDegree = function (angle) { - var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'center'; - var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'center'; +var shg_table = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; - // const r = F.radian(angle) +function BlurStack() { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 0; + this.next = null; +} - return function (bitmap) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); - var width = bitmap.width; - var height = bitmap.height; +function stackBlurImage(bitmap, radius, blurAlphaChannel) { - if (cx == 'center') { - cx = Math.floor(width / 2); - } + if (blurAlphaChannel) return stackBlurCanvasRGBA(bitmap, 0, 0, radius);else return stackBlurCanvasRGB(bitmap, 0, 0, radius); +} - if (cy == 'center') { - cy = Math.floor(height / 2); - } +function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { + if (isNaN(radius) || radius < 1) return bitmap; + radius |= 0; - var translateMatrix = Matrix.CONSTANT.translate(-cx, -cy); - var translateMatrix2 = Matrix.CONSTANT.translate(cx, cy); - var shear1Matrix = Matrix.CONSTANT.shear1(angle); - var shear2Matrix = Matrix.CONSTANT.shear2(angle); + var pixels = bitmap.pixels, + width = bitmap.width, + height = bitmap.height; - return packXY(function (pixels, i, x, y) { - // console.log(x, y, i) - var arr = Matrix.multiply(translateMatrix, [x, y, 1]); + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, r_out_sum, g_out_sum, b_out_sum, a_out_sum, r_in_sum, g_in_sum, b_in_sum, a_in_sum, pr, pg, pb, pa, rbs; - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); - arr = Matrix.multiply(shear2Matrix, arr).map(Math.round); - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); - arr = Matrix.multiply(translateMatrix2, arr); + var div = radius + radius + 1; + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; - var _arr = arr, - _arr2 = slicedToArray(_arr, 2), - x1 = _arr2[0], - y1 = _arr2[1]; + var stackStart = new BlurStack(); + var stack = stackStart; + for (i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + if (i == radiusPlus1) var stackEnd = stack; + } + stack.next = stackStart; + var stackIn = null; + var stackOut = null; - if (x1 < 0) return; - if (y1 < 0) return; - if (x1 > width - 1) return; - if (y1 > height - 1) return; + yw = yi = 0; - var endIndex = (y1 * width + x1) * 4; + var mul_sum = mul_table[radius]; + var shg_sum = shg_table[radius]; - pixels[endIndex] = bitmap.pixels[i]; - pixels[endIndex + 1] = bitmap.pixels[i + 1]; - pixels[endIndex + 2] = bitmap.pixels[i + 2]; - pixels[endIndex + 3] = bitmap.pixels[i + 3]; - })(newBitmap); - }; -}; + for (y = 0; y < height; y++) { + r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; -F.rotate = function rotate() { - var degree = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - degree = parseParamNumber(degree); - degree = degree % 360; - return function (bitmap) { + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; - if (degree == 0) return bitmap; + stack = stackStart; - if (degree == 90 || degree == 270) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width); - } else if (degree == 180) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); - } else { - return F.rotateDegree(degree)(bitmap); + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; } - var width = bitmap.width; - var height = bitmap.height; + for (i = 1; i < radiusPlus1; i++) { + p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); + r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[p + 1]) * rbs; + b_sum += (stack.b = pb = pixels[p + 2]) * rbs; + a_sum += (stack.a = pa = pixels[p + 3]) * rbs; - packXY(function (pixels, i, x, y) { + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; - if (degree == 90) { - var endIndex = (x * newBitmap.width + (newBitmap.width - 1 - y)) * 4; - } else if (degree == 270) { - var endIndex = ((newBitmap.height - 1 - x) * newBitmap.width + y) * 4; - } else if (degree == 180) { - var endIndex = ((newBitmap.height - 1 - y) * newBitmap.width + (newBitmap.width - 1 - x)) * 4; + stack = stack.next; + } + + stackIn = stackStart; + stackOut = stackEnd; + for (x = 0; x < width; x++) { + pixels[yi + 3] = pa = a_sum * mul_sum >> shg_sum; + if (pa != 0) { + pa = 255 / pa; + pixels[yi] = (r_sum * mul_sum >> shg_sum) * pa; + pixels[yi + 1] = (g_sum * mul_sum >> shg_sum) * pa; + pixels[yi + 2] = (b_sum * mul_sum >> shg_sum) * pa; + } else { + pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; } - // console.log(startIndex, endIndex) + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; + + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; - newBitmap.pixels[endIndex] = bitmap.pixels[i]; - newBitmap.pixels[endIndex + 1] = bitmap.pixels[i + 1]; - newBitmap.pixels[endIndex + 2] = bitmap.pixels[i + 2]; - newBitmap.pixels[endIndex + 3] = bitmap.pixels[i + 3]; - })(bitmap); + p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; - return newBitmap; - }; -}; + r_in_sum += stackIn.r = pixels[p]; + g_in_sum += stackIn.g = pixels[p + 1]; + b_in_sum += stackIn.b = pixels[p + 2]; + a_in_sum += stackIn.a = pixels[p + 3]; -// Pixel based + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; + a_sum += a_in_sum; + stackIn = stackIn.next; -F.grayscale = function (amount) { - amount = parseParamNumber(amount); - var C = amount / 100; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; + a_out_sum += pa = stackOut.a; - if (C > 1) C = 1; + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; - return pack$1(function (pixels, i) { + stackOut = stackOut.next; - colorMatrix(pixels, i, [0.2126 + 0.7874 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 + 0.2848 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 + 0.9278 * (1 - C), 0, 0, 0, 0, 1]); - }); -}; + yi += 4; + } + yw += width; + } -/* - * @param {Number} amount 0..360 - */ -F.hue = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 360; + for (x = 0; x < width; x++) { + g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - var r = pixels[i], - g = pixels[i + 1], - b = pixels[i + 2]; + yi = x << 2; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - var hsv = color.RGBtoHSV(r, g, b); + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; - // 0 ~ 360 - var h = hsv.h; - h += Math.abs(amount); - h = h % 360; - hsv.h = h; + stack = stackStart; - var rgb = color.HSVtoRGB(hsv); + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } - pixels[i] = rgb.r; - pixels[i + 1] = rgb.g; - pixels[i + 2] = rgb.b; - }); -}; + yp = width; -F.shade = function () { - var r = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var g = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - var b = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + for (i = 1; i <= radius; i++) { + yi = yp + x << 2; - r = parseParamNumber(r); - g = parseParamNumber(g); - b = parseParamNumber(b); - return pack$1(function (pixels, i) { - pixels[i] *= r; - pixels[i + 1] *= g; - pixels[i + 2] *= b; - }); -}; + r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; + b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; + a_sum += (stack.a = pa = pixels[yi + 3]) * rbs; -F.bitonal = function (darkColor, lightColor) { - var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100; + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; - darkColor = color.parse(darkColor); - lightColor = color.parse(lightColor); - return pack$1(function (pixels, i) { + stack = stack.next; - if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { - pixels[i] = darkColor.r; - pixels[i + 1] = darkColor.g; - pixels[i + 2] = darkColor.b; - } else { - pixels[i] = lightColor.r; - pixels[i + 1] = lightColor.g; - pixels[i + 2] = lightColor.b; + if (i < heightMinus1) { + yp += width; + } } - }); -}; -/** - * F.gradient('red', 'blue', 'yellow', 'white', 10) - * F.gradient('red, blue, yellow, white, 10') - */ -F.duotone = function () { - // 전체 매개변수 기준으로 파싱 - // 색이 아닌 것 기준으로 scale 변수로 인식 + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for (y = 0; y < height; y++) { + p = yi << 2; + pixels[p + 3] = pa = a_sum * mul_sum >> shg_sum; + if (pa > 0) { + pa = 255 / pa; + pixels[p] = (r_sum * mul_sum >> shg_sum) * pa; + pixels[p + 1] = (g_sum * mul_sum >> shg_sum) * pa; + pixels[p + 2] = (b_sum * mul_sum >> shg_sum) * pa; + } else { + pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; + } - var params = [].concat(Array.prototype.slice.call(arguments)); + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; - if (params.length === 1 && typeof params[0] === 'string') { - params = color.convertMatchesArray(params[0]); - } + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; - params = params.map(function (arg) { - var res = color.matches(arg); + p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; - if (!res.length) { - return { type: 'scale', value: arg }; - } + r_sum += r_in_sum += stackIn.r = pixels[p]; + g_sum += g_in_sum += stackIn.g = pixels[p + 1]; + b_sum += b_in_sum += stackIn.b = pixels[p + 2]; + a_sum += a_in_sum += stackIn.a = pixels[p + 3]; - return { type: 'param', value: arg }; - }); + stackIn = stackIn.next; - var scale = params.filter(function (it) { - return it.type == 'scale'; - })[0]; - scale = scale ? +scale.value : 256; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; + a_out_sum += pa = stackOut.a; - params = params.filter(function (it) { - return it.type == 'param'; - }).map(function (it) { - return it.value; - }).join(','); + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; - var colors = color.gradient(params, scale).map(function (c) { - return color.parse(c); - }); + stackOut = stackOut.next; - return pack$1(function (pixels, i) { - var colorIndex = F.clamp(color.brightness(pixels[i], pixels[i + 1], pixels[i + 2])); - var newColorIndex = F.clamp(Math.floor(colorIndex * (scale / 256))); - var color$$1 = colors[newColorIndex]; + yi += width; + } + } - pixels[i] = color$$1.r; - pixels[i + 1] = color$$1.g; - pixels[i + 2] = color$$1.b; - pixels[i + 3] = F.clamp(Math.floor(color$$1.a * 256)); - }); -}; + return bitmap; +} -F.gradient = F.duotone; +function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { + if (isNaN(radius) || radius < 1) return bitmap; + radius |= 0; -F.tint = function () { - var redTint = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var greenTint = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - var blueTint = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var pixels = bitmap.pixels, + width = bitmap.width, + height = bitmap.height; - redTint = parseParamNumber(redTint); - greenTint = parseParamNumber(greenTint); - blueTint = parseParamNumber(blueTint); - return pack$1(function (pixels, i) { - pixels[i] += (255 - pixels[i]) * redTint; - pixels[i + 1] += (255 - pixels[i + 1]) * greenTint; - pixels[i + 2] += (255 - pixels[i + 2]) * blueTint; - }); -}; + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, r_out_sum, g_out_sum, b_out_sum, r_in_sum, g_in_sum, b_in_sum, pr, pg, pb, rbs; -F.clamp = function (num) { - return Math.min(255, num); -}; -/** - * - * @param {*} amount min = -128, max = 128 - */ -F.contrast = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var div = radius + radius + 1; + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; - amount = parseParamNumber(amount); - var C = Math.max((128 + amount) / 128, 0); + var stackStart = new BlurStack(); + var stack = stackStart; + for (i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + if (i == radiusPlus1) var stackEnd = stack; + } + stack.next = stackStart; + var stackIn = null; + var stackOut = null; - return pack$1(function (pixels, i) { - pixels[i] = pixels[i] * C; - pixels[i + 1] = pixels[i + 1] * C; - pixels[i + 2] = pixels[i + 2] * C; - }); -}; + yw = yi = 0; -F.invert = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + var mul_sum = mul_table[radius]; + var shg_sum = shg_table[radius]; - amount = parseParamNumber(amount); - var C = amount / 100; + for (y = 0; y < height; y++) { + r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0; - return pack$1(function (pixels, i) { + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - pixels[i] = (255 - pixels[i]) * C; - pixels[i + 1] = (255 - pixels[i + 1]) * C; - pixels[i + 2] = (255 - pixels[i + 2]) * C; - }); -}; + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; -F.opacity = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + stack = stackStart; - amount = parseParamNumber(amount); - var C = amount / 100; + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack = stack.next; + } - return pack$1(function (pixels, i) { - pixels[i + 3] *= C; - }); -}; + for (i = 1; i < radiusPlus1; i++) { + p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); + r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[p + 1]) * rbs; + b_sum += (stack.b = pb = pixels[p + 2]) * rbs; -/** - * change the relative darkness of (a part of an image) by overexposure to light. - * @param {*} r - * @param {*} g - * @param {*} b - */ -F.solarize = function (r, g, b) { - r = parseParamNumber(r); - g = parseParamNumber(g); - b = parseParamNumber(b); - return pack$1(function (pixels, i) { - if (pixels[i] < r) pixels[i] = 255 - pixels[i]; - if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; - if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; - }); -}; + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; -/* - * @param {Number} amount 0..100 - */ -F.sepia = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + stack = stack.next; + } - amount = parseParamNumber(amount); - var C = amount / 100; - if (C > 1) C = 1; + stackIn = stackStart; + stackOut = stackEnd; + for (x = 0; x < width; x++) { + pixels[yi] = r_sum * mul_sum >> shg_sum; + pixels[yi + 1] = g_sum * mul_sum >> shg_sum; + pixels[yi + 2] = b_sum * mul_sum >> shg_sum; - return pack$1(function (pixels, i) { + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; - colorMatrix(pixels, i, [0.393 + 0.607 * (1 - C), 0.769 - 0.769 * (1 - C), 0.189 - 0.189 * (1 - C), 0, 0.349 - 0.349 * (1 - C), 0.686 + 0.314 * (1 - C), 0.168 - 0.168 * (1 - C), 0, 0.272 - 0.272 * (1 - C), 0.534 - 0.534 * (1 - C), 0.131 + 0.869 * (1 - C), 0, 0, 0, 0, 1]); - }); -}; + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; -F.gamma = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - pixels[i] = Math.pow(pixels[i] / 255, amount) * 255; - pixels[i + 1] = Math.pow(pixels[i + 1] / 255, amount) * 255; - pixels[i + 2] = Math.pow(pixels[i + 2] / 255, amount) * 255; - }); -}; + r_in_sum += stackIn.r = pixels[p]; + g_in_sum += stackIn.g = pixels[p + 1]; + b_in_sum += stackIn.b = pixels[p + 2]; -/** - * - * @param {Number} amount 1..100 - */ -F.noise = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - var C = Math.abs(amount) * 5; - var min = -C; - var max = C; - var noiseValue = Math.round(min + Math.random() * (max - min)); - pixels[i] += noiseValue; - pixels[i + 1] += noiseValue; - pixels[i + 2] += noiseValue; - }); -}; + stackIn = stackIn.next; -/** - * - * @param {Number} amount from 0 to 100 - */ -F.clip = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; - amount = parseParamNumber(amount); - var C = Math.abs(amount) * 2.55; + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; - return pack$1(function (pixels, i) { + stackOut = stackOut.next; - for (var start = i, end = i + 2; start <= end; start++) { - if (pixels[start] > 255 - C) { - pixels[start] = 255; - } else if (pixels[start] < C) { - pixels[start] = 0; - } + yi += 4; } - }); -}; - -/* - * @param {Number} amount -100..100 , value < 0 is darken, value > 0 is brighten - */ -F.brightness = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + yw += width; + } - amount = parseParamNumber(amount); - var C = Math.floor(255 * (amount / 100)); + for (x = 0; x < width; x++) { + g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0; - return pack$1(function (pixels, i) { - pixels[i] += C; - pixels[i + 1] += C; - pixels[i + 2] += C; - }); -}; + yi = x << 2; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); -/* - * @param {Number} amount -100..100 - */ -F.saturation = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; - amount = parseParamNumber(amount); - var C = amount / 100; - var L = 1 - Math.abs(C); - return pack$1(function (pixels, i) { + stack = stackStart; - colorMatrix(pixels, i, [L, 0, 0, 0, 0, L, 0, 0, 0, 0, L, 0, 0, 0, 0, L]); - }); -}; + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack = stack.next; + } -/* - * @param {Number} amount 0..100 - */ -F.threshold = function () { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; - var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + yp = width; - return F.thresholdColor(scale, amount, false); -}; + for (i = 1; i <= radius; i++) { + yi = yp + x << 2; -F['threshold-color'] = F.thresholdColor = function () { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; - var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; - var hasColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; + b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; - scale = parseParamNumber(scale); - amount = parseParamNumber(amount); - var C = amount / 100; - return pack$1(function (pixels, i) { - var v = C * color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) >= scale ? 255 : 0; + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; - if (hasColor) { + stack = stack.next; - if (v == 0) { - pixels[i] = pixels[i + 1] = pixels[i + 2] = 0; + if (i < heightMinus1) { + yp += width; } - } else { - pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v); } - }); -}; -// Matrix based + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for (y = 0; y < height; y++) { + p = yi << 2; + pixels[p] = r_sum * mul_sum >> shg_sum; + pixels[p + 1] = g_sum * mul_sum >> shg_sum; + pixels[p + 2] = b_sum * mul_sum >> shg_sum; -F.convolution = function (weights) { - var opaque = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; - return function (_ref) { - var pixels = _ref.pixels, - width = _ref.width, - height = _ref.height; + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; - var side = Math.round(Math.sqrt(weights.length)); - var halfSide = Math.floor(side / 2); + p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; - var w = width; - var h = height; - var sw = w; - var sh = h; - var dst = new Uint8ClampedArray(pixels.length); - var alphaFac = opaque ? 1 : 0; + r_sum += r_in_sum += stackIn.r = pixels[p]; + g_sum += g_in_sum += stackIn.g = pixels[p + 1]; + b_sum += b_in_sum += stackIn.b = pixels[p + 2]; - for (var y = 0; y < h; y++) { - for (var x = 0; x < w; x++) { - var sy = y; - var sx = x; - var dstIndex = (y * w + x) * 4; + stackIn = stackIn.next; - var r = 0, - g = 0, - b = 0, - a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; - var scy = sy + cy - halfSide; - var scx = sx + cx - halfSide; + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; - if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { - var srcIndex = (scy * sw + scx) * 4; - var wt = weights[cy * side + cx]; - r += pixels[srcIndex] * wt; - g += pixels[srcIndex + 1] * wt; - b += pixels[srcIndex + 2] * wt; - a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. - } - } - } + stackOut = stackOut.next; - dst[dstIndex] = r; - dst[dstIndex + 1] = g; - dst[dstIndex + 2] = b; - dst[dstIndex + 3] = a + alphaFac * (255 - a); - } + yi += width; } + } - return { pixels: dst, width: sw, height: sh }; - }; -}; + return bitmap; +} -F.identity = function () { - return F.convolution([0, 0, 0, 0, 1, 0, 0, 0, 0]); -}; +function stackBlur () { + var radius = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; + var hasAlphaChannel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; -F.random = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; - var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createRandomCount(); + radius = parseParamNumber(radius); - amount = parseParamNumber(amount); - return function (pixels, width, height) { - var rand = createRandRange(-1, 5, count); - return F.convolution(rand)(pixels, width, height); + return function (bitmap) { + return stackBlurImage(bitmap, radius, hasAlphaChannel); }; -}; +} -F.grayscale2 = function () { +function transparency() { var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; amount = parseParamNumber(amount); - return F.convolution(weight([0.3, 0.3, 0.3, 0, 0, 0.59, 0.59, 0.59, 0, 0, 0.11, 0.11, 0.11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); -}; + return convolution(weight([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 1], amount / 100)); +} -F.sepia2 = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +function unsharpMasking() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 256; amount = parseParamNumber(amount); - return F.convolution(weight([0.393, 0.349, 0.272, 0, 0, 0.769, 0.686, 0.534, 0, 0, 0.189, 0.168, 0.131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); -}; - -F.negative = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + return convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, -476, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], -1 / amount)); +} - amount = parseParamNumber(amount); - return F.convolution(weight([-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1], amount / 100)); +var matrix = { + blur: blur, + emboss: emboss, + gaussianBlur: gaussianBlur, + 'gaussian-blur': gaussianBlur, + gaussianBlur5x: gaussianBlur5x, + 'gaussian-blur-5x': gaussianBlur5x, + grayscale2: grayscale2, + identity: identity, + kirschHorizontal: kirschHorizontal, + 'kirsch-horizontal': kirschHorizontal, + kirschVertical: kirschVertical, + 'kirsch-vertical': kirschVertical, + laplacian: laplacian, + laplacian5x: laplacian5x, + 'laplacian-5x': laplacian5x, + motionBlur: motionBlur, + 'motion-blur': motionBlur, + motionBlur2: motionBlur2, + 'motion-blur-2': motionBlur2, + motionBlur3: motionBlur3, + 'motion-blur-3': motionBlur3, + negative: negative, + random: random, + sepia2: sepia2, + sharpen: sharpen, + sobelHorizontal: sobelHorizontal, + 'sobel-horizontal': sobelHorizontal, + sobelVertical: sobelVertical, + 'sobel-vertical': sobelVertical, + stackBlur: stackBlur, + 'stack-blur': stackBlur, + transparency: transparency, + unsharpMasking: unsharpMasking, + 'unsharp-masking': unsharpMasking }; -F.sharpen = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - return F.convolution(weight([0, -1, 0, -1, 5, -1, 0, -1, 0], amount / 100)); -}; +var ImageFilter$1 = _extends({}, image, pixel, matrix); -F['motion-blur'] = F.motionBlur = function () { - return F.convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); -}; +// TODO: worker run +Object.assign(ImageFilter$1, { + pack: pack$1, + packXY: packXY, + swapColor: swapColor +}); -F['motion-blur-2'] = F.motionBlur2 = function () { - return F.convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); -}; +var F = ImageFilter$1; -F['motion-blur-3'] = F.motionBlur3 = function () { - return F.convolution(weight([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], 1 / 9)); +F.filter = function (str) { + return F.merge(matches(str).map(function (it) { + return it.arr; + })); }; -function createBlurMatrix() { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - - var count = Math.pow(amount, 2); - var value = 1 / count; - return repeat(value, count); -} - -/** +/** + * + * multiply filters + * + * ImageFilter.multi('blur', 'grayscale', 'sharpen', ['blur', 3], function (bitmap) { return bitmap }); * - * @param {Number} amount from 3 to 100 */ -F.blur = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - amount = parseParamNumber(amount); - - return F.convolution(createBlurMatrix(amount)); -}; - -F['stack-blur'] = F.stackBlur = function () { - var radius = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; - var hasAlphaChannel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; +F.multi = function () { + for (var _len = arguments.length, filters = Array(_len), _key = 0; _key < _len; _key++) { + filters[_key] = arguments[_key]; + } - radius = parseParamNumber(radius); + filters = filters.map(function (filter) { + return makeFilter(filter, F); + }); return function (bitmap) { - return stackBlurImage(bitmap, radius, hasAlphaChannel); + return filters.reduce(function (bitmap, f) { + return f(bitmap); + }, bitmap); }; }; -F['gaussian-blur'] = F.gaussianBlur = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - var C = amount / 100; - - return F.convolution(weight([1, 2, 1, 2, 4, 2, 1, 2, 1], 1 / 16 * C)); +F.merge = function (filters) { + return F.multi.apply(F, toConsumableArray(filters)); }; -F['gaussian-blur-5x'] = F.gaussianBlur5x = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +/** + * apply filter into special area + * + * F.partial({x,y,width,height}, filter, filter, filter ) + * F.partial({x,y,width,height}, 'filter' ) + * + * @param {{x, y, width, height}} area + * @param {*} filters + */ +F.partial = function (area) { + var allFilter = null; - amount = parseParamNumber(amount); - var C = amount / 100; - return F.convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, 36, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], 1 / 256 * C)); -}; + for (var _len2 = arguments.length, filters = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + filters[_key2 - 1] = arguments[_key2]; + } -F['unsharp-masking'] = F.unsharpMasking = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 256; + if (filters.length == 1 && typeof filters[0] === 'string') { + allFilter = F.filter(filters[0]); + } else { + allFilter = F.merge(filters); + } - amount = parseParamNumber(amount); - return F.convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, -476, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], -1 / amount)); + return function (bitmap) { + return putBitmap(bitmap, allFilter(getBitmap(bitmap, area)), area); + }; }; -F.transparency = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +F.counter = function (filter) { + var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - amount = parseParamNumber(amount); - return F.convolution(weight([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 1], amount / 100)); -}; + var filters = []; -F.laplacian = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + for (var i = 0; i < count; i++) { + filters.push(filter); + } - amount = parseParamNumber(amount); - return F.convolution(weight([-1, -1, -1, -1, 8, -1, -1, -1, -1], amount / 100)); + return F.multi.apply(F, filters); }; +/** + * multi filter + */ + F.laplacian.grayscale = function () { var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; return F.filter('grayscale laplacian(' + amount); }; -F.laplacian5x = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - return F.convolution(weight([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], amount / 100)); -}; - F.laplacian5x.grayscale = function () { return F.filter('grayscale laplacian5x'); }; -F['kirsch-horizontal'] = F.kirschHorizontal = function () { - var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - - count = parseParamNumber(count); - return F.convolution([5, 5, 5, -3, 0, -3, -3, -3, -3]); -}; - -F['kirsch-vertical'] = F.kirschVertical = function () { - var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - - count = parseParamNumber(count); - return F.convolution([5, -3, -3, 5, 0, -3, 5, -3, -3]); -}; - F.kirsch = function () { return F.filter('kirsch-horizontal kirsch-vertical'); }; @@ -3371,14 +3405,6 @@ F.kirsch.grayscale = function () { return F.filter('grayscale kirsch'); }; -F['sobel-horizontal'] = F.sobelHorizontal = function () { - return F.convolution([-1, -2, -1, 0, 0, 0, 1, 2, 1]); -}; - -F['sobel-vertical'] = F.sobelVertical = function () { - return F.convolution([-1, 0, 1, -2, 0, 2, -1, 0, 1]); -}; - F.sobel = function () { return F.filter('sobel-horizontal sobel-vertical'); }; @@ -3387,22 +3413,6 @@ F.sobel.grayscale = function () { return F.filter('grayscale sobel'); }; -/* - * carve, mold, or stamp a design on (a surface) so that it stands out in relief. - * - * @param {Number} amount 0.0 .. 4.0 - */ -F.emboss = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4; - - amount = parseParamNumber(amount); - return F.convolution([amount * -2.0, -amount, 0.0, -amount, 1.0, amount, 0.0, amount, amount * 2.0]); -}; - -/** - * multi filter - */ - F.vintage = function () { return F.filter('brightness(15) saturation(-20) gamma(1.8)'); }; @@ -6183,7 +6193,7 @@ var index = { Color: color, ColorNames: ColorNames, ColorPicker: ColorPicker, - ImageFilter: ImageFilter, + ImageFilter: ImageFilter$1, HueColor: HueColor, Canvas: Canvas, ImageLoader: ImageLoader diff --git a/dist/codemirror-colorpicker.js b/dist/codemirror-colorpicker.js index 5c93423..b4ca738 100644 --- a/dist/codemirror-colorpicker.js +++ b/dist/codemirror-colorpicker.js @@ -443,6 +443,20 @@ var defineProperty = function (obj, key, value) { return obj; }; +var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; + var get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); @@ -1772,1599 +1786,1662 @@ var HueColor = { checkHueColor: checkHueColor }; -/* +var CONSTANT = { + identity: function identity() { + return [1, 0, 0, 0, 1, 0, 0, 0, 1]; + }, + stretching: function stretching(k) { + return [k, 0, 0, 0, 1, 0, 0, 0, 1]; + }, + squeezing: function squeezing(k) { + return [k, 0, 0, 0, 1 / k, 0, 0, 0, 1]; + }, + scale: function scale() { + var sx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var sy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; -StackBlur - a fast almost Gaussian Blur For Canvas + sx = sx || sx === 0 ? sx : 1; + sy = sy || sy === 0 ? sy : 1; + return [sx, 0, 0, 0, sy, 0, 0, 0, 1]; + }, + scaleX: function scaleX(sx) { + return this.scale(sx); + }, + scaleY: function scaleY(sy) { + return this.scale(1, sy); + }, + translate: function translate(tx, ty) { + return [1, 0, tx, 0, 1, ty, 0, 0, 1]; + }, + rotate: function rotate(angle) { + var r = this.radian(angle); + return [Math.cos(r), -Math.sin(r), 0, Math.sin(r), Math.cos(r), 0, 0, 0, 1]; + }, + rotate90: function rotate90() { + return [0, -1, 0, 1, 0, 0, 0, 0, 1]; + }, + rotate180: function rotate180() { + return [-1, 0, 0, 0, -1, 0, 0, 0, 1]; + }, + rotate270: function rotate270() { + return [0, 1, 0, -1, 0, 0, 0, 0, 1]; + }, + radian: function radian(degree) { + return degree * Math.PI / 180; + }, + skew: function skew(degreeX, degreeY) { + var radianX = this.radian(degreeX); + var radianY = this.radian(degreeY); + return [1, Math.tan(radianX), 0, Math.tan(radianY), 1, 0, 0, 0, 1]; + }, + skewX: function skewX(degreeX) { + var radianX = this.radian(degreeX); -Version: 0.5 -Author: Mario Klingemann -Contact: mario@quasimondo.com -Website: http://www.quasimondo.com/StackBlurForCanvas -Twitter: @quasimondo + return [1, Math.tan(radianX), 0, 0, 1, 0, 0, 0, 1]; + }, + skewY: function skewY(degreeY) { + var radianY = this.radian(degreeY); -In case you find this class useful - especially in commercial projects - -I am not totally unhappy for a small donation to my PayPal account -mario@quasimondo.de + return [1, 0, 0, Math.tan(radianY), 1, 0, 0, 0, 1]; + }, + shear1: function shear1(angle) { + return [1, -Math.tan(this.radian(angle) / 2), 0, 0, 1, 0, 0, 0, 1]; + }, + shear2: function shear2(angle) { + return [1, 0, 0, Math.sin(this.radian(angle)), 1, 0, 0, 0, 1]; + } +}; -Or support me on flattr: -https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript +var Matrix = { + CONSTANT: CONSTANT, -Copyright (c) 2010 Mario Klingemann + radian: function radian(angle) { + return CONSTANT.radian(angle); + }, + multiply: function multiply(A, C) { + // console.log(JSON.stringify(A), JSON.stringify(C)) + return [A[0] * C[0] + A[1] * C[1] + A[2] * C[2], A[3] * C[0] + A[4] * C[1] + A[5] * C[2], A[6] * C[0] + A[7] * C[1] + A[8] * C[2]]; + }, + identity: function identity(B) { + return this.multiply(CONSTANT.identity(), B); + }, + translate: function translate(x, y, B) { + return this.multiply(CONSTANT.translate(x, y), B); + }, + rotate: function rotate(angle, B) { + return this.multiply(CONSTANT.rotate(angle), B); + }, + shear1: function shear1(angle, B) { + return this.multiply(CONSTANT.shear1(angle), B); + }, + shear2: function shear2(angle, B) { + return this.multiply(CONSTANT.shear2(angle), B); + }, + rotateShear: function rotateShear(angle, B) { -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: + var arr = B; -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. + arr = this.shear1(angle, arr); + arr = this.shear2(angle, arr); + arr = this.shear1(angle, arr); -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ + return arr; + } +}; -var mul_table = [512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; +function weight(arr) { + var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; -var shg_table = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; + return arr.map(function (i) { + return i * num; + }); +} -function BlurStack() { - this.r = 0; - this.g = 0; - this.b = 0; - this.a = 0; - this.next = null; +function repeat(value, num) { + var arr = new Array(num); + for (var i = 0; i < num; i++) { + arr[i] = value; + } + return arr; } -function stackBlurImage(bitmap, radius, blurAlphaChannel) { +function colorMatrix(pixels, i, matrix) { + var r = pixels[i], + g = pixels[i + 1], + b = pixels[i + 2], + a = pixels[i + 3]; - if (blurAlphaChannel) return stackBlurCanvasRGBA(bitmap, 0, 0, radius);else return stackBlurCanvasRGB(bitmap, 0, 0, radius); + pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; + pixels[i + 1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; + pixels[i + 2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; + pixels[i + 3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; } -function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { - if (isNaN(radius) || radius < 1) return bitmap; - radius |= 0; +function makeFilter(filter, F) { - var pixels = bitmap.pixels, - width = bitmap.width, - height = bitmap.height; + if (typeof filter == 'function') { + return filter; + } - var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, r_out_sum, g_out_sum, b_out_sum, a_out_sum, r_in_sum, g_in_sum, b_in_sum, a_in_sum, pr, pg, pb, pa, rbs; + if (typeof filter == 'string') { + filter = [filter]; + } - var div = radius + radius + 1; - var widthMinus1 = width - 1; - var heightMinus1 = height - 1; - var radiusPlus1 = radius + 1; - var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var filterName = filter.shift(); - var stackStart = new BlurStack(); - var stack = stackStart; - for (i = 1; i < div; i++) { - stack = stack.next = new BlurStack(); - if (i == radiusPlus1) var stackEnd = stack; + if (typeof filterName == 'function') { + return filterName; } - stack.next = stackStart; - var stackIn = null; - var stackOut = null; - - yw = yi = 0; - var mul_sum = mul_table[radius]; - var shg_sum = shg_table[radius]; + var params = filter; - for (y = 0; y < height; y++) { - r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; + var filterFunction = F[filterName]; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); + if (!filterFunction) { + throw new Error(filterName + ' is not filter. please check filter name.'); + } + return filterFunction.apply(filterFunction, params); +} - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - a_sum += sumFactor * pa; +function each$1(len, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex); + } +} - stack = stackStart; +function eachXY(len, width, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex % width, Math.floor(xyIndex / width)); + } +} - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack.a = pa; - stack = stack.next; - } +function createRandRange(min, max, count) { + var result = []; - for (i = 1; i < radiusPlus1; i++) { - p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); - r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[p + 1]) * rbs; - b_sum += (stack.b = pb = pixels[p + 2]) * rbs; - a_sum += (stack.a = pa = pixels[p + 3]) * rbs; + for (var i = 1; i <= count; i++) { + var num = Math.random() * (max - min) + min; + var sign = Math.floor(Math.random() * 10) % 2 == 0 ? -1 : 1; + result.push(sign * num); + } - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; - a_in_sum += pa; + result.sort(); - stack = stack.next; - } + var centerIndex = Math.floor(count / 2); + var a = result[centerIndex]; + result[centerIndex] = result[0]; + result[0] = a; - stackIn = stackStart; - stackOut = stackEnd; - for (x = 0; x < width; x++) { - pixels[yi + 3] = pa = a_sum * mul_sum >> shg_sum; - if (pa != 0) { - pa = 255 / pa; - pixels[yi] = (r_sum * mul_sum >> shg_sum) * pa; - pixels[yi + 1] = (g_sum * mul_sum >> shg_sum) * pa; - pixels[yi + 2] = (b_sum * mul_sum >> shg_sum) * pa; - } else { - pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; - } + return result; +} - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; - a_sum -= a_out_sum; +function createRandomCount() { + return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { + return 0.5 - Math.random(); + })[0]; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; - a_out_sum -= stackIn.a; +function createBitmap(length, width, height) { + return { pixels: new Uint8ClampedArray(length), width: width, height: height }; +} - p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; +function getBitmap(bitmap, area) { + return Canvas.getBitmap(bitmap, area); +} - r_in_sum += stackIn.r = pixels[p]; - g_in_sum += stackIn.g = pixels[p + 1]; - b_in_sum += stackIn.b = pixels[p + 2]; - a_in_sum += stackIn.a = pixels[p + 3]; +function putBitmap(bitmap, subBitmap, area) { + return Canvas.putBitmap(bitmap, subBitmap, area); +} - r_sum += r_in_sum; - g_sum += g_in_sum; - b_sum += b_in_sum; - a_sum += a_in_sum; +function parseParamNumber(param) { + if (typeof param === 'string') { + param = param.replace(/deg/, ''); + param = param.replace(/px/, ''); + } + return +param; +} - stackIn = stackIn.next; +var filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; +function pack$1(callback) { + return function (bitmap) { + each$1(bitmap.pixels.length, function (i, xyIndex) { + callback(bitmap.pixels, i, xyIndex); + }); + return bitmap; + }; +} - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; - a_out_sum += pa = stackOut.a; +var ColorListIndex = [0, 1, 2, 3]; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; - a_in_sum -= pa; +function swapColor(pixels, startIndex, endIndex) { - stackOut = stackOut.next; + ColorListIndex.forEach(function (i) { + var temp = pixels[startIndex + i]; + pixels[startIndex + i] = pixels[endIndex + i]; + pixels[endIndex + i] = temp; + }); +} - yi += 4; - } - yw += width; - } +function packXY(callback) { + return function (bitmap) { + eachXY(bitmap.pixels.length, bitmap.width, function (i, x, y) { + callback(bitmap.pixels, i, x, y); + }); + return bitmap; + }; +} - for (x = 0; x < width; x++) { - g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; - yi = x << 2; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - a_sum += sumFactor * pa; +function createBlurMatrix() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - stack = stackStart; + var count = Math.pow(amount, 2); + var value = 1 / count; + return repeat(value, count); +} - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack.a = pa; - stack = stack.next; - } +function convolution(weights) { + var opaque = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - yp = width; + return function (_ref) { + var pixels = _ref.pixels, + width = _ref.width, + height = _ref.height; - for (i = 1; i <= radius; i++) { - yi = yp + x << 2; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); - r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; - b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; - a_sum += (stack.a = pa = pixels[yi + 3]) * rbs; + var w = width; + var h = height; + var sw = w; + var sh = h; + var dst = new Uint8ClampedArray(pixels.length); + var alphaFac = opaque ? 1 : 0; - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; - a_in_sum += pa; + for (var y = 0; y < h; y++) { + for (var x = 0; x < w; x++) { + var sy = y; + var sx = x; + var dstIndex = (y * w + x) * 4; - stack = stack.next; + var r = 0, + g = 0, + b = 0, + a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { - if (i < heightMinus1) { - yp += width; + var scy = sy + cy - halfSide; + var scx = sx + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + var srcIndex = (scy * sw + scx) * 4; + var wt = weights[cy * side + cx]; + r += pixels[srcIndex] * wt; + g += pixels[srcIndex + 1] * wt; + b += pixels[srcIndex + 2] * wt; + a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. + } + } + } + + dst[dstIndex] = r; + dst[dstIndex + 1] = g; + dst[dstIndex + 2] = b; + dst[dstIndex + 3] = a + alphaFac * (255 - a); } } - yi = x; - stackIn = stackStart; - stackOut = stackEnd; - for (y = 0; y < height; y++) { - p = yi << 2; - pixels[p + 3] = pa = a_sum * mul_sum >> shg_sum; - if (pa > 0) { - pa = 255 / pa; - pixels[p] = (r_sum * mul_sum >> shg_sum) * pa; - pixels[p + 1] = (g_sum * mul_sum >> shg_sum) * pa; - pixels[p + 2] = (b_sum * mul_sum >> shg_sum) * pa; - } else { - pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; - } + return { pixels: dst, width: sw, height: sh }; + }; +} - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; - a_sum -= a_out_sum; +function matches(str) { + var ret = Color.convertMatches(str); + var matches = ret.str.match(filter_regexp); + var result = []; - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; - a_out_sum -= stackIn.a; + if (!matches) { + return result; + } - p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; + result = matches.map(function (it) { + return { filter: it, origin: Color.reverseMatches(it, ret.matches) }; + }); - r_sum += r_in_sum += stackIn.r = pixels[p]; - g_sum += g_in_sum += stackIn.g = pixels[p + 1]; - b_sum += b_in_sum += stackIn.b = pixels[p + 2]; - a_sum += a_in_sum += stackIn.a = pixels[p + 3]; + var pos = { next: 0 }; + result = result.map(function (item) { - stackIn = stackIn.next; + var startIndex = str.indexOf(item.origin, pos.next); - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; - a_out_sum += pa = stackOut.a; + item.startIndex = startIndex; + item.endIndex = startIndex + item.origin.length; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; - a_in_sum -= pa; + item.arr = parseFilter(item.origin); - stackOut = stackOut.next; + pos.next = item.endIndex; - yi += width; - } - } + return item; + }).filter(function (it) { + if (!it.arr.length) return false; + return true; + }); - return bitmap; + return result; } -function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { - if (isNaN(radius) || radius < 1) return bitmap; - radius |= 0; +/** + * Filter Parser + * + * F.parseFilter('blur(30)') == ['blue', '30'] + * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] + * + * @param {String} filterString + */ +function parseFilter(filterString) { - var pixels = bitmap.pixels, - width = bitmap.width, - height = bitmap.height; + var ret = Color.convertMatches(filterString); + var matches = ret.str.match(filter_regexp); - var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, r_out_sum, g_out_sum, b_out_sum, r_in_sum, g_in_sum, b_in_sum, pr, pg, pb, rbs; + if (!matches[0]) { + return []; + } - var div = radius + radius + 1; - var widthMinus1 = width - 1; - var heightMinus1 = height - 1; - var radiusPlus1 = radius + 1; - var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; + var arr = matches[0].split('('); - var stackStart = new BlurStack(); - var stack = stackStart; - for (i = 1; i < div; i++) { - stack = stack.next = new BlurStack(); - if (i == radiusPlus1) var stackEnd = stack; + var filterName = arr.shift(); + var filterParams = []; + + if (arr.length) { + filterParams = arr.shift().split(')')[0].split(',').map(function (f) { + return Color.reverseMatches(f, ret.matches); + }); } - stack.next = stackStart; - var stackIn = null; - var stackOut = null; - yw = yi = 0; + var result = [filterName].concat(toConsumableArray(filterParams)).map(Color.trim); - var mul_sum = mul_table[radius]; - var shg_sum = shg_table[radius]; + return result; +} - for (y = 0; y < height; y++) { - r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0; +function clamp(num) { + return Math.min(255, num); +} - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); +function crop() { + var startX = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var startY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var width = arguments[2]; + var height = arguments[3]; - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; - stack = stackStart; + var newBitmap = createBitmap(width * height * 4, width, height); - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack = stack.next; + return function (bitmap) { + for (var y = startY, realY = 0; y < height; y++, realY++) { + for (var x = startX, realX = 0; x < width; x++, realX++) { + newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x]; + } } - for (i = 1; i < radiusPlus1; i++) { - p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); - r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[p + 1]) * rbs; - b_sum += (stack.b = pb = pixels[p + 2]) * rbs; + return newBitmap; + }; +} - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; +// Image manupulate +function resize(dstWidth, dstHeight) { + return function (bitmap) { - stack = stack.next; - } + var c = Canvas.drawPixels(bitmap); + var context = c.getContext('2d'); - stackIn = stackStart; - stackOut = stackEnd; - for (x = 0; x < width; x++) { - pixels[yi] = r_sum * mul_sum >> shg_sum; - pixels[yi + 1] = g_sum * mul_sum >> shg_sum; - pixels[yi + 2] = b_sum * mul_sum >> shg_sum; + c.width = dstWidth; + c.height = dstHeight; - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; + return { + pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), + width: dstWidth, + height: dstHeight + }; + }; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; +function flipV() { + return function (bitmap) { - p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; + var width = bitmap.width; + var height = bitmap.height; + var isCenter = height % 2 == 1 ? 1 : 0; - r_in_sum += stackIn.r = pixels[p]; - g_in_sum += stackIn.g = pixels[p + 1]; - b_in_sum += stackIn.b = pixels[p + 2]; + var halfHeight = isCenter ? Math.floor(height / 2) : height / 2; - r_sum += r_in_sum; - g_sum += g_in_sum; - b_sum += b_in_sum; + for (var y = 0; y < halfHeight; y++) { + for (var x = 0; x < width; x++) { - stackIn = stackIn.next; + var startIndex = (y * width + x) * 4; + var endIndex = ((height - 1 - y) * width + x) * 4; + swapColor(bitmap.pixels, startIndex, endIndex); + } + } - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; + return bitmap; + }; +} - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; +function flipH() { + return function (bitmap) { - stackOut = stackOut.next; + var width = bitmap.width; + var height = bitmap.height; + var isCenter = width % 2 == 1 ? 1 : 0; - yi += 4; + var halfWidth = isCenter ? Math.floor(width / 2) : width / 2; + + for (var y = 0; y < height; y++) { + for (var x = 0; x < halfWidth; x++) { + + var startIndex = (y * width + x) * 4; + var endIndex = (y * width + (width - 1 - x)) * 4; + swapColor(bitmap.pixels, startIndex, endIndex); + } } - yw += width; - } - for (x = 0; x < width; x++) { - g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0; + return bitmap; + }; +} - yi = x << 2; - r_out_sum = radiusPlus1 * (pr = pixels[yi]); - g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); - b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); +function rotateDegree(angle) { + var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'center'; + var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'center'; - r_sum += sumFactor * pr; - g_sum += sumFactor * pg; - b_sum += sumFactor * pb; + // const r = F.radian(angle) - stack = stackStart; + return function (bitmap) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); + var width = bitmap.width; + var height = bitmap.height; - for (i = 0; i < radiusPlus1; i++) { - stack.r = pr; - stack.g = pg; - stack.b = pb; - stack = stack.next; + if (cx == 'center') { + cx = Math.floor(width / 2); } - yp = width; + if (cy == 'center') { + cy = Math.floor(height / 2); + } - for (i = 1; i <= radius; i++) { - yi = yp + x << 2; + var translateMatrix = Matrix.CONSTANT.translate(-cx, -cy); + var translateMatrix2 = Matrix.CONSTANT.translate(cx, cy); + var shear1Matrix = Matrix.CONSTANT.shear1(angle); + var shear2Matrix = Matrix.CONSTANT.shear2(angle); - r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); - g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; - b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; + return packXY(function (pixels, i, x, y) { + // console.log(x, y, i) + var arr = Matrix.multiply(translateMatrix, [x, y, 1]); - r_in_sum += pr; - g_in_sum += pg; - b_in_sum += pb; + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); + arr = Matrix.multiply(shear2Matrix, arr).map(Math.round); + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); + arr = Matrix.multiply(translateMatrix2, arr); - stack = stack.next; + var _arr = arr, + _arr2 = slicedToArray(_arr, 2), + x1 = _arr2[0], + y1 = _arr2[1]; - if (i < heightMinus1) { - yp += width; - } - } + if (x1 < 0) return; + if (y1 < 0) return; + if (x1 > width - 1) return; + if (y1 > height - 1) return; - yi = x; - stackIn = stackStart; - stackOut = stackEnd; - for (y = 0; y < height; y++) { - p = yi << 2; - pixels[p] = r_sum * mul_sum >> shg_sum; - pixels[p + 1] = g_sum * mul_sum >> shg_sum; - pixels[p + 2] = b_sum * mul_sum >> shg_sum; + var endIndex = (y1 * width + x1) * 4; - r_sum -= r_out_sum; - g_sum -= g_out_sum; - b_sum -= b_out_sum; + pixels[endIndex] = bitmap.pixels[i]; + pixels[endIndex + 1] = bitmap.pixels[i + 1]; + pixels[endIndex + 2] = bitmap.pixels[i + 2]; + pixels[endIndex + 3] = bitmap.pixels[i + 3]; + })(newBitmap); + }; +} - r_out_sum -= stackIn.r; - g_out_sum -= stackIn.g; - b_out_sum -= stackIn.b; +function rotate() { + var degree = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; + degree = parseParamNumber(degree); + degree = degree % 360; + return function (bitmap) { - r_sum += r_in_sum += stackIn.r = pixels[p]; - g_sum += g_in_sum += stackIn.g = pixels[p + 1]; - b_sum += b_in_sum += stackIn.b = pixels[p + 2]; + if (degree == 0) return bitmap; - stackIn = stackIn.next; + if (degree == 90 || degree == 270) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width); + } else if (degree == 180) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); + } else { + return rotateDegree(degree)(bitmap); + } - r_out_sum += pr = stackOut.r; - g_out_sum += pg = stackOut.g; - b_out_sum += pb = stackOut.b; + var width = bitmap.width; + var height = bitmap.height; - r_in_sum -= pr; - g_in_sum -= pg; - b_in_sum -= pb; + packXY(function (pixels, i, x, y) { - stackOut = stackOut.next; + if (degree == 90) { + var endIndex = (x * newBitmap.width + (newBitmap.width - 1 - y)) * 4; + } else if (degree == 270) { + var endIndex = ((newBitmap.height - 1 - x) * newBitmap.width + y) * 4; + } else if (degree == 180) { + var endIndex = ((newBitmap.height - 1 - y) * newBitmap.width + (newBitmap.width - 1 - x)) * 4; + } - yi += width; - } - } + newBitmap.pixels[endIndex] = bitmap.pixels[i]; + newBitmap.pixels[endIndex + 1] = bitmap.pixels[i + 1]; + newBitmap.pixels[endIndex + 2] = bitmap.pixels[i + 2]; + newBitmap.pixels[endIndex + 3] = bitmap.pixels[i + 3]; + })(bitmap); - return bitmap; + return newBitmap; + }; } -var CONSTANT = { - identity: function identity() { - return [1, 0, 0, 0, 1, 0, 0, 0, 1]; - }, - stretching: function stretching(k) { - return [k, 0, 0, 0, 1, 0, 0, 0, 1]; - }, - squeezing: function squeezing(k) { - return [k, 0, 0, 0, 1 / k, 0, 0, 0, 1]; - }, - scale: function scale() { - var sx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var sy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; +var image = { + crop: crop, + resize: resize, + flipH: flipH, + flipV: flipV, + rotate: rotate, + rotateDegree: rotateDegree, + 'rotate-degree': rotateDegree +}; - sx = sx || sx === 0 ? sx : 1; - sy = sy || sy === 0 ? sy : 1; - return [sx, 0, 0, 0, sy, 0, 0, 0, 1]; - }, - scaleX: function scaleX(sx) { - return this.scale(sx); - }, - scaleY: function scaleY(sy) { - return this.scale(1, sy); - }, - translate: function translate(tx, ty) { - return [1, 0, tx, 0, 1, ty, 0, 0, 1]; - }, - rotate: function rotate(angle) { - var r = this.radian(angle); - return [Math.cos(r), -Math.sin(r), 0, Math.sin(r), Math.cos(r), 0, 0, 0, 1]; - }, - rotate90: function rotate90() { - return [0, -1, 0, 1, 0, 0, 0, 0, 1]; - }, - rotate180: function rotate180() { - return [-1, 0, 0, 0, -1, 0, 0, 0, 1]; - }, - rotate270: function rotate270() { - return [0, 1, 0, -1, 0, 0, 0, 0, 1]; - }, - radian: function radian(degree) { - return degree * Math.PI / 180; - }, - skew: function skew(degreeX, degreeY) { - var radianX = this.radian(degreeX); - var radianY = this.radian(degreeY); - return [1, Math.tan(radianX), 0, Math.tan(radianY), 1, 0, 0, 0, 1]; - }, - skewX: function skewX(degreeX) { - var radianX = this.radian(degreeX); +function bitonal(darkColor, lightColor) { + var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100; - return [1, Math.tan(radianX), 0, 0, 1, 0, 0, 0, 1]; - }, - skewY: function skewY(degreeY) { - var radianY = this.radian(degreeY); + darkColor = color.parse(darkColor); + lightColor = color.parse(lightColor); + return pack$1(function (pixels, i) { - return [1, 0, 0, Math.tan(radianY), 1, 0, 0, 0, 1]; - }, - shear1: function shear1(angle) { - return [1, -Math.tan(this.radian(angle) / 2), 0, 0, 1, 0, 0, 0, 1]; - }, - shear2: function shear2(angle) { - return [1, 0, 0, Math.sin(this.radian(angle)), 1, 0, 0, 0, 1]; - } -}; + if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { + pixels[i] = darkColor.r; + pixels[i + 1] = darkColor.g; + pixels[i + 2] = darkColor.b; + } else { + pixels[i] = lightColor.r; + pixels[i + 1] = lightColor.g; + pixels[i + 2] = lightColor.b; + } + }); +} -var Matrix = { - CONSTANT: CONSTANT, +/* + * @param {Number} amount -100..100 , value < 0 is darken, value > 0 is brighten + */ +function brightness() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - radian: function radian(angle) { - return CONSTANT.radian(angle); - }, - multiply: function multiply(A, C) { - // console.log(JSON.stringify(A), JSON.stringify(C)) - return [A[0] * C[0] + A[1] * C[1] + A[2] * C[2], A[3] * C[0] + A[4] * C[1] + A[5] * C[2], A[6] * C[0] + A[7] * C[1] + A[8] * C[2]]; - }, - identity: function identity(B) { - return this.multiply(CONSTANT.identity(), B); - }, - translate: function translate(x, y, B) { - return this.multiply(CONSTANT.translate(x, y), B); - }, - rotate: function rotate(angle, B) { - return this.multiply(CONSTANT.rotate(angle), B); - }, - shear1: function shear1(angle, B) { - return this.multiply(CONSTANT.shear1(angle), B); - }, - shear2: function shear2(angle, B) { - return this.multiply(CONSTANT.shear2(angle), B); - }, - rotateShear: function rotateShear(angle, B) { + amount = parseParamNumber(amount); + var C = Math.floor(255 * (amount / 100)); - var arr = B; + return pack$1(function (pixels, i) { + pixels[i] += C; + pixels[i + 1] += C; + pixels[i + 2] += C; + }); +} - arr = this.shear1(angle, arr); - arr = this.shear2(angle, arr); - arr = this.shear1(angle, arr); +/** + * + * @param {Number} amount from 0 to 100 + */ +function clip() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - return arr; - } -}; + amount = parseParamNumber(amount); + var C = Math.abs(amount) * 2.55; -// TODO: worker run -function weight(arr) { - var num = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + return pack$1(function (pixels, i) { - return arr.map(function (i) { - return i * num; + for (var start = i, end = i + 2; start <= end; start++) { + if (pixels[start] > 255 - C) { + pixels[start] = 255; + } else if (pixels[start] < C) { + pixels[start] = 0; + } + } }); } -function repeat(value, num) { - var arr = new Array(num); - for (var i = 0; i < num; i++) { - arr[i] = value; - } - return arr; +/** + * + * @param {*} amount min = -128, max = 128 + */ +function contrast() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + + amount = parseParamNumber(amount); + var C = Math.max((128 + amount) / 128, 0); + + return pack$1(function (pixels, i) { + pixels[i] = pixels[i] * C; + pixels[i + 1] = pixels[i + 1] * C; + pixels[i + 2] = pixels[i + 2] * C; + }); } -function colorMatrix(pixels, i, matrix) { - var r = pixels[i], - g = pixels[i + 1], - b = pixels[i + 2], - a = pixels[i + 3]; +function gamma() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; - pixels[i + 1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; - pixels[i + 2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; - pixels[i + 3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + pixels[i] = Math.pow(pixels[i] / 255, amount) * 255; + pixels[i + 1] = Math.pow(pixels[i + 1] / 255, amount) * 255; + pixels[i + 2] = Math.pow(pixels[i + 2] / 255, amount) * 255; + }); } -function makeFilter(filter) { +/** + * F.gradient('red', 'blue', 'yellow', 'white', 10) + * F.gradient('red, blue, yellow, white, 10') + */ +function gradient() { + // 전체 매개변수 기준으로 파싱 + // 색이 아닌 것 기준으로 scale 변수로 인식 - if (typeof filter == 'function') { - return filter; - } + var params = [].concat(Array.prototype.slice.call(arguments)); - if (typeof filter == 'string') { - filter = [filter]; + if (params.length === 1 && typeof params[0] === 'string') { + params = color.convertMatchesArray(params[0]); } - var filterName = filter.shift(); + params = params.map(function (arg) { + var res = color.matches(arg); - if (typeof filterName == 'function') { - return filterName; - } + if (!res.length) { + return { type: 'scale', value: arg }; + } - var params = filter; + return { type: 'param', value: arg }; + }); - var filterFunction = F[filterName]; + var scale = params.filter(function (it) { + return it.type == 'scale'; + })[0]; + scale = scale ? +scale.value : 256; - if (!filterFunction) { - throw new Error(filterName + ' is not filter. please check filter name.'); - } - return filterFunction.apply(filterFunction, params); -} + params = params.filter(function (it) { + return it.type == 'param'; + }).map(function (it) { + return it.value; + }).join(','); -function each$1(len, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex); - } + var colors = color.gradient(params, scale).map(function (c) { + return color.parse(c); + }); + + return pack$1(function (pixels, i) { + var colorIndex = clamp(color.brightness(pixels[i], pixels[i + 1], pixels[i + 2])); + var newColorIndex = clamp(Math.floor(colorIndex * (scale / 256))); + var color$$1 = colors[newColorIndex]; + + pixels[i] = color$$1.r; + pixels[i + 1] = color$$1.g; + pixels[i + 2] = color$$1.b; + pixels[i + 3] = clamp(Math.floor(color$$1.a * 256)); + }); } -function eachXY(len, width, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex % width, Math.floor(xyIndex / width)); - } +function grayscale(amount) { + amount = parseParamNumber(amount); + var C = amount / 100; + + if (C > 1) C = 1; + + return pack$1(function (pixels, i) { + + colorMatrix(pixels, i, [0.2126 + 0.7874 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 + 0.2848 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 + 0.9278 * (1 - C), 0, 0, 0, 0, 1]); + }); } -function createRandRange(min, max, count) { - var result = []; +/* + * @param {Number} amount 0..360 + */ +function hue() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 360; - for (var i = 1; i <= count; i++) { - var num = Math.random() * (max - min) + min; - var sign = Math.floor(Math.random() * 10) % 2 == 0 ? -1 : 1; - result.push(sign * num); - } + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + var r = pixels[i], + g = pixels[i + 1], + b = pixels[i + 2]; - result.sort(); + var hsv = Color.RGBtoHSV(r, g, b); - var centerIndex = Math.floor(count / 2); - var a = result[centerIndex]; - result[centerIndex] = result[0]; - result[0] = a; + // 0 ~ 360 + var h = hsv.h; + h += Math.abs(amount); + h = h % 360; + hsv.h = h; - return result; -} + var rgb = Color.HSVtoRGB(hsv); -function createRandomCount() { - return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { - return 0.5 - Math.random(); - })[0]; + pixels[i] = rgb.r; + pixels[i + 1] = rgb.g; + pixels[i + 2] = rgb.b; + }); } -function createBitmap(length, width, height) { - return { pixels: new Uint8ClampedArray(length), width: width, height: height }; -} +function invert() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -function getBitmap(bitmap, area) { - return Canvas.getBitmap(bitmap, area); -} + amount = parseParamNumber(amount); + var C = amount / 100; -function putBitmap(bitmap, subBitmap, area) { - return Canvas.putBitmap(bitmap, subBitmap, area); -} + return pack$1(function (pixels, i) { -function parseParamNumber(param) { - if (typeof param === 'string') { - param = param.replace(/deg/, ''); - param = param.replace(/px/, ''); - } - return +param; + pixels[i] = (255 - pixels[i]) * C; + pixels[i + 1] = (255 - pixels[i + 1]) * C; + pixels[i + 2] = (255 - pixels[i + 2]) * C; + }); } -var F = {}; -var ImageFilter = F; +/** + * + * @param {Number} amount 1..100 + */ +function noise() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; -var filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; -var pack$1 = F.pack = function pack(callback) { - return function (bitmap) { - each$1(bitmap.pixels.length, function (i, xyIndex) { - callback(bitmap.pixels, i, xyIndex); - }); - return bitmap; - }; -}; + amount = parseParamNumber(amount); + return pack$1(function (pixels, i) { + var C = Math.abs(amount) * 5; + var min = -C; + var max = C; + var noiseValue = Math.round(min + Math.random() * (max - min)); + pixels[i] += noiseValue; + pixels[i + 1] += noiseValue; + pixels[i + 2] += noiseValue; + }); +} -var ColorListIndex = [0, 1, 2, 3]; +function opacity() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -var swapColor = F.swapColor = function swapColor(pixels, startIndex, endIndex) { + amount = parseParamNumber(amount); + var C = amount / 100; - ColorListIndex.forEach(function (i) { - var temp = pixels[startIndex + i]; - pixels[startIndex + i] = pixels[endIndex + i]; - pixels[endIndex + i] = temp; + return pack$1(function (pixels, i) { + pixels[i + 3] *= C; }); -}; +} -var packXY = F.packXY = function packXY(callback) { - return function (bitmap) { - eachXY(bitmap.pixels.length, bitmap.width, function (i, x, y) { - callback(bitmap.pixels, i, x, y); - }); - return bitmap; - }; -}; +/* + * @param {Number} amount -100..100 + */ +function saturation() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.matches = function (str) { - var _this = this; + amount = parseParamNumber(amount); + var C = amount / 100; + var L = 1 - Math.abs(C); + return pack$1(function (pixels, i) { - var ret = color.convertMatches(str); - var matches = ret.str.match(filter_regexp); - var result = []; + colorMatrix(pixels, i, [L, 0, 0, 0, 0, L, 0, 0, 0, 0, L, 0, 0, 0, 0, L]); + }); +} - if (!matches) { - return result; - } +/* + * @param {Number} amount 0..100 + */ +function sepia() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - result = matches.map(function (it) { - return { filter: it, origin: color.reverseMatches(it, ret.matches) }; + amount = parseParamNumber(amount); + var C = amount / 100; + if (C > 1) C = 1; + + return pack$1(function (pixels, i) { + + colorMatrix(pixels, i, [0.393 + 0.607 * (1 - C), 0.769 - 0.769 * (1 - C), 0.189 - 0.189 * (1 - C), 0, 0.349 - 0.349 * (1 - C), 0.686 + 0.314 * (1 - C), 0.168 - 0.168 * (1 - C), 0, 0.272 - 0.272 * (1 - C), 0.534 - 0.534 * (1 - C), 0.131 + 0.869 * (1 - C), 0, 0, 0, 0, 1]); }); +} - var pos = { next: 0 }; - result = result.map(function (item) { +function shade() { + var r = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var g = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + var b = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; - var startIndex = str.indexOf(item.origin, pos.next); + r = parseParamNumber(r); + g = parseParamNumber(g); + b = parseParamNumber(b); + return pack$1(function (pixels, i) { + pixels[i] *= r; + pixels[i + 1] *= g; + pixels[i + 2] *= b; + }); +} - item.startIndex = startIndex; - item.endIndex = startIndex + item.origin.length; +/** + * change the relative darkness of (a part of an image) by overexposure to light. + * @param {*} r + * @param {*} g + * @param {*} b + */ +function solarize(r, g, b) { + r = parseParamNumber(r); + g = parseParamNumber(g); + b = parseParamNumber(b); + return pack$1(function (pixels, i) { + if (pixels[i] < r) pixels[i] = 255 - pixels[i]; + if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; + if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; + }); +} - item.arr = _this.parseFilter(item.origin); +function thresholdColor() { + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; + var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + var hasColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; - pos.next = item.endIndex; + scale = parseParamNumber(scale); + amount = parseParamNumber(amount); + var C = amount / 100; + return pack$1(function (pixels, i) { + var v = C * color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) >= scale ? 255 : 0; - return item; - }).filter(function (it) { - if (!it.arr.length) return false; - return !!F[it.arr[0]]; + if (hasColor) { + + if (v == 0) { + pixels[i] = pixels[i + 1] = pixels[i + 2] = 0; + } + } else { + pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v); + } }); +} - return result; +/* + * @param {Number} amount 0..100 + */ +function threshold() { + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; + var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + + return thresholdColor(scale, amount, false); +} + +var pixel = { + bitonal: bitonal, + brightness: brightness, + clip: clip, + contrast: contrast, + gamma: gamma, + gradient: gradient, + grayscale: grayscale, + hue: hue, + invert: invert, + noise: noise, + opacity: opacity, + saturation: saturation, + sepia: sepia, + shade: shade, + solarize: solarize, + threshold: threshold, + 'threshold-color': thresholdColor }; -/** - * Filter Parser - * - * F.parseFilter('blur(30)') == ['blue', '30'] - * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] +function blur () { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; + amount = parseParamNumber(amount); + + return convolution(createBlurMatrix(amount)); +} + +/* + * carve, mold, or stamp a design on (a surface) so that it stands out in relief. * - * @param {String} filterString + * @param {Number} amount 0.0 .. 4.0 */ -F.parseFilter = function (filterString) { - - var ret = color.convertMatches(filterString); - var matches = ret.str.match(filter_regexp); +function emboss() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4; - if (!matches[0]) { - return []; - } + amount = parseParamNumber(amount); + return convolution([amount * -2.0, -amount, 0.0, -amount, 1.0, amount, 0.0, amount, amount * 2.0]); +} - var arr = matches[0].split('('); +function gaussianBlur() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - var filterName = arr.shift(); - var filterParams = []; + amount = parseParamNumber(amount); + var C = amount / 100; - if (!F[filterName.toLowerCase()]) { - return []; - } + return convolution(weight([1, 2, 1, 2, 4, 2, 1, 2, 1], 1 / 16 * C)); +} - if (arr.length) { - filterParams = arr.shift().split(')')[0].split(',').map(function (f) { - return color.reverseMatches(f, ret.matches); - }); - } +function gaussianBlur5x() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - var result = [filterName].concat(toConsumableArray(filterParams)).map(color.trim); + amount = parseParamNumber(amount); + var C = amount / 100; + return convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, 36, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], 1 / 256 * C)); +} - return result; -}; +function grayscale2() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.filter = function (str) { - return F.merge(F.matches(str).map(function (it) { - return it.arr; - })); -}; + amount = parseParamNumber(amount); + return convolution(weight([0.3, 0.3, 0.3, 0, 0, 0.59, 0.59, 0.59, 0, 0, 0.11, 0.11, 0.11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); +} -/** - * - * multiply filters - * - * ImageFilter.multi('blur', 'grayscale', 'sharpen', ['blur', 3], function (bitmap) { return bitmap }); - * - */ -F.multi = function () { - for (var _len = arguments.length, filters = Array(_len), _key = 0; _key < _len; _key++) { - filters[_key] = arguments[_key]; - } +function identity() { + return convolution([0, 0, 0, 0, 1, 0, 0, 0, 0]); +} - filters = filters.map(function (f) { - return makeFilter(f); - }); +function kirschHorizontal() { + var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - return function (bitmap) { - return filters.reduce(function (bitmap, f) { - return f(bitmap); - }, bitmap); - }; -}; + count = parseParamNumber(count); + return convolution([5, 5, 5, -3, 0, -3, -3, -3, -3]); +} -F.merge = function (filters) { - return F.multi.apply(F, toConsumableArray(filters)); -}; +function kirschVertical() { + var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; -/** - * apply filter into special area - * - * F.partial({x,y,width,height}, filter, filter, filter ) - * F.partial({x,y,width,height}, 'filter' ) - * - * @param {{x, y, width, height}} area - * @param {*} filters - */ -F.partial = function (area) { - var allFilter = null; + count = parseParamNumber(count); + return convolution([5, -3, -3, 5, 0, -3, 5, -3, -3]); +} - for (var _len2 = arguments.length, filters = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - filters[_key2 - 1] = arguments[_key2]; - } +function laplacian() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - if (filters.length == 1 && typeof filters[0] === 'string') { - allFilter = F.filter(filters[0]); - } else { - allFilter = F.merge(filters); - } + amount = parseParamNumber(amount); + return convolution(weight([-1, -1, -1, -1, 8, -1, -1, -1, -1], amount / 100)); +} - return function (bitmap) { - return putBitmap(bitmap, allFilter(getBitmap(bitmap, area)), area); - }; -}; +function laplacian5x() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.counter = function (filter) { - var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + amount = parseParamNumber(amount); + return convolution(weight([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], amount / 100)); +} - var filters = []; +function motionBlur() { + return convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); +} - for (var i = 0; i < count; i++) { - filters.push(filter); - } +function motionBlur2() { + return convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); +} - return F.multi.apply(F, filters); -}; +function motionBlur3() { + return convolution(weight([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], 1 / 9)); +} -// Image manupulate -F.resize = function (dstWidth, dstHeight) { - return function (bitmap) { +function negative() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - var c = Canvas.drawPixels(bitmap); - var context = c.getContext('2d'); + amount = parseParamNumber(amount); + return convolution(weight([-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1], amount / 100)); +} - c.width = dstWidth; - c.height = dstHeight; +function random() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; + var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createRandomCount(); - return { - pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), - width: dstWidth, - height: dstHeight - }; + amount = parseParamNumber(amount); + return function (pixels, width, height) { + var rand = createRandRange(-1, 5, count); + return convolution(rand)(pixels, width, height); }; -}; - -F.crop = function () { - var startX = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var startY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var width = arguments[2]; - var height = arguments[3]; - +} - var newBitmap = createBitmap(width * height * 4, width, height); +function sepia2() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - return function (bitmap) { - for (var y = startY, realY = 0; y < height; y++, realY++) { - for (var x = startX, realX = 0; x < width; x++, realX++) { - newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x]; - } - } + amount = parseParamNumber(amount); + return convolution(weight([0.393, 0.349, 0.272, 0, 0, 0.769, 0.686, 0.534, 0, 0, 0.189, 0.168, 0.131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); +} - return newBitmap; - }; -}; +function sharpen() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; -F.flipH = function flipH() { - return function (bitmap) { + amount = parseParamNumber(amount); + return convolution(weight([0, -1, 0, -1, 5, -1, 0, -1, 0], amount / 100)); +} - var width = bitmap.width; - var height = bitmap.height; - var isCenter = width % 2 == 1 ? 1 : 0; +function sobelHorizontal() { + return convolution([-1, -2, -1, 0, 0, 0, 1, 2, 1]); +} - var halfWidth = isCenter ? Math.floor(width / 2) : width / 2; +function sobelVertical() { + return convolution([-1, 0, 1, -2, 0, 2, -1, 0, 1]); +} - for (var y = 0; y < height; y++) { - for (var x = 0; x < halfWidth; x++) { +/* - var startIndex = (y * width + x) * 4; - var endIndex = (y * width + (width - 1 - x)) * 4; - swapColor(bitmap.pixels, startIndex, endIndex); - } - } +StackBlur - a fast almost Gaussian Blur For Canvas - return bitmap; - }; -}; +Version: 0.5 +Author: Mario Klingemann +Contact: mario@quasimondo.com +Website: http://www.quasimondo.com/StackBlurForCanvas +Twitter: @quasimondo -F.flipV = function flipV() { - return function (bitmap) { +In case you find this class useful - especially in commercial projects - +I am not totally unhappy for a small donation to my PayPal account +mario@quasimondo.de - var width = bitmap.width; - var height = bitmap.height; - var isCenter = height % 2 == 1 ? 1 : 0; +Or support me on flattr: +https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript - var halfHeight = isCenter ? Math.floor(height / 2) : height / 2; +Copyright (c) 2010 Mario Klingemann - for (var y = 0; y < halfHeight; y++) { - for (var x = 0; x < width; x++) { +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: - var startIndex = (y * width + x) * 4; - var endIndex = ((height - 1 - y) * width + x) * 4; - swapColor(bitmap.pixels, startIndex, endIndex); - } - } +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. - return bitmap; - }; -}; +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +*/ -F.radian = function (degree) { - return Matrix.CONSTANT.radian(degree); -}; +var mul_table = [512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259]; -F['rotate-degree'] = F.rotateDegree = function (angle) { - var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'center'; - var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'center'; +var shg_table = [9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]; - // const r = F.radian(angle) +function BlurStack() { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 0; + this.next = null; +} - return function (bitmap) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); - var width = bitmap.width; - var height = bitmap.height; +function stackBlurImage(bitmap, radius, blurAlphaChannel) { - if (cx == 'center') { - cx = Math.floor(width / 2); - } + if (blurAlphaChannel) return stackBlurCanvasRGBA(bitmap, 0, 0, radius);else return stackBlurCanvasRGB(bitmap, 0, 0, radius); +} - if (cy == 'center') { - cy = Math.floor(height / 2); - } +function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { + if (isNaN(radius) || radius < 1) return bitmap; + radius |= 0; - var translateMatrix = Matrix.CONSTANT.translate(-cx, -cy); - var translateMatrix2 = Matrix.CONSTANT.translate(cx, cy); - var shear1Matrix = Matrix.CONSTANT.shear1(angle); - var shear2Matrix = Matrix.CONSTANT.shear2(angle); + var pixels = bitmap.pixels, + width = bitmap.width, + height = bitmap.height; - return packXY(function (pixels, i, x, y) { - // console.log(x, y, i) - var arr = Matrix.multiply(translateMatrix, [x, y, 1]); + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, r_out_sum, g_out_sum, b_out_sum, a_out_sum, r_in_sum, g_in_sum, b_in_sum, a_in_sum, pr, pg, pb, pa, rbs; - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); - arr = Matrix.multiply(shear2Matrix, arr).map(Math.round); - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round); - arr = Matrix.multiply(translateMatrix2, arr); + var div = radius + radius + 1; + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; - var _arr = arr, - _arr2 = slicedToArray(_arr, 2), - x1 = _arr2[0], - y1 = _arr2[1]; + var stackStart = new BlurStack(); + var stack = stackStart; + for (i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + if (i == radiusPlus1) var stackEnd = stack; + } + stack.next = stackStart; + var stackIn = null; + var stackOut = null; - if (x1 < 0) return; - if (y1 < 0) return; - if (x1 > width - 1) return; - if (y1 > height - 1) return; + yw = yi = 0; - var endIndex = (y1 * width + x1) * 4; + var mul_sum = mul_table[radius]; + var shg_sum = shg_table[radius]; - pixels[endIndex] = bitmap.pixels[i]; - pixels[endIndex + 1] = bitmap.pixels[i + 1]; - pixels[endIndex + 2] = bitmap.pixels[i + 2]; - pixels[endIndex + 3] = bitmap.pixels[i + 3]; - })(newBitmap); - }; -}; + for (y = 0; y < height; y++) { + r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; -F.rotate = function rotate() { - var degree = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - degree = parseParamNumber(degree); - degree = degree % 360; - return function (bitmap) { + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; - if (degree == 0) return bitmap; + stack = stackStart; - if (degree == 90 || degree == 270) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width); - } else if (degree == 180) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height); - } else { - return F.rotateDegree(degree)(bitmap); + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; } - var width = bitmap.width; - var height = bitmap.height; + for (i = 1; i < radiusPlus1; i++) { + p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); + r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[p + 1]) * rbs; + b_sum += (stack.b = pb = pixels[p + 2]) * rbs; + a_sum += (stack.a = pa = pixels[p + 3]) * rbs; - packXY(function (pixels, i, x, y) { + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; - if (degree == 90) { - var endIndex = (x * newBitmap.width + (newBitmap.width - 1 - y)) * 4; - } else if (degree == 270) { - var endIndex = ((newBitmap.height - 1 - x) * newBitmap.width + y) * 4; - } else if (degree == 180) { - var endIndex = ((newBitmap.height - 1 - y) * newBitmap.width + (newBitmap.width - 1 - x)) * 4; + stack = stack.next; + } + + stackIn = stackStart; + stackOut = stackEnd; + for (x = 0; x < width; x++) { + pixels[yi + 3] = pa = a_sum * mul_sum >> shg_sum; + if (pa != 0) { + pa = 255 / pa; + pixels[yi] = (r_sum * mul_sum >> shg_sum) * pa; + pixels[yi + 1] = (g_sum * mul_sum >> shg_sum) * pa; + pixels[yi + 2] = (b_sum * mul_sum >> shg_sum) * pa; + } else { + pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; } - // console.log(startIndex, endIndex) + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; - newBitmap.pixels[endIndex] = bitmap.pixels[i]; - newBitmap.pixels[endIndex + 1] = bitmap.pixels[i + 1]; - newBitmap.pixels[endIndex + 2] = bitmap.pixels[i + 2]; - newBitmap.pixels[endIndex + 3] = bitmap.pixels[i + 3]; - })(bitmap); + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; - return newBitmap; - }; -}; + p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; -// Pixel based + r_in_sum += stackIn.r = pixels[p]; + g_in_sum += stackIn.g = pixels[p + 1]; + b_in_sum += stackIn.b = pixels[p + 2]; + a_in_sum += stackIn.a = pixels[p + 3]; + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; + a_sum += a_in_sum; -F.grayscale = function (amount) { - amount = parseParamNumber(amount); - var C = amount / 100; + stackIn = stackIn.next; - if (C > 1) C = 1; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; + a_out_sum += pa = stackOut.a; - return pack$1(function (pixels, i) { + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; - colorMatrix(pixels, i, [0.2126 + 0.7874 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 + 0.2848 * (1 - C), 0.0722 - 0.0722 * (1 - C), 0, 0.2126 - 0.2126 * (1 - C), 0.7152 - 0.7152 * (1 - C), 0.0722 + 0.9278 * (1 - C), 0, 0, 0, 0, 1]); - }); -}; + stackOut = stackOut.next; -/* - * @param {Number} amount 0..360 - */ -F.hue = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 360; + yi += 4; + } + yw += width; + } - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - var r = pixels[i], - g = pixels[i + 1], - b = pixels[i + 2]; + for (x = 0; x < width; x++) { + g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; - var hsv = color.RGBtoHSV(r, g, b); + yi = x << 2; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * (pa = pixels[yi + 3]); - // 0 ~ 360 - var h = hsv.h; - h += Math.abs(amount); - h = h % 360; - hsv.h = h; + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; - var rgb = color.HSVtoRGB(hsv); + stack = stackStart; - pixels[i] = rgb.r; - pixels[i + 1] = rgb.g; - pixels[i + 2] = rgb.b; - }); -}; + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } -F.shade = function () { - var r = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var g = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - var b = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + yp = width; - r = parseParamNumber(r); - g = parseParamNumber(g); - b = parseParamNumber(b); - return pack$1(function (pixels, i) { - pixels[i] *= r; - pixels[i + 1] *= g; - pixels[i + 2] *= b; - }); -}; + for (i = 1; i <= radius; i++) { + yi = yp + x << 2; -F.bitonal = function (darkColor, lightColor) { - var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100; + r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; + b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; + a_sum += (stack.a = pa = pixels[yi + 3]) * rbs; - darkColor = color.parse(darkColor); - lightColor = color.parse(lightColor); - return pack$1(function (pixels, i) { + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; - if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { - pixels[i] = darkColor.r; - pixels[i + 1] = darkColor.g; - pixels[i + 2] = darkColor.b; - } else { - pixels[i] = lightColor.r; - pixels[i + 1] = lightColor.g; - pixels[i + 2] = lightColor.b; + stack = stack.next; + + if (i < heightMinus1) { + yp += width; + } } - }); -}; -/** - * F.gradient('red', 'blue', 'yellow', 'white', 10) - * F.gradient('red, blue, yellow, white, 10') - */ -F.duotone = function () { - // 전체 매개변수 기준으로 파싱 - // 색이 아닌 것 기준으로 scale 변수로 인식 + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for (y = 0; y < height; y++) { + p = yi << 2; + pixels[p + 3] = pa = a_sum * mul_sum >> shg_sum; + if (pa > 0) { + pa = 255 / pa; + pixels[p] = (r_sum * mul_sum >> shg_sum) * pa; + pixels[p + 1] = (g_sum * mul_sum >> shg_sum) * pa; + pixels[p + 2] = (b_sum * mul_sum >> shg_sum) * pa; + } else { + pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; + } - var params = [].concat(Array.prototype.slice.call(arguments)); + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; - if (params.length === 1 && typeof params[0] === 'string') { - params = color.convertMatchesArray(params[0]); - } + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; - params = params.map(function (arg) { - var res = color.matches(arg); + p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; - if (!res.length) { - return { type: 'scale', value: arg }; - } + r_sum += r_in_sum += stackIn.r = pixels[p]; + g_sum += g_in_sum += stackIn.g = pixels[p + 1]; + b_sum += b_in_sum += stackIn.b = pixels[p + 2]; + a_sum += a_in_sum += stackIn.a = pixels[p + 3]; - return { type: 'param', value: arg }; - }); + stackIn = stackIn.next; - var scale = params.filter(function (it) { - return it.type == 'scale'; - })[0]; - scale = scale ? +scale.value : 256; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; + a_out_sum += pa = stackOut.a; - params = params.filter(function (it) { - return it.type == 'param'; - }).map(function (it) { - return it.value; - }).join(','); + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; - var colors = color.gradient(params, scale).map(function (c) { - return color.parse(c); - }); + stackOut = stackOut.next; - return pack$1(function (pixels, i) { - var colorIndex = F.clamp(color.brightness(pixels[i], pixels[i + 1], pixels[i + 2])); - var newColorIndex = F.clamp(Math.floor(colorIndex * (scale / 256))); - var color$$1 = colors[newColorIndex]; + yi += width; + } + } - pixels[i] = color$$1.r; - pixels[i + 1] = color$$1.g; - pixels[i + 2] = color$$1.b; - pixels[i + 3] = F.clamp(Math.floor(color$$1.a * 256)); - }); -}; + return bitmap; +} -F.gradient = F.duotone; +function stackBlurCanvasRGBA(bitmap, top_x, top_y, radius) { + if (isNaN(radius) || radius < 1) return bitmap; + radius |= 0; -F.tint = function () { - var redTint = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var greenTint = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - var blueTint = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var pixels = bitmap.pixels, + width = bitmap.width, + height = bitmap.height; - redTint = parseParamNumber(redTint); - greenTint = parseParamNumber(greenTint); - blueTint = parseParamNumber(blueTint); - return pack$1(function (pixels, i) { - pixels[i] += (255 - pixels[i]) * redTint; - pixels[i + 1] += (255 - pixels[i + 1]) * greenTint; - pixels[i + 2] += (255 - pixels[i + 2]) * blueTint; - }); -}; + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, r_out_sum, g_out_sum, b_out_sum, r_in_sum, g_in_sum, b_in_sum, pr, pg, pb, rbs; -F.clamp = function (num) { - return Math.min(255, num); -}; -/** - * - * @param {*} amount min = -128, max = 128 - */ -F.contrast = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var div = radius + radius + 1; + var widthMinus1 = width - 1; + var heightMinus1 = height - 1; + var radiusPlus1 = radius + 1; + var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2; - amount = parseParamNumber(amount); - var C = Math.max((128 + amount) / 128, 0); + var stackStart = new BlurStack(); + var stack = stackStart; + for (i = 1; i < div; i++) { + stack = stack.next = new BlurStack(); + if (i == radiusPlus1) var stackEnd = stack; + } + stack.next = stackStart; + var stackIn = null; + var stackOut = null; - return pack$1(function (pixels, i) { - pixels[i] = pixels[i] * C; - pixels[i + 1] = pixels[i + 1] * C; - pixels[i + 2] = pixels[i + 2] * C; - }); -}; + yw = yi = 0; -F.invert = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + var mul_sum = mul_table[radius]; + var shg_sum = shg_table[radius]; - amount = parseParamNumber(amount); - var C = amount / 100; + for (y = 0; y < height; y++) { + r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0; - return pack$1(function (pixels, i) { + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); - pixels[i] = (255 - pixels[i]) * C; - pixels[i + 1] = (255 - pixels[i + 1]) * C; - pixels[i + 2] = (255 - pixels[i + 2]) * C; - }); -}; + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; -F.opacity = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + stack = stackStart; - amount = parseParamNumber(amount); - var C = amount / 100; + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack = stack.next; + } - return pack$1(function (pixels, i) { - pixels[i + 3] *= C; - }); -}; + for (i = 1; i < radiusPlus1; i++) { + p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); + r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[p + 1]) * rbs; + b_sum += (stack.b = pb = pixels[p + 2]) * rbs; -/** - * change the relative darkness of (a part of an image) by overexposure to light. - * @param {*} r - * @param {*} g - * @param {*} b - */ -F.solarize = function (r, g, b) { - r = parseParamNumber(r); - g = parseParamNumber(g); - b = parseParamNumber(b); - return pack$1(function (pixels, i) { - if (pixels[i] < r) pixels[i] = 255 - pixels[i]; - if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; - if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; - }); -}; + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; -/* - * @param {Number} amount 0..100 - */ -F.sepia = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + stack = stack.next; + } - amount = parseParamNumber(amount); - var C = amount / 100; - if (C > 1) C = 1; + stackIn = stackStart; + stackOut = stackEnd; + for (x = 0; x < width; x++) { + pixels[yi] = r_sum * mul_sum >> shg_sum; + pixels[yi + 1] = g_sum * mul_sum >> shg_sum; + pixels[yi + 2] = b_sum * mul_sum >> shg_sum; - return pack$1(function (pixels, i) { + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; - colorMatrix(pixels, i, [0.393 + 0.607 * (1 - C), 0.769 - 0.769 * (1 - C), 0.189 - 0.189 * (1 - C), 0, 0.349 - 0.349 * (1 - C), 0.686 + 0.314 * (1 - C), 0.168 - 0.168 * (1 - C), 0, 0.272 - 0.272 * (1 - C), 0.534 - 0.534 * (1 - C), 0.131 + 0.869 * (1 - C), 0, 0, 0, 0, 1]); - }); -}; + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; -F.gamma = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + p = yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1) << 2; - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - pixels[i] = Math.pow(pixels[i] / 255, amount) * 255; - pixels[i + 1] = Math.pow(pixels[i + 1] / 255, amount) * 255; - pixels[i + 2] = Math.pow(pixels[i + 2] / 255, amount) * 255; - }); -}; + r_in_sum += stackIn.r = pixels[p]; + g_in_sum += stackIn.g = pixels[p + 1]; + b_in_sum += stackIn.b = pixels[p + 2]; -/** - * - * @param {Number} amount 1..100 - */ -F.noise = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; - amount = parseParamNumber(amount); - return pack$1(function (pixels, i) { - var C = Math.abs(amount) * 5; - var min = -C; - var max = C; - var noiseValue = Math.round(min + Math.random() * (max - min)); - pixels[i] += noiseValue; - pixels[i + 1] += noiseValue; - pixels[i + 2] += noiseValue; - }); -}; + stackIn = stackIn.next; -/** - * - * @param {Number} amount from 0 to 100 - */ -F.clip = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; - amount = parseParamNumber(amount); - var C = Math.abs(amount) * 2.55; + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; - return pack$1(function (pixels, i) { + stackOut = stackOut.next; - for (var start = i, end = i + 2; start <= end; start++) { - if (pixels[start] > 255 - C) { - pixels[start] = 255; - } else if (pixels[start] < C) { - pixels[start] = 0; - } + yi += 4; } - }); -}; - -/* - * @param {Number} amount -100..100 , value < 0 is darken, value > 0 is brighten - */ -F.brightness = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + yw += width; + } - amount = parseParamNumber(amount); - var C = Math.floor(255 * (amount / 100)); + for (x = 0; x < width; x++) { + g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0; - return pack$1(function (pixels, i) { - pixels[i] += C; - pixels[i + 1] += C; - pixels[i + 2] += C; - }); -}; + yi = x << 2; + r_out_sum = radiusPlus1 * (pr = pixels[yi]); + g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]); -/* - * @param {Number} amount -100..100 - */ -F.saturation = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; - amount = parseParamNumber(amount); - var C = amount / 100; - var L = 1 - Math.abs(C); - return pack$1(function (pixels, i) { + stack = stackStart; - colorMatrix(pixels, i, [L, 0, 0, 0, 0, L, 0, 0, 0, 0, L, 0, 0, 0, 0, L]); - }); -}; + for (i = 0; i < radiusPlus1; i++) { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack = stack.next; + } -/* - * @param {Number} amount 0..100 - */ -F.threshold = function () { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; - var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + yp = width; - return F.thresholdColor(scale, amount, false); -}; + for (i = 1; i <= radius; i++) { + yi = yp + x << 2; -F['threshold-color'] = F.thresholdColor = function () { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200; - var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; - var hasColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); + g_sum += (stack.g = pg = pixels[yi + 1]) * rbs; + b_sum += (stack.b = pb = pixels[yi + 2]) * rbs; - scale = parseParamNumber(scale); - amount = parseParamNumber(amount); - var C = amount / 100; - return pack$1(function (pixels, i) { - var v = C * color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) >= scale ? 255 : 0; + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; - if (hasColor) { + stack = stack.next; - if (v == 0) { - pixels[i] = pixels[i + 1] = pixels[i + 2] = 0; + if (i < heightMinus1) { + yp += width; } - } else { - pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v); } - }); -}; -// Matrix based + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for (y = 0; y < height; y++) { + p = yi << 2; + pixels[p] = r_sum * mul_sum >> shg_sum; + pixels[p + 1] = g_sum * mul_sum >> shg_sum; + pixels[p + 2] = b_sum * mul_sum >> shg_sum; -F.convolution = function (weights) { - var opaque = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; - return function (_ref) { - var pixels = _ref.pixels, - width = _ref.width, - height = _ref.height; + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; - var side = Math.round(Math.sqrt(weights.length)); - var halfSide = Math.floor(side / 2); + p = x + ((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width << 2; - var w = width; - var h = height; - var sw = w; - var sh = h; - var dst = new Uint8ClampedArray(pixels.length); - var alphaFac = opaque ? 1 : 0; + r_sum += r_in_sum += stackIn.r = pixels[p]; + g_sum += g_in_sum += stackIn.g = pixels[p + 1]; + b_sum += b_in_sum += stackIn.b = pixels[p + 2]; - for (var y = 0; y < h; y++) { - for (var x = 0; x < w; x++) { - var sy = y; - var sx = x; - var dstIndex = (y * w + x) * 4; + stackIn = stackIn.next; - var r = 0, - g = 0, - b = 0, - a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { + r_out_sum += pr = stackOut.r; + g_out_sum += pg = stackOut.g; + b_out_sum += pb = stackOut.b; - var scy = sy + cy - halfSide; - var scx = sx + cx - halfSide; + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; - if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { - var srcIndex = (scy * sw + scx) * 4; - var wt = weights[cy * side + cx]; - r += pixels[srcIndex] * wt; - g += pixels[srcIndex + 1] * wt; - b += pixels[srcIndex + 2] * wt; - a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. - } - } - } + stackOut = stackOut.next; - dst[dstIndex] = r; - dst[dstIndex + 1] = g; - dst[dstIndex + 2] = b; - dst[dstIndex + 3] = a + alphaFac * (255 - a); - } + yi += width; } + } - return { pixels: dst, width: sw, height: sh }; - }; -}; + return bitmap; +} -F.identity = function () { - return F.convolution([0, 0, 0, 0, 1, 0, 0, 0, 0]); -}; +function stackBlur () { + var radius = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; + var hasAlphaChannel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; -F.random = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; - var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createRandomCount(); + radius = parseParamNumber(radius); - amount = parseParamNumber(amount); - return function (pixels, width, height) { - var rand = createRandRange(-1, 5, count); - return F.convolution(rand)(pixels, width, height); + return function (bitmap) { + return stackBlurImage(bitmap, radius, hasAlphaChannel); }; -}; +} -F.grayscale2 = function () { +function transparency() { var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; amount = parseParamNumber(amount); - return F.convolution(weight([0.3, 0.3, 0.3, 0, 0, 0.59, 0.59, 0.59, 0, 0, 0.11, 0.11, 0.11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); -}; + return convolution(weight([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 1], amount / 100)); +} -F.sepia2 = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +function unsharpMasking() { + var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 256; amount = parseParamNumber(amount); - return F.convolution(weight([0.393, 0.349, 0.272, 0, 0, 0.769, 0.686, 0.534, 0, 0, 0.189, 0.168, 0.131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], amount / 100)); -}; - -F.negative = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + return convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, -476, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], -1 / amount)); +} - amount = parseParamNumber(amount); - return F.convolution(weight([-1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1], amount / 100)); +var matrix = { + blur: blur, + emboss: emboss, + gaussianBlur: gaussianBlur, + 'gaussian-blur': gaussianBlur, + gaussianBlur5x: gaussianBlur5x, + 'gaussian-blur-5x': gaussianBlur5x, + grayscale2: grayscale2, + identity: identity, + kirschHorizontal: kirschHorizontal, + 'kirsch-horizontal': kirschHorizontal, + kirschVertical: kirschVertical, + 'kirsch-vertical': kirschVertical, + laplacian: laplacian, + laplacian5x: laplacian5x, + 'laplacian-5x': laplacian5x, + motionBlur: motionBlur, + 'motion-blur': motionBlur, + motionBlur2: motionBlur2, + 'motion-blur-2': motionBlur2, + motionBlur3: motionBlur3, + 'motion-blur-3': motionBlur3, + negative: negative, + random: random, + sepia2: sepia2, + sharpen: sharpen, + sobelHorizontal: sobelHorizontal, + 'sobel-horizontal': sobelHorizontal, + sobelVertical: sobelVertical, + 'sobel-vertical': sobelVertical, + stackBlur: stackBlur, + 'stack-blur': stackBlur, + transparency: transparency, + unsharpMasking: unsharpMasking, + 'unsharp-masking': unsharpMasking }; -F.sharpen = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - return F.convolution(weight([0, -1, 0, -1, 5, -1, 0, -1, 0], amount / 100)); -}; +var ImageFilter$1 = _extends({}, image, pixel, matrix); -F['motion-blur'] = F.motionBlur = function () { - return F.convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); -}; +// TODO: worker run +Object.assign(ImageFilter$1, { + pack: pack$1, + packXY: packXY, + swapColor: swapColor +}); -F['motion-blur-2'] = F.motionBlur2 = function () { - return F.convolution(weight([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], 1 / 9)); -}; +var F = ImageFilter$1; -F['motion-blur-3'] = F.motionBlur3 = function () { - return F.convolution(weight([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], 1 / 9)); +F.filter = function (str) { + return F.merge(matches(str).map(function (it) { + return it.arr; + })); }; -function createBlurMatrix() { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - - var count = Math.pow(amount, 2); - var value = 1 / count; - return repeat(value, count); -} - -/** +/** + * + * multiply filters + * + * ImageFilter.multi('blur', 'grayscale', 'sharpen', ['blur', 3], function (bitmap) { return bitmap }); * - * @param {Number} amount from 3 to 100 */ -F.blur = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3; - amount = parseParamNumber(amount); - - return F.convolution(createBlurMatrix(amount)); -}; - -F['stack-blur'] = F.stackBlur = function () { - var radius = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10; - var hasAlphaChannel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; +F.multi = function () { + for (var _len = arguments.length, filters = Array(_len), _key = 0; _key < _len; _key++) { + filters[_key] = arguments[_key]; + } - radius = parseParamNumber(radius); + filters = filters.map(function (filter) { + return makeFilter(filter, F); + }); return function (bitmap) { - return stackBlurImage(bitmap, radius, hasAlphaChannel); + return filters.reduce(function (bitmap, f) { + return f(bitmap); + }, bitmap); }; }; -F['gaussian-blur'] = F.gaussianBlur = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - var C = amount / 100; - - return F.convolution(weight([1, 2, 1, 2, 4, 2, 1, 2, 1], 1 / 16 * C)); +F.merge = function (filters) { + return F.multi.apply(F, toConsumableArray(filters)); }; -F['gaussian-blur-5x'] = F.gaussianBlur5x = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +/** + * apply filter into special area + * + * F.partial({x,y,width,height}, filter, filter, filter ) + * F.partial({x,y,width,height}, 'filter' ) + * + * @param {{x, y, width, height}} area + * @param {*} filters + */ +F.partial = function (area) { + var allFilter = null; - amount = parseParamNumber(amount); - var C = amount / 100; - return F.convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, 36, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], 1 / 256 * C)); -}; + for (var _len2 = arguments.length, filters = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + filters[_key2 - 1] = arguments[_key2]; + } -F['unsharp-masking'] = F.unsharpMasking = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 256; + if (filters.length == 1 && typeof filters[0] === 'string') { + allFilter = F.filter(filters[0]); + } else { + allFilter = F.merge(filters); + } - amount = parseParamNumber(amount); - return F.convolution(weight([1, 4, 6, 4, 1, 4, 16, 24, 16, 4, 6, 24, -476, 24, 6, 4, 16, 24, 16, 4, 1, 4, 6, 4, 1], -1 / amount)); + return function (bitmap) { + return putBitmap(bitmap, allFilter(getBitmap(bitmap, area)), area); + }; }; -F.transparency = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; +F.counter = function (filter) { + var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - amount = parseParamNumber(amount); - return F.convolution(weight([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 1], amount / 100)); -}; + var filters = []; -F.laplacian = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; + for (var i = 0; i < count; i++) { + filters.push(filter); + } - amount = parseParamNumber(amount); - return F.convolution(weight([-1, -1, -1, -1, 8, -1, -1, -1, -1], amount / 100)); + return F.multi.apply(F, filters); }; +/** + * multi filter + */ + F.laplacian.grayscale = function () { var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; return F.filter('grayscale laplacian(' + amount); }; -F.laplacian5x = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100; - - amount = parseParamNumber(amount); - return F.convolution(weight([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], amount / 100)); -}; - F.laplacian5x.grayscale = function () { return F.filter('grayscale laplacian5x'); }; -F['kirsch-horizontal'] = F.kirschHorizontal = function () { - var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - - count = parseParamNumber(count); - return F.convolution([5, 5, 5, -3, 0, -3, -3, -3, -3]); -}; - -F['kirsch-vertical'] = F.kirschVertical = function () { - var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - - count = parseParamNumber(count); - return F.convolution([5, -3, -3, 5, 0, -3, 5, -3, -3]); -}; - F.kirsch = function () { return F.filter('kirsch-horizontal kirsch-vertical'); }; @@ -3373,14 +3450,6 @@ F.kirsch.grayscale = function () { return F.filter('grayscale kirsch'); }; -F['sobel-horizontal'] = F.sobelHorizontal = function () { - return F.convolution([-1, -2, -1, 0, 0, 0, 1, 2, 1]); -}; - -F['sobel-vertical'] = F.sobelVertical = function () { - return F.convolution([-1, 0, 1, -2, 0, 2, -1, 0, 1]); -}; - F.sobel = function () { return F.filter('sobel-horizontal sobel-vertical'); }; @@ -3389,22 +3458,6 @@ F.sobel.grayscale = function () { return F.filter('grayscale sobel'); }; -/* - * carve, mold, or stamp a design on (a surface) so that it stands out in relief. - * - * @param {Number} amount 0.0 .. 4.0 - */ -F.emboss = function () { - var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4; - - amount = parseParamNumber(amount); - return F.convolution([amount * -2.0, -amount, 0.0, -amount, 1.0, amount, 0.0, amount, amount * 2.0]); -}; - -/** - * multi filter - */ - F.vintage = function () { return F.filter('brightness(15) saturation(-20) gamma(1.8)'); }; @@ -6185,7 +6238,7 @@ var index = { Color: color, ColorNames: ColorNames, ColorPicker: ColorPicker, - ImageFilter: ImageFilter, + ImageFilter: ImageFilter$1, HueColor: HueColor, Canvas: Canvas, ImageLoader: ImageLoader diff --git a/dist/codemirror-colorpicker.min.js b/dist/codemirror-colorpicker.min.js index fc4a920..cc2d0ab 100644 --- a/dist/codemirror-colorpicker.min.js +++ b/dist/codemirror-colorpicker.min.js @@ -1 +1 @@ -var CodeMirrorColorPicker=function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb(0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb(0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb(0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb(95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(237, 20, 61)",cyan:"rgb(0, 255, 255)",darkblue:"rgb(0, 0, 139)",darkcyan:"rgb(0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgrey:"rgb(169, 169, 169)",darkgreen:"rgb(0, 100, 0)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb(85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb(72, 61, 139)",darkslategray:"rgb(47, 79, 79)",darkslategrey:"rgb(47, 79, 79)",darkturquoise:"rgb(0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb(0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb(30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb(34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb(75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgreen:"rgb(144, 238, 144)",lightgray:"rgb(211, 211, 211)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb(32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb(0, 255, 0)",limegreen:"rgb(50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb(0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb(60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb(0, 250, 154)",mediumturquoise:"rgb(72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb(25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb(0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",rebeccapurple:"rgb(102, 51, 153)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb(65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb(46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb(0, 255, 127)",steelblue:"rgb(70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb(0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb(64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)",transparent:"rgba(0, 0, 0, 0)"};var r={isColorName:function(t){return!!e[t]},getColorByName:function(t){return e[t]}};function i(t,e){if(t.length!==e.length)return!1;for(var r=0,i=t.length;r0)u=s(c);else u=e[Math.floor(a()*e.length)];o=!i(u,h),n[l]=u}return o}function h(t,e,r){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:10,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"linear";t=t,e=e||Math.max(2,Math.ceil(Math.sqrt(t.length/2)));var s=r||"euclidean";"string"==typeof s&&(s=n[s]);for(var h=0,u=function(){return(h=(9301*h+49297)%233280)/233280},f=function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"linear";return o[r](t.length,e).map(function(e){return t[e]})}(t,e,a),v=!0,g=0;v;){if(v=c(e,t,l(e,t,f,s),f,!1,u),++g%i==0)break}return f}var u={create:function(t,e){var r=document.createElement("canvas");return r.width=t||0,r.height=e||0,r},drawPixels:function(t){var e=this.create(t.width,t.height),r=e.getContext("2d"),i=r.getImageData(0,0,e.width,e.height);return i.data.set(t.pixels),r.putImageData(i,0,0),e},createHistogram:function(t,e,r,i){var n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{black:!0,red:!1,green:!1,blue:!1},o=this.create(t,e),a=o.getContext("2d");a.clearRect(0,0,t,e),a.fillStyle="white",a.fillRect(0,0,t,e),a.globalAlpha=.7;var s={black:!1};n.black?s.black=!1:s.black=!0,n.red?s.red=!1:s.red=!0,n.green?s.green=!1:s.green=!0,n.blue?s.blue=!1:s.blue=!0,Object.keys(r).forEach(function(i){if(!s[i]){var n=r[i],o=Math.max.apply(Math,n),l=t/n.length;a.fillStyle=i,n.forEach(function(t,r){var i=e*(t/o),n=r*l;a.fillRect(n,e-i,l,i)})}}),"function"==typeof i&&i(o)},getHistogram:function(t){for(var e,r,i=new Array(256),n=new Array(256),o=new Array(256),a=new Array(256),s=0;s<256;s++)i[s]=0,n[s]=0,o[s]=0,a[s]=0;return r=function(t,e){var r=Math.round(w.brightness(t[e],t[e+1],t[e+2]));i[r]++,n[t[e]]++,o[t[e+1]]++,a[t[e+2]]++},function(t,e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{};v(this,t),this.isLoaded=!1,this.imageUrl=e,this.opt=r,this.initialize()}return g(t,[{key:"initialize",value:function(){this.canvas=this.createCanvas(),this.context=this.canvas.getContext("2d")}},{key:"createCanvas",value:function(){return document.createElement("canvas")}},{key:"load",value:function(t){this.loadImage(t)}},{key:"loadImage",value:function(t){var e=this,r=this.context,i=new Image;i.onload=function(){var n=i.height/i.width;e.opt.canvasWidth&&e.opt.canvasHeight?(e.canvas.width=e.opt.canvasWidth,e.canvas.height=e.opt.canvasHeight):(e.canvas.width=e.opt.maxWidth?e.opt.maxWidth:i.width,e.canvas.height=e.canvas.width*n),r.drawImage(i,0,0,i.width,i.height,0,0,e.canvas.width,e.canvas.height),e.isLoaded=!0,t&&t()},this.getImageUrl(function(t){i.src=t})}},{key:"getImageUrl",value:function(t){if("string"==typeof this.imageUrl)return t(this.imageUrl);if(this.imageUrl instanceof Blob){var e=new FileReader;e.onload=function(e){t(e.target.result)},e.readAsDataURL(this.imageUrl)}}},{key:"getRGBA",value:function(t,e,r,i){return[t,e,r,i]}},{key:"toArray",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=this.context.getImageData(0,0,this.canvas.width,this.canvas.height),i=r.width,n=r.height,o={pixels:new Uint8ClampedArray(r.data),width:i,height:n};return t&&(o=t(o)),u.drawPixels(o).toDataURL(e.outputFormat||"image/png")}},{key:"toHistogram",value:function(t){var e=this.context.getImageData(0,0,this.canvas.width,this.canvas.height),r=e.width,i=e.height,n={pixels:new Uint8ClampedArray(e.data),width:r,height:i};return u.getHistogram(n)}},{key:"toRGB",value:function(){for(var t=this.context.getImageData(0,0,this.canvas.width,this.canvas.height).data,e=[],r=0,i=t.length;r-1||e[n].indexOf("rgb")>-1||e[n].indexOf("hsl")>-1)i.push({color:e[n]});else{var a=r.getColorByName(e[n]);a&&i.push({color:e[n],nameColor:a})}var s={next:0};return i.forEach(function(e){var r=t.indexOf(e.color,s.next);e.startIndex=r,e.endIndex=r+e.color.length,s.next=e.endIndex}),i},convertMatches:function(t){var e=this.matches(t);return e.forEach(function(e,r){t=t.replace(e.color,"@"+r)}),{str:t,matches:e}},convertMatchesArray:function(t){var e=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:",",i=this.convertMatches(t);return i.str.split(r).map(function(t,r){return t=e.trim(t),i.matches[r]&&(t=t.replace("@"+r,i.matches[r].color)),t})},reverseMatches:function(t,e){return e.forEach(function(e,r){t=t.replace("@"+r,e.color)}),t},trim:function(t){return t.replace(/^\s+|\s+$/g,"")},round:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return Math.round(t*e)/e},format:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgba(0, 0, 0, 0)";return Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),"hex"==e?this.hex(t):"rgb"==e?this.rgb(t,r):"hsl"==e?this.hsl(t):t},hex:function(t){Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]});var e=t.r.toString(16);t.r<16&&(e="0"+e);var r=t.g.toString(16);t.g<16&&(r="0"+r);var i=t.b.toString(16);return t.b<16&&(i="0"+i),"#"+e+r+i},rgb:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"rgba(0, 0, 0, 0)";if(Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),void 0!==t)return 1==t.a||void 0===t.a?isNaN(t.r)?e:"rgb("+t.r+","+t.g+","+t.b+")":"rgba("+t.r+","+t.g+","+t.b+","+t.a+")"},hsl:function(t){return Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),1==t.a||void 0===t.a?"hsl("+t.h+","+t.s+"%,"+t.l+"%)":"hsla("+t.h+","+t.s+"%,"+t.l+"%,"+t.a+")"},parse:function(t){if("string"==typeof t){if(r.isColorName(t)&&(t=r.getColorByName(t)),t.indexOf("rgb(")>-1){for(var e=0,i=(o=t.replace("rgb(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("rgba(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("hsl(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("hsla(","").replace(")","").split(",")).length;e>16,g:(65280&t)>>8,b:(255&t)>>0,a:1};return n=Object.assign(n,this.RGBtoHSL(n))}if(0<=t&&t<=4294967295){n={type:"hex",r:(4278190080&t)>>24,g:(16711680&t)>>16,b:(65280&t)>>8,a:(255&t)/255};return n=Object.assign(n,this.RGBtoHSL(n))}}return t},HSVtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.v}var n=t,o=r;360==n&&(n=0);var a=e*o,s=a*(1-Math.abs(n/60%2-1)),l=o-a,c=[];return 0<=n&&n<60?c=[a,s,0]:60<=n&&n<120?c=[s,a,0]:120<=n&&n<180?c=[0,a,s]:180<=n&&n<240?c=[0,s,a]:240<=n&&n<300?c=[s,0,a]:300<=n&&n<360&&(c=[a,0,s]),{r:this.round(255*(c[0]+l)),g:this.round(255*(c[1]+l)),b:this.round(255*(c[2]+l))}},RGBtoHSV:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255,s=Math.max(n,o,a),l=s-Math.min(n,o,a),c=0;0==l?c=0:s==n?c=(o-a)/l%6*60:s==o?c=60*((a-n)/l+2):s==a&&(c=60*((n-o)/l+4)),c<0&&(c=360+c);return{h:c,s:0==s?0:l/s,v:s}},HSVtoHSL:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.v}var n=this.HSVtoRGB(t,e,r);return this.RGBtoHSL(n.r,n.g,n.b)},RGBtoCMYK:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255,s=1-Math.max(n,o,a);return{c:(1-n-s)/(1-s),m:(1-o-s)/(1-s),y:(1-a-s)/(1-s),k:s}},CMYKtoRGB:function(t,e,r,i){if(1==arguments.length){var n=arguments[0];t=n.c,e=n.m,r=n.y,i=n.k}return{r:255*(1-t)*(1-i),g:255*(1-e)*(1-i),b:255*(1-r)*(1-i)}},RGBtoHSL:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}t/=255,e/=255,r/=255;var n,o,a=Math.max(t,e,r),s=Math.min(t,e,r),l=(a+s)/2;if(a==s)n=o=0;else{var c=a-s;switch(o=l>.5?c/(2-a-s):c/(a+s),a){case t:n=(e-r)/c+(e1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t},HSLtoHSV:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,i.v}var n=this.HSLtoRGB(t,e,r);return this.RGBtoHSV(n.r,n.g,n.b)},HSLtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.l}var n,o,a;if(t/=360,r/=100,0==(e/=100))n=o=a=r;else{var s=r<.5?r*(1+e):r+e-r*e,l=2*r-s;n=this.HUEtoRGB(l,s,t+1/3),o=this.HUEtoRGB(l,s,t),a=this.HUEtoRGB(l,s,t-1/3)}return{r:this.round(255*n),g:this.round(255*o),b:this.round(255*a)}},c:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray((t+e+r)/3>90?0:255)},gray:function(t){return{r:t,g:t,b:t}},RGBtoSimpleGray:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray(Math.ceil((t+e+r)/3))},RGBtoGray:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray(this.RGBtoYCrCb(t,e,r).y)},brightness:function(t,e,r){return Math.ceil(.2126*t+.7152*e+.0722*r)},RGBtoYCrCb:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=this.brightness(t,e,r);return{y:n,cr:.713*(t-n),cb:.564*(r-n)}},YCrCbtoRGB:function(t,e,r,i){if(1==arguments.length){var n=arguments[0];t=n.y,e=n.cr,r=n.cb;i=(i=n.bit)||0}var o=t+1.402*(e-i),a=t-.344*(r-i)-.714*(e-i),s=t+1.772*(r-i);return{r:Math.ceil(o),g:Math.ceil(a),b:Math.ceil(s)}},ReverseRGB:function(t){return t>.0031308?1.055*Math.pow(t,1/2.4)-.055:12.92*t},XYZtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.x,e=i.y,r=i.z}var n=t/100,o=e/100,a=r/100,s=3.2406*n+-1.5372*o+-.4986*a,l=-.9689*n+1.8758*o+.0415*a,c=.0557*n+-.204*o+1.057*a;return s=this.ReverseRGB(s),l=this.ReverseRGB(l),c=this.ReverseRGB(c),{r:this.round(255*s),g:this.round(255*l),b:this.round(255*c)}},PivotRGB:function(t){return 100*(t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92)},RGBtoXYZ:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255;return{x:.4124*(n=this.PivotRGB(n))+.3576*(o=this.PivotRGB(o))+.1805*(a=this.PivotRGB(a)),y:.2126*n+.7152*o+.0722*a,z:.0193*n+.1192*o+.9505*a}},ReverseXyz:function(t){return Math.pow(t,3)>.008856?Math.pow(t,3):(t-16/116)/7.787},LABtoXYZ:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.l,e=i.a,r=i.b}var n=(t+16)/116,o=e/500+n,a=n-r/200;return n=this.ReverseXyz(n),{x:95.047*(o=this.ReverseXyz(o)),y:100*n,z:108.883*(a=this.ReverseXyz(a))}},PivotXyz:function(t){return t>.008856?Math.pow(t,1/3):(7.787*t+16)/116},XYZtoLAB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.x,e=i.y,r=i.z}var n=t/95.047,o=e/100,a=r/108.883;return n=this.PivotXyz(n),{l:116*(o=this.PivotXyz(o))-16,a:500*(n-o),b:200*(o-(a=this.PivotXyz(a)))}},RGBtoLAB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.XYZtoLAB(this.RGBtoXYZ(t,e,r))},LABtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.l,e=i.a,r=i.b}return this.XYZtoRGB(this.LABtoXYZ(t,e,r))},blend:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex",n=this.parse(t),o=this.parse(e);return this.interpolateRGB(n,o,r,i)},mix:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex";return this.blend(t,e,r,i)},contrast:function(t){t=this.parse(t);var e=(Math.round(299*t.r)+Math.round(587*t.g)+Math.round(114*t.b))/1e3;return e},contrastColor:function(t){return this.contrast(t)>=128?"black":"white"},interpolateRGB:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex",n={r:this.round(t.r+(e.r-t.r)*r),g:this.round(t.g+(e.g-t.g)*r),b:this.round(t.b+(e.b-t.b)*r),a:this.round(t.a+(e.a-t.a)*r,100)};return this.format(n,n.a<1?"rgb":i)},scale:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;if(!t)return[];"string"==typeof t&&(t=this.convertMatchesArray(t));for(var r=(t=t||[]).length,i=[],n=0;n0){var i=(1-t.filter(function(t){return"*"!=t[1]&&1!=t[1]}).map(function(t){return t[1]}).reduce(function(t,e){return t+e},0))/r;t.forEach(function(e,r){"*"==e[1]&&r>0&&(t.length-1==r||(e[1]=i))})}return t},gradient:function(t){for(var e=[],r=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:10)-((t=this.parseGradient(t)).length-1),i=r,n=1,o=t.length;n1&&void 0!==arguments[1]?arguments[1]:"h",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:9,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"rgb",n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1,a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:100,s=this.parse(t),l=this.RGBtoHSV(s),c=(o-n)*a/r,h=[],u=1;u<=r;u++)l[e]=Math.abs((a-c*u)/a),h.push(this.format(this.HSVtoRGB(l),i));return h},scaleH:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:360;return this.scaleHSV(t,"h",e,r,i,n,1)},scaleS:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;return this.scaleHSV(t,"s",e,r,i,n,100)},scaleV:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;return this.scaleHSV(t,"v",e,r,i,n,100)},palette:function(t){var e=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"hex";return t.length>r&&(t=h(t,r)),t.map(function(t){return e.format(t,i)})},ImageToRGB:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments[2];if(r){if(r){var i;(i=new k(t,e)).loadImage(function(){"function"==typeof r&&r(i.toRGB())})}}else(i=new k(t)).loadImage(function(){"function"==typeof e&&e(i.toRGB())})},ImageToURL:function(t,e,r){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},n=new k(t);n.loadImage(function(){"function"==typeof r&&r(n.toArray(e,i))})},histogram:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=new k(t);i.loadImage(function(){"function"==typeof e&&e(i.toHistogram(r))})},ImageToHistogram:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{width:200,height:100},i=new k(t);i.loadImage(function(){u.createHistogram(r.width||200,r.height||100,i.toHistogram(r),function(t){"function"==typeof e&&e(t.toDataURL("image/png"))},r)})}};w.scale.parula=function(t){return w.scale(["#352a87","#0f5cdd","#00b5a6","#ffc337","#fdff00"],t)},w.scale.jet=function(t){return w.scale(["#00008f","#0020ff","#00ffff","#51ff77","#fdff00","#ff0000","#800000"],t)},w.scale.hsv=function(t){return w.scale(["#ff0000","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff","#ff0000"],t)},w.scale.hot=function(t){return w.scale(["#0b0000","#ff0000","#ffff00","#ffffff"],t)},w.scale.pink=function(t){return w.scale(["#1e0000","#bd7b7b","#e7e5b2","#ffffff"],t)},w.scale.bone=function(t){return w.scale(["#000000","#4a4a68","#a6c6c6","#ffffff"],t)},w.scale.copper=function(t){return w.scale(["#000000","#3d2618","#9d623e","#ffa167","#ffc77f"],t)};var x=[{rgb:"#ff0000",start:0},{rgb:"#ffff00",start:.17},{rgb:"#00ff00",start:.33},{rgb:"#00ffff",start:.5},{rgb:"#0000ff",start:.67},{rgb:"#ff00ff",start:.83},{rgb:"#ff0000",start:1}];!function(){for(var t=0,e=x.length;t=t){e=x[i-1],r=x[i];break}return e&&r?w.interpolateRGB(e,r,(t-e.start)/(r.start-e.start)):x[0].rgb}},$=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],S=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function M(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}function H(t,e,r){return r?function(t,e,r,i){if(isNaN(i)||i<1)return t;i|=0;var n,o,a,s,l,c,h,u,f,v,g,d,p,m,y,b,k,C,w,x,_,H,B,R,E=t.pixels,A=t.width,L=t.height,I=i+i+1,O=A-1,F=L-1,G=i+1,P=G*(G+1)/2,N=new M,T=N;for(a=1;a>U,0!=B?(B=255/B,E[c]=(u*j>>U)*B,E[c+1]=(f*j>>U)*B,E[c+2]=(v*j>>U)*B):E[c]=E[c+1]=E[c+2]=0,u-=d,f-=p,v-=m,g-=y,d-=z.r,p-=z.g,m-=z.b,y-=z.a,s=h+((s=n+i+1)>U,B>0?(B=255/B,E[s]=(u*j>>U)*B,E[s+1]=(f*j>>U)*B,E[s+2]=(v*j>>U)*B):E[s]=E[s+1]=E[s+2]=0,u-=d,f-=p,v-=m,g-=y,d-=z.r,p-=z.g,m-=z.b,y-=z.a,s=n+((s=o+G)0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return[t=t||0===t?t:1,0,0,0,e=e||0===e?e:1,0,0,0,1]},scaleX:function(t){return this.scale(t)},scaleY:function(t){return this.scale(1,t)},translate:function(t,e){return[1,0,t,0,1,e,0,0,1]},rotate:function(t){var e=this.radian(t);return[Math.cos(e),-Math.sin(e),0,Math.sin(e),Math.cos(e),0,0,0,1]},rotate90:function(){return[0,-1,0,1,0,0,0,0,1]},rotate180:function(){return[-1,0,0,0,-1,0,0,0,1]},rotate270:function(){return[0,1,0,-1,0,0,0,0,1]},radian:function(t){return t*Math.PI/180},skew:function(t,e){var r=this.radian(t),i=this.radian(e);return[1,Math.tan(r),0,Math.tan(i),1,0,0,0,1]},skewX:function(t){var e=this.radian(t);return[1,Math.tan(e),0,0,1,0,0,0,1]},skewY:function(t){var e=this.radian(t);return[1,0,0,Math.tan(e),1,0,0,0,1]},shear1:function(t){return[1,-Math.tan(this.radian(t)/2),0,0,1,0,0,0,1]},shear2:function(t){return[1,0,0,Math.sin(this.radian(t)),1,0,0,0,1]}},R={CONSTANT:B,radian:function(t){return B.radian(t)},multiply:function(t,e){return[t[0]*e[0]+t[1]*e[1]+t[2]*e[2],t[3]*e[0]+t[4]*e[1]+t[5]*e[2],t[6]*e[0]+t[7]*e[1]+t[8]*e[2]]},identity:function(t){return this.multiply(B.identity(),t)},translate:function(t,e,r){return this.multiply(B.translate(t,e),r)},rotate:function(t,e){return this.multiply(B.rotate(t),e)},shear1:function(t,e){return this.multiply(B.shear1(t),e)},shear2:function(t,e){return this.multiply(B.shear2(t),e)},rotateShear:function(t,e){var r=e;return r=this.shear1(t,r),r=this.shear2(t,r),r=this.shear1(t,r)}};function E(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return t.map(function(t){return t*e})}function A(t,e,r){var i=t[e],n=t[e+1],o=t[e+2],a=t[e+3];t[e]=r[0]*i+r[1]*n+r[2]*o+r[3]*a,t[e+1]=r[4]*i+r[5]*n+r[6]*o+r[7]*a,t[e+2]=r[8]*i+r[9]*n+r[10]*o+r[11]*a,t[e+3]=r[12]*i+r[13]*n+r[14]*o+r[15]*a}function L(t,e,r){return{pixels:new Uint8ClampedArray(t),width:e,height:r}}function I(t){return"string"==typeof t&&(t=(t=t.replace(/deg/,"")).replace(/px/,"")),+t}var O={},F=O,G=/(([\w_\-]+)(\(([^\)]*)\))?)+/gi,P=O.pack=function(t){return function(e){return function(t,e){for(var r=0,i=0;r0&&void 0!==arguments[0]?arguments[0]:3,e=Math.pow(t,2);return function(t,e){for(var r=new Array(e),i=0;i1?r-1:0),n=1;n1&&void 0!==arguments[1]?arguments[1]:1,r=[],i=0;i0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments[2],i=arguments[3],n=L(r*i*4,r,i);return function(o){for(var a=e,s=0;a1&&void 0!==arguments[1]?arguments[1]:"center",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"center";return function(i){var n=L(i.pixels.length,i.width,i.height),o=i.width,a=i.height;"center"==e&&(e=Math.floor(o/2)),"center"==r&&(r=Math.floor(a/2));var s=R.CONSTANT.translate(-e,-r),l=R.CONSTANT.translate(e,r),c=R.CONSTANT.shear1(t),h=R.CONSTANT.shear2(t);return D(function(t,e,r,n){var u=R.multiply(s,[r,n,1]);u=R.multiply(c,u).map(Math.round),u=R.multiply(h,u).map(Math.round),u=R.multiply(c,u).map(Math.round),u=R.multiply(l,u);var f=y(u,2),v=f[0],g=f[1];if(!(v<0||g<0||v>o-1||g>a-1)){var d=4*(g*o+v);t[d]=i.pixels[e],t[d+1]=i.pixels[e+1],t[d+2]=i.pixels[e+2],t[d+3]=i.pixels[e+3]}})(n)}},O.rotate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return t=I(t),t%=360,function(e){if(0==t)return e;if(90==t||270==t)var r=L(e.pixels.length,e.height,e.width);else{if(180!=t)return O.rotateDegree(t)(e);r=L(e.pixels.length,e.width,e.height)}e.width,e.height;return D(function(i,n,o,a){if(90==t)var s=4*(o*r.width+(r.width-1-a));else if(270==t)s=4*((r.height-1-o)*r.width+a);else if(180==t)s=4*((r.height-1-a)*r.width+(r.width-1-o));r.pixels[s]=e.pixels[n],r.pixels[s+1]=e.pixels[n+1],r.pixels[s+2]=e.pixels[n+2],r.pixels[s+3]=e.pixels[n+3]})(e),r}},O.grayscale=function(t){var e=(t=I(t))/100;return e>1&&(e=1),P(function(t,r){A(t,r,[.2126+.7874*(1-e),.7152-.7152*(1-e),.0722-.0722*(1-e),0,.2126-.2126*(1-e),.7152+.2848*(1-e),.0722-.0722*(1-e),0,.2126-.2126*(1-e),.7152-.7152*(1-e),.0722+.9278*(1-e),0,0,0,0,1])})},O.hue=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:360;return t=I(t),P(function(e,r){var i=e[r],n=e[r+1],o=e[r+2],a=w.RGBtoHSV(i,n,o),s=a.h;s+=Math.abs(t),s%=360,a.h=s;var l=w.HSVtoRGB(a);e[r]=l.r,e[r+1]=l.g,e[r+2]=l.b})},O.shade=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return t=I(t),e=I(e),r=I(r),P(function(i,n){i[n]*=t,i[n+1]*=e,i[n+2]*=r})},O.bitonal=function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:100;return t=w.parse(t),e=w.parse(e),P(function(i,n){i[n]+i[n+1]+i[n+2]<=r?(i[n]=t.r,i[n+1]=t.g,i[n+2]=t.b):(i[n]=e.r,i[n+1]=e.g,i[n+2]=e.b)})},O.duotone=function(){var t=[].concat(Array.prototype.slice.call(arguments));1===t.length&&"string"==typeof t[0]&&(t=w.convertMatchesArray(t[0]));var e=(t=t.map(function(t){return w.matches(t).length?{type:"param",value:t}:{type:"scale",value:t}})).filter(function(t){return"scale"==t.type})[0];e=e?+e.value:256,t=t.filter(function(t){return"param"==t.type}).map(function(t){return t.value}).join(",");var r=w.gradient(t,e).map(function(t){return w.parse(t)});return P(function(t,i){var n=O.clamp(w.brightness(t[i],t[i+1],t[i+2])),o=O.clamp(Math.floor(n*(e/256))),a=r[o];t[i]=a.r,t[i+1]=a.g,t[i+2]=a.b,t[i+3]=O.clamp(Math.floor(256*a.a))})},O.gradient=O.duotone,O.tint=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return t=I(t),e=I(e),r=I(r),P(function(i,n){i[n]+=(255-i[n])*t,i[n+1]+=(255-i[n+1])*e,i[n+2]+=(255-i[n+2])*r})},O.clamp=function(t){return Math.min(255,t)},O.contrast=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;t=I(t);var e=Math.max((128+t)/128,0);return P(function(t,r){t[r]=t[r]*e,t[r+1]=t[r+1]*e,t[r+2]=t[r+2]*e})},O.invert=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100;return P(function(t,r){t[r]=(255-t[r])*e,t[r+1]=(255-t[r+1])*e,t[r+2]=(255-t[r+2])*e})},O.opacity=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100;return P(function(t,r){t[r+3]*=e})},O.solarize=function(t,e,r){return t=I(t),e=I(e),r=I(r),P(function(i,n){i[n]0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100;return e>1&&(e=1),P(function(t,r){A(t,r,[.393+.607*(1-e),.769-.769*(1-e),.189-.189*(1-e),0,.349-.349*(1-e),.686+.314*(1-e),.168-.168*(1-e),0,.272-.272*(1-e),.534-.534*(1-e),.131+.869*(1-e),0,0,0,0,1])})},O.gamma=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=I(t),P(function(e,r){e[r]=255*Math.pow(e[r]/255,t),e[r+1]=255*Math.pow(e[r+1]/255,t),e[r+2]=255*Math.pow(e[r+2]/255,t)})},O.noise=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=I(t),P(function(e,r){var i=5*Math.abs(t),n=-i,o=i,a=Math.round(n+Math.random()*(o-n));e[r]+=a,e[r+1]+=a,e[r+2]+=a})},O.clip=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;t=I(t);var e=2.55*Math.abs(t);return P(function(t,r){for(var i=r,n=r+2;i<=n;i++)t[i]>255-e?t[i]=255:t[i]0&&void 0!==arguments[0]?arguments[0]:1;t=I(t);var e=Math.floor(t/100*255);return P(function(t,r){t[r]+=e,t[r+1]+=e,t[r+2]+=e})},O.saturation=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100,r=1-Math.abs(e);return P(function(t,e){A(t,e,[r,0,0,0,0,r,0,0,0,0,r,0,0,0,0,r])})},O.threshold=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:200,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100;return O.thresholdColor(t,e,!1)},O["threshold-color"]=O.thresholdColor=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:200,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];t=I(t);var i=(e=I(e))/100;return P(function(e,n){var o=i*w.brightness(e[n],e[n+1],e[n+2])>=t?255:0;r?0==o&&(e[n]=e[n+1]=e[n+2]=0):e[n]=e[n+1]=e[n+2]=Math.round(o)})},O.convolution=function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return function(r){for(var i=r.pixels,n=r.width,o=r.height,a=Math.round(Math.sqrt(t.length)),s=Math.floor(a/2),l=n,c=o,h=l,u=c,f=new Uint8ClampedArray(i.length),v=e?1:0,g=0;g=0&&$=0&&S0&&void 0!==arguments[0]?arguments[0]:10,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[9,16,25,36,49,64,81,100].sort(function(t,e){return.5-Math.random()})[0];return t=I(t),function(t,r,i){var n=function(t,e,r){for(var i=[],n=1;n<=r;n++){var o=Math.random()*(e-t)+t,a=Math.floor(10*Math.random())%2==0?-1:1;i.push(a*o)}i.sort();var s=Math.floor(r/2),l=i[s];return i[s]=i[0],i[0]=l,i}(-1,5,e);return O.convolution(n)(t,r,i)}},O.grayscale2=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([.3,.3,.3,0,0,.59,.59,.59,0,0,.11,.11,.11,0,0,0,0,0,0,0,0,0,0,0,0],t/100))},O.sepia2=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([.393,.349,.272,0,0,.769,.686,.534,0,0,.189,.168,.131,0,0,0,0,0,0,0,0,0,0,0,0],t/100))},O.negative=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([-1,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,0,1,0,1,1,1,1,1],t/100))},O.sharpen=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([0,-1,0,-1,5,-1,0,-1,0],t/100))},O["motion-blur"]=O.motionBlur=function(){return O.convolution(E([1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1],1/9))},O["motion-blur-2"]=O.motionBlur2=function(){return O.convolution(E([1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1],1/9))},O["motion-blur-3"]=O.motionBlur3=function(){return O.convolution(E([1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1],1/9))},O.blur=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:3;return t=I(t),O.convolution(z(t))},O["stack-blur"]=O.stackBlur=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10,e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return t=I(t),function(r){return H(r,t,e)}},O["gaussian-blur"]=O.gaussianBlur=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100;return O.convolution(E([1,2,1,2,4,2,1,2,1],1/16*e))},O["gaussian-blur-5x"]=O.gaussianBlur5x=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=I(t))/100;return O.convolution(E([1,4,6,4,1,4,16,24,16,4,6,24,36,24,6,4,16,24,16,4,1,4,6,4,1],1/256*e))},O["unsharp-masking"]=O.unsharpMasking=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:256;return t=I(t),O.convolution(E([1,4,6,4,1,4,16,24,16,4,6,24,-476,24,6,4,16,24,16,4,1,4,6,4,1],-1/t))},O.transparency=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,.3,0,0,0,0,0,1],t/100))},O.laplacian=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([-1,-1,-1,-1,8,-1,-1,-1,-1],t/100))},O.laplacian.grayscale=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return O.filter("grayscale laplacian("+t)},O.laplacian5x=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return t=I(t),O.convolution(E([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],t/100))},O.laplacian5x.grayscale=function(){return O.filter("grayscale laplacian5x")},O["kirsch-horizontal"]=O.kirschHorizontal=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=I(t),O.convolution([5,5,5,-3,0,-3,-3,-3,-3])},O["kirsch-vertical"]=O.kirschVertical=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=I(t),O.convolution([5,-3,-3,5,0,-3,5,-3,-3])},O.kirsch=function(){return O.filter("kirsch-horizontal kirsch-vertical")},O.kirsch.grayscale=function(){return O.filter("grayscale kirsch")},O["sobel-horizontal"]=O.sobelHorizontal=function(){return O.convolution([-1,-2,-1,0,0,0,1,2,1])},O["sobel-vertical"]=O.sobelVertical=function(){return O.convolution([-1,0,1,-2,0,2,-1,0,1])},O.sobel=function(){return O.filter("sobel-horizontal sobel-vertical")},O.sobel.grayscale=function(){return O.filter("grayscale sobel")},O.emboss=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:4;return t=I(t),O.convolution([-2*t,-t,0,-t,1,t,0,t,2*t])},O.vintage=function(){return O.filter("brightness(15) saturation(-20) gamma(1.8)")};var V=0,j=[],U=function(){function t(e,r,i){if(v(this,t),"string"!=typeof e)this.el=e;else{var n=document.createElement(e);for(var o in this.uniqId=V++,r&&(n.className=r),i=i||{})n.setAttribute(o,i[o]);this.el=n}}return g(t,[{key:"attr",value:function(t,e){return 1==arguments.length?this.el.getAttribute(t):(this.el.setAttribute(t,e),this)}},{key:"closest",value:function(e){for(var r=this,i=!1;!(i=r.hasClass(e));){if(!r.el.parentNode)return null;r=new t(r.el.parentNode)}return i?r:null}},{key:"removeClass",value:function(t){this.el.className=(" "+this.el.className+" ").replace(" "+t+" "," ").trim()}},{key:"hasClass",value:function(t){return!!this.el.className&&(" "+this.el.className+" ").indexOf(" "+t+" ")>-1}},{key:"addClass",value:function(t){this.hasClass(t)||(this.el.className=this.el.className+" "+t)}},{key:"toggleClass",value:function(t){this.hasClass(t)?this.removeClass(t):this.addClass(t)}},{key:"html",value:function(t){return"string"==typeof t?this.el.innerHTML=t:this.empty().append(t),this}},{key:"empty",value:function(){return this.html("")}},{key:"append",value:function(t){return"string"==typeof t?this.el.appendChild(document.createTextNode(t)):this.el.appendChild(t.el||t),this}},{key:"appendTo",value:function(t){return(t.el?t.el:t).appendChild(this.el),this}},{key:"remove",value:function(){return this.el.parentNode&&this.el.parentNode.removeChild(this.el),this}},{key:"text",value:function(){return this.el.textContent}},{key:"css",value:function(t,e){var r=this;if(2==arguments.length)this.el.style[t]=e;else if(1==arguments.length){if("string"==typeof t)return getComputedStyle(this.el)[t];var i=t||{};Object.keys(i).forEach(function(t){r.el.style[t]=i[t]})}return this}},{key:"cssFloat",value:function(t){return parseFloat(this.css(t))}},{key:"cssInt",value:function(t){return parseInt(this.css(t))}},{key:"offset",value:function(){var t=this.el.getBoundingClientRect();return{top:t.top+document.documentElement.scrollTop,left:t.left+document.documentElement.scrollLeft}}},{key:"position",value:function(){return this.el.style.top?{top:parseFloat(this.css("top")),left:parseFloat(this.css("left"))}:this.el.getBoundingClientRect()}},{key:"width",value:function(){return this.el.offsetWidth}},{key:"contentWidth",value:function(){return this.width()-this.cssFloat("padding-left")-this.cssFloat("padding-right")}},{key:"height",value:function(){return this.el.offsetHeight}},{key:"contentHeight",value:function(){return this.height()-this.cssFloat("padding-top")-this.cssFloat("padding-bottom")}},{key:"dataKey",value:function(t){return this.uniqId+"."+t}},{key:"data",value:function(t,e){if(2!=arguments.length){if(1==arguments.length)return j[this.dataKey(t)];var r=Object.keys(j),i=this.uniqId+".";return r.filter(function(t){return 0==t.indexOf(i)}).map(function(t){return j[t]})}return j[this.dataKey(t)]=e,this}},{key:"val",value:function(t){return 0==arguments.length?this.el.value:(1==arguments.length&&(this.el.value=t),this)}},{key:"int",value:function(){return parseInt(this.val(),10)}},{key:"float",value:function(){return parseFloat(this.val())}},{key:"show",value:function(){return this.css("display","block")}},{key:"hide",value:function(){return this.css("display","none")}},{key:"toggle",value:function(){return"none"==this.css("display")?this.show():this.hide()}},{key:"scrollTop",value:function(){return this.el===document.body?document.documentElement.scrollTop:this.el.scrollTop}},{key:"scrollLeft",value:function(){return this.el===document.body?document.documentElement.scrollLeft:this.el.scrollLeft}},{key:"on",value:function(t,e,r,i){return this.el.addEventListener(t,e,r,i),this}},{key:"off",value:function(t,e){return this.el.removeEventListener(t,e),this}},{key:"getElement",value:function(){return this.el}},{key:"createChild",value:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=new t(e,r,i);return o.css(n),this.append(o),o}}]),t}(),X={addEvent:function(t,e,r){t.addEventListener(e,r)},removeEvent:function(t,e,r){t.removeEventListener(e,r)},pos:function(t){return t.touches&&t.touches[0]?t.touches[0]:t}},Y=function(){function t(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};v(this,t),this.masterObj=e,this.settingObj=r}return g(t,[{key:"set",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;this.settingObj[t]=e||r}},{key:"init",value:function(t){if(!this.has(t)){var e=t.split("."),r=this.masterObj[e[0]]||this.masterObj,i=e.pop();if(r[i]){for(var n=arguments.length,o=Array(n>1?n-1:0),a=1;a1&&void 0!==arguments[1]?arguments[1]:"";return this.init(t,e),this.settingObj[t]||e}},{key:"has",value:function(t){return!!this.settingObj[t]}}]),t}(),q=/^(click|mouse(down|up|move|enter|leave)|key(down|up|press)|contextmenu|change|input)/gi,K=["Control","Shift","Alt","Meta"],W=function(){function t(){v(this,t),this.state=new Y(this)}return g(t,[{key:"initializeEvent",value:function(){this.initializeEventMachin()}},{key:"destroy",value:function(){this.destroyEventMachin()}},{key:"destroyEventMachin",value:function(){this.removeEventAll()}},{key:"initializeEventMachin",value:function(){this.filterProps(q).forEach(this.parseEvent.bind(this))}},{key:"filterProps",value:function(t){return Object.getOwnPropertyNames(this.__proto__).filter(function(e){return e.match(t)})}},{key:"parseEvent",value:function(t){var e=t.split(" ");this.bindingEvent(e,this[t].bind(this))}},{key:"getDefaultDomElement",value:function(t){var e=void 0;return(e=t?this[t]||window[t]:this.el||this.$el||this.$root)instanceof U?e.getElement():e}},{key:"getDefaultEventObject",value:function(t){var e=this,r=t.split("."),i=r.shift(),n=r.includes("Control"),o=r.includes("Shift"),a=r.includes("Alt"),s=r.includes("Meta"),l=(r=r.filter(function(t){return!1===K.includes(t)})).filter(function(t){return!!e[t]});return{eventName:i,isControl:n,isShift:o,isAlt:a,isMeta:s,codes:r=r.filter(function(t){return!1===l.includes(t)}).map(function(t){return t.toLowerCase()}),checkMethodList:l}}},{key:"bindingEvent",value:function(t,e){var r,i=(r=t,Array.isArray(r)?r:Array.from(r)),n=i[0],o=i[1],a=i.slice(2);o=this.getDefaultDomElement(o);var s=this.getDefaultEventObject(n);s.dom=o,s.delegate=a.join(" "),this.addEvent(s,e)}},{key:"matchPath",value:function(t,e){return t?t.matches(e)?t:this.matchPath(t.parentElement,e):null}},{key:"getBindings",value:function(){return this._bindings||this.initBindings(),this._bindings}},{key:"addBinding",value:function(t){this.getBindings().push(t)}},{key:"initBindings",value:function(){this._bindings=[]}},{key:"checkEventType",value:function(t,e){var r=this,i=!t.ctrlKey||e.isControl,n=!t.shiftKey||e.isShift,o=!t.altKey||e.isAlt,a=!t.metaKey||e.isMeta,s=!0;e.codes.length&&(s=e.codes.includes(t.code.toLowerCase())||e.codes.includes(t.key.toLowerCase()));var l=!0;return e.checkMethodList.length&&(l=e.checkMethodList.every(function(e){return r[e].call(r,t)})),i&&o&&n&&a&&s&&l}},{key:"makeCallback",value:function(t,e){var r=this;return t.delegate?function(i){if(r.checkEventType(i,t)){var n=r.matchPath(i.target||i.srcElement,t.delegate);if(n)return i.delegateTarget=n,i.$delegateTarget=new U(n),e(i)}}:function(i){if(r.checkEventType(i,t))return e(i)}}},{key:"addEvent",value:function(t,e){t.callback=this.makeCallback(t,e),this.addBinding(t),X.addEvent(t.dom,t.eventName,t.callback)}},{key:"removeEventAll",value:function(){var t=this;this.getBindings().forEach(function(e){t.removeEvent(e)}),this.initBindings()}},{key:"removeEvent",value:function(t){var e=t.eventName,r=t.dom,i=t.callback;X.removeEvent(r,e,i)}}]),t}(),Z=function(t){function e(t){v(this,e);var r=m(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return p(e,W),g(e,[{key:"initialize",value:function(){this.$el=new U("div","control"),this.$hue=this.$el.createChild("div","hue"),this.$opacity=this.$el.createChild("div","opacity"),this.$controlPattern=this.$el.createChild("div","empty"),this.$controlColor=this.$el.createChild("div","color"),this.$hueContainer=this.$hue.createChild("div","hue-container"),this.$drag_bar=this.$hueContainer.createChild("div","drag-bar"),this.drag_bar_pos={},this.$opacityContainer=this.$opacity.createChild("div","opacity-container"),this.$opacityColorBar=this.$opacityContainer.createChild("div","color-bar"),this.$opacity_drag_bar=this.$opacityContainer.createChild("div","drag-bar2"),this.opacity_drag_bar_pos={}}},{key:"setBackgroundColor",value:function(t){this.$controlColor.css("background-color",t)}},{key:"refresh",value:function(){this.setColorUI()}},{key:"setColorUI",value:function(){var t=this.state.get("$el.width")*this.colorpicker.currentS,e=this.state.get("$el.height")*(1-this.colorpicker.currentV);this.$drag_pointer.css({left:t+"px",top:e+"px"})}},{key:"setOpacityColorBar",value:function(t){var e=w.parse(t);e.a=0;var r=w.format(e,"rgb");e.a=1;var i=w.format(e,"rgb");this.$opacityColorBar.css("background","linear-gradient(to right, "+r+", "+i+")")}},{key:"setOpacity",value:function(t){var e,r=this.$opacityContainer.offset().left,i=r+this.state.get("$opacityContainer.width"),n=X.pos(t).clientX;e=ni?100:(n-r)/(i-r)*100;var o=this.state.get("$opacityContainer.width")*(e/100);this.$opacity_drag_bar.css({left:o-Math.ceil(this.state.get("$opacity_drag_bar.width")/2)+"px"}),this.opacity_drag_bar_pos={x:o},this.colorpicker.setCurrentA(this.caculateOpacity()),this.colorpicker.currentFormat(),this.colorpicker.setInputColor()}},{key:"setInputColor",value:function(){this.setBackgroundColor(this.colorpicker.getFormattedColor("rgb"));var t=this.colorpicker.convertRGB(),e=w.format(t,"rgb");this.setOpacityColorBar(e)}},{key:"setColorUI",value:function(){var t=this.state.get("$hueContainer.width")*(this.colorpicker.currentH/360);this.$drag_bar.css({left:t-7.5+"px"}),this.drag_bar_pos={x:t};var e=this.state.get("$opacityContainer.width")*(this.colorpicker.currentA||0);this.$opacity_drag_bar.css({left:e-7.5+"px"}),this.opacity_drag_bar_pos={x:e}}},{key:"caculateH",value:function(){return{h:(this.drag_bar_pos||{x:0}).x/this.state.get("$hueContainer.width")*360}}},{key:"caculateOpacity",value:function(){var t=this.opacity_drag_bar_pos||{x:0},e=Math.round(t.x/this.state.get("$opacityContainer.width")*100)/100;return isNaN(e)?1:e}},{key:"EventDocumentMouseMove",value:function(t){this.isHueDown&&this.setHueColor(t),this.isOpacityDown&&this.setOpacity(t)}},{key:"EventDocumentMouseUp",value:function(t){this.isHueDown=!1,this.isOpacityDown=!1}},{key:"setControlColor",value:function(t){this.$controlColor.css("background-color",t)}},{key:"setHueColor",value:function(t){var e,r=this.$hueContainer.offset().left,i=r+this.state.get("$hueContainer.width"),n=t?X.pos(t).clientX:r+(i-r)*(this.colorpicker.currentH/360);e=ni?100:(n-r)/(i-r)*100;var o=this.state.get("$hueContainer.width")*(e/100);this.$drag_bar.css({left:o-Math.ceil(this.state.get("$drag_bar.width")/2)+"px"}),this.drag_bar_pos={x:o};var a=_.checkHueColor(e/100);this.colorpicker.setBackgroundColor(a),this.colorpicker.setCurrentH(e/100*360),this.colorpicker.setInputColor()}},{key:"setOnlyHueColor",value:function(){var t,e=this.$hueContainer.offset().left,r=e+this.state.get("$hueContainer.width"),i=e+(r-e)*(this.colorpicker.currentH/360);t=ir?100:(i-e)/(r-e)*100;var n=this.state.get("$hueContainer.width")*(t/100);this.$drag_bar.css({left:n-Math.ceil(this.state.get("$drag_bar.width")/2)+"px"}),this.drag_bar_pos={x:n};var o=_.checkHueColor(t/100);this.colorpicker.setBackgroundColor(o),this.colorpicker.setCurrentH(t/100*360)}},{key:"mousedown $drag_bar",value:function(t){t.preventDefault(),this.isHueDown=!0}},{key:"mousedown $opacity_drag_bar",value:function(t){t.preventDefault(),this.isOpacityDown=!0}},{key:"mousedown $hueContainer",value:function(t){this.isHueDown=!0,this.setHueColor(t)}},{key:"mousedown $opacityContainer",value:function(t){this.isOpacityDown=!0,this.setOpacity(t)}}]),e}(),J=function(t){function e(t){v(this,e);var r=m(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return p(e,W),g(e,[{key:"initialize",value:function(){this.$el=new U("div","information hex"),this.$informationChange=this.$el.createChild("div","information-change"),this.$formatChangeButton=this.$informationChange.createChild("button","format-change-button arrow-button",{type:"button"}),this.$el.append(this.makeInputFieldHex()),this.$el.append(this.makeInputFieldRgb()),this.$el.append(this.makeInputFieldHsl()),this.format="hex"}},{key:"makeInputFieldHex",value:function(){var t=new U("div","information-item hex"),e=t.createChild("div","input-field hex");return this.$hexCode=e.createChild("input","input",{type:"text"}),e.createChild("div","title").html("HEX"),t}},{key:"makeInputFieldRgb",value:function(){var t=new U("div","information-item rgb"),e=t.createChild("div","input-field rgb-r");return this.$rgb_r=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("R"),e=t.createChild("div","input-field rgb-g"),this.$rgb_g=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("G"),e=t.createChild("div","input-field rgb-b"),this.$rgb_b=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("B"),e=t.createChild("div","input-field rgb-a"),this.$rgb_a=e.createChild("input","input",{type:"number",step:.01,min:0,max:1}),e.createChild("div","title").html("A"),t}},{key:"makeInputFieldHsl",value:function(){var t=new U("div","information-item hsl"),e=t.createChild("div","input-field hsl-h");return this.$hsl_h=e.createChild("input","input",{type:"number",step:1,min:0,max:360}),e.createChild("div","title").html("H"),e=t.createChild("div","input-field hsl-s"),this.$hsl_s=e.createChild("input","input",{type:"number",step:1,min:0,max:100}),e.createChild("div","postfix").html("%"),e.createChild("div","title").html("S"),e=t.createChild("div","input-field hsl-l"),this.$hsl_l=e.createChild("input","input",{type:"number",step:1,min:0,max:100}),e.createChild("div","postfix").html("%"),e.createChild("div","title").html("L"),e=t.createChild("div","input-field hsl-a"),this.$hsl_a=e.createChild("input","input",{type:"number",step:.01,min:0,max:1}),e.createChild("div","title").html("A"),t}},{key:"currentFormat",value:function(){var t=this.format||"hex";if(this.colorpicker.currentA<1&&"hex"==t){this.$el.removeClass(t),this.$el.addClass("rgb"),this.format="rgb",this.colorpicker.setInputColor()}}},{key:"setCurrentFormat",value:function(t){this.format=t,this.initFormat()}},{key:"initFormat",value:function(){var t=this.format||"hex";this.$el.removeClass("hex"),this.$el.removeClass("rgb"),this.$el.removeClass("hsl"),this.$el.addClass(t)}},{key:"nextFormat",value:function(){var t=this.format||"hex",e="hex";"hex"==t?e="rgb":"rgb"==t?e="hsl":"hsl"==t&&(e=1==this.colorpicker.currentA?"hex":"rgb"),this.$el.removeClass(t),this.$el.addClass(e),this.format=e,this.setInputColor(),this.colorpicker.changeInputColorAfterNextFormat()}},{key:"setRGBInput",value:function(t,e,r){this.$rgb_r.val(t),this.$rgb_g.val(e),this.$rgb_b.val(r),this.$rgb_a.val(this.colorpicker.currentA)}},{key:"setHSLInput",value:function(t,e,r){this.$hsl_h.val(t),this.$hsl_s.val(e),this.$hsl_l.val(r),this.$hsl_a.val(this.colorpicker.currentA)}},{key:"getHexFormat",value:function(){return w.format({r:this.$rgb_r.int(),g:this.$rgb_g.int(),b:this.$rgb_b.int()},"hex",this.colorpicker.opt.color)}},{key:"getRgbFormat",value:function(){return w.format({r:this.$rgb_r.int(),g:this.$rgb_g.int(),b:this.$rgb_b.int(),a:this.$rgb_a.float()},"rgb",this.colorpicker.opt.color)}},{key:"getHslFormat",value:function(){return w.format({h:this.$hsl_h.val(),s:this.$hsl_s.val(),l:this.$hsl_l.val(),a:this.$hsl_a.float()},"hsl",this.colorpicker.opt.color)}},{key:"convertRGB",value:function(){return this.colorpicker.convertRGB()}},{key:"convertHEX",value:function(){return this.colorpicker.convertHEX()}},{key:"convertHSL",value:function(){return this.colorpicker.convertHSL()}},{key:"getFormattedColor",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return"hex"==(t=t||this.getFormat())?this.$hexCode.val():"rgb"==t?this.getRgbFormat(e):"hsl"==t?this.getHslFormat(e):void 0}},{key:"getFormat",value:function(){return this.format||"hex"}},{key:"setInputColor",value:function(){var t=this.getFormat(),e=null;if("hex"==t){this.$hexCode.val(this.convertHEX());e=this.convertRGB();this.setRGBInput(e.r,e.g,e.b,e.a)}else if("rgb"==t){e=this.convertRGB();this.setRGBInput(e.r,e.g,e.b,e.a),this.$hexCode.val(this.convertHEX())}else if("hsl"==t){var r=this.convertHSL();this.setHSLInput(r.h,r.s,r.l,r.a)}}},{key:"checkNumberKey",value:function(t){return X.checkNumberKey(t)}},{key:"checkNotNumberKey",value:function(t){return!X.checkNumberKey(t)}},{key:"changeRgbColor",value:function(){this.colorpicker.changeInformationColor(this.getRgbFormat())}},{key:"changeHslColor",value:function(){this.colorpicker.changeInformationColor(this.getHslFormat())}},{key:"change $rgb_r",value:function(t){this.changeRgbColor()}},{key:"change $rgb_g",value:function(t){this.changeRgbColor()}},{key:"change $rgb_b",value:function(t){this.changeRgbColor()}},{key:"change $rgb_a",value:function(t){this.changeRgbColor()}},{key:"change $hsl_h",value:function(t){this.changeHslColor()}},{key:"change $hsl_s",value:function(t){this.changeHslColor()}},{key:"change $hsl_l",value:function(t){this.changeHslColor()}},{key:"change $hsl_a",value:function(t){this.changeHslColor()}},{key:"keydown $hexCode",value:function(t){if(t.which<65||t.which>70)return this.checkNumberKey(t)}},{key:"keyup $hexCode",value:function(t){var e=this.$hexCode.val();"#"==e.charAt(0)&&7==e.length&&(this.colorpicker.changeInformationColor(e),this.setInputColor())}},{key:"click $formatChangeButton",value:function(t){this.nextFormat()}},{key:"refresh",value:function(){}}]),e}(),Q=function(t){function e(t){v(this,e);var r=m(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return p(e,W),g(e,[{key:"initialize",value:function(){this.$el=new U("div","color"),this.$saturation=this.$el.createChild("div","saturation"),this.$value=this.$saturation.createChild("div","value"),this.$drag_pointer=this.$value.createChild("div","drag-pointer")}},{key:"setBackgroundColor",value:function(t){this.$el.css("background-color",t)}},{key:"refresh",value:function(){this.setColorUI()}},{key:"caculateSV",value:function(){var t=this.drag_pointer_pos||{x:0,y:0},e=this.state.get("$el.width"),r=this.state.get("$el.height");return{s:t.x/e,v:(r-t.y)/r,width:e,height:r}}},{key:"setColorUI",value:function(){var t=this.state.get("$el.width")*this.colorpicker.currentS,e=this.state.get("$el.height")*(1-this.colorpicker.currentV);this.$drag_pointer.css({left:t-5+"px",top:e-5+"px"}),this.drag_pointer_pos={x:t,y:e}}},{key:"setMainColor",value:function(t){t.preventDefault();var e=this.$el.position(),r=this.state.get("$el.contentWidth"),i=this.state.get("$el.contentHeight"),n=t.clientX-e.left,o=t.clientY-e.top;n<0?n=0:n>r&&(n=r),o<0?o=0:o>i&&(o=i),this.$drag_pointer.css({left:n-5+"px",top:o-5+"px"}),this.drag_pointer_pos={x:n,y:o},this.colorpicker.caculateHSV(),this.colorpicker.setInputColor()}},{key:"EventDocumentMouseUp",value:function(t){this.isDown=!1}},{key:"EventDocumentMouseMove",value:function(t){this.isDown&&this.setMainColor(t)}},{key:"mousedown",value:function(t){this.isDown=!0,this.setMainColor(t)}},{key:"mouseup",value:function(t){this.isDown=!1}}]),e}(),tt="data-colorsets-index",et=function(t){function e(t){v(this,e);var r=m(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return p(e,W),g(e,[{key:"initialize",value:function(){this.$el=new U("div","color-chooser");var t=this.$el.createChild("div","color-chooser-container"),e=t.createChild("div","colorsets-item colorsets-item-header");e.createChild("h1","title").html("Color Paletts"),this.$toggleButton=e.createChild("span","items").html("×"),this.$colorsetsList=t.createChild("div","colorsets-list"),this.refresh()}},{key:"refresh",value:function(){this.$colorsetsList.html(this.makeColorSetsList())}},{key:"makeColorItemList",value:function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5,r=new U("div"),i=0;i1&&void 0!==arguments[1]&&arguments[1];if("object"==(void 0===t?"undefined":f(t))){if(!t.r||!t.g||!t.b)return;e?this.callbackColorValue(w.format(t,"hex")):this.initColor(w.format(t,"hex"))}else"string"==typeof t&&(e?this.callbackColorValue(t):this.initColor(t))}},{key:"getColor",value:function(t){this.caculateHSV();var e=this.convertRGB();return t?w.format(e,t):e}},{key:"definePositionForArrow",value:function(t,e,r){}},{key:"definePosition",value:function(t){var e=this.$root.width(),r=this.$root.height(),i=t.left-this.$body.scrollLeft();e+i>window.innerWidth&&(i-=e+i-window.innerWidth),i<0&&(i=0);var n=t.top-this.$body.scrollTop();r+n>window.innerHeight&&(n-=r+n-window.innerHeight),n<0&&(n=0),this.$root.css({left:i+"px",top:n+"px"})}},{key:"getInitalizePosition",value:function(){return"inline"==this.opt.position?{position:"relative",left:"auto",top:"auto",display:"inline-block"}:{position:"fixed",left:"-10000px",top:"-10000px"}}},{key:"show",value:function(t,e,r){this.destroy(),this.initializeEvent(),this.$root.appendTo(this.$body),this.$root.css(this.getInitalizePosition()).show(),this.definePosition(t),this.isColorPickerShow=!0,this.isShortCut=t.isShortCut||!1,this.initColor(e),this.colorpickerCallback=r,this.hideDelay=t.hideDelay||2e3,this.hideDelay>0&&this.setHideDelay(this.hideDelay)}},{key:"setHideDelay",value:function(t){var e=this;t=t||0,this.$root.off("mouseenter"),this.$root.off("mouseleave"),this.$root.on("mouseenter",function(){clearTimeout(e.timerCloseColorPicker)}),this.$root.on("mouseleave",function(){clearTimeout(e.timerCloseColorPicker),e.timerCloseColorPicker=setTimeout(e.hide.bind(e),t)}),clearTimeout(this.timerCloseColorPicker),this.timerCloseColorPicker=setTimeout(this.hide.bind(this),t)}},{key:"hide",value:function(){this.isColorPickerShow&&(this.destroy(),this.$root.hide(),this.$root.remove(),this.isColorPickerShow=!1)}},{key:"convertRGB",value:function(){return w.HSVtoRGB(this.currentH,this.currentS,this.currentV)}},{key:"convertHEX",value:function(){return w.format(this.convertRGB(),"hex")}},{key:"convertHSL",value:function(){return w.HSVtoHSL(this.currentH,this.currentS,this.currentV)}},{key:"getCurrentColor",value:function(){return this.information.getFormattedColor()}},{key:"getFormattedColor",value:function(t){if("rgb"==(t=t||"hex"))return(r=this.convertRGB()).a=this.currentA,w.format(r,"rgb");if("hsl"==t){var e=this.convertHSL();return e.a=this.currentA,w.format(e,"hsl")}var r=this.convertRGB();return w.format(r,"hex")}},{key:"setInputColor",value:function(t){this.information.setInputColor(t),this.control.setInputColor(t),this.callbackColorValue()}},{key:"changeInputColorAfterNextFormat",value:function(){this.control.setInputColor(),this.callbackColorValue()}},{key:"callbackColorValue",value:function(t){t=t||this.getCurrentColor(),isNaN(this.currentA)||("function"==typeof this.opt.onChange&&this.opt.onChange.call(this,t),"function"==typeof this.colorpickerCallback&&this.colorpickerCallback(t))}},{key:"caculateHSV",value:function(){var t=this.palette.caculateSV(),e=this.control.caculateH(),r=t.s,i=t.v,n=e.h;0==t.width&&(n=0,r=0,i=0),this.currentH=n,this.currentS=r,this.currentV=i}},{key:"setColorUI",value:function(){this.control.setColorUI(),this.palette.setColorUI()}},{key:"setCurrentHSV",value:function(t,e,r,i){this.currentA=i,this.currentH=t,this.currentS=e,this.currentV=r}},{key:"setCurrentH",value:function(t){this.currentH=t}},{key:"setCurrentA",value:function(t){this.currentA=t}},{key:"setBackgroundColor",value:function(t){this.palette.setBackgroundColor(t)}},{key:"setCurrentFormat",value:function(t){this.format=t,this.information.setCurrentFormat(t)}},{key:"getHSV",value:function(t){return"hsl"==t.type?w.HSLtoHSV(t):w.RGBtoHSV(t)}},{key:"initColor",value:function(t,e){var r=t||"#FF0000",i=w.parse(r);e=e||i.type,this.setCurrentFormat(e);var n=this.getHSV(i);this.setCurrentHSV(n.h,n.s,n.v,i.a),this.setColorUI(),this.setHueColor(),this.setInputColor()}},{key:"changeInformationColor",value:function(t){var e=t||"#FF0000",r=w.parse(e),i=this.getHSV(r);this.setCurrentHSV(i.h,i.s,i.v,r.a),this.setColorUI(),this.setHueColor(),this.control.setInputColor(),this.callbackColorValue()}},{key:"setHueColor",value:function(){this.control.setOnlyHueColor()}},{key:"checkColorPickerClass",value:function(t){var e=new U(t).closest("codemirror-colorview"),r=new U(t).closest("codemirror-colorpicker"),i=new U(t).closest("CodeMirror");t.nodeName;return!!(r||e||i)}},{key:"checkInHtml",value:function(t){return"HTML"==t.nodeName}},{key:"mouseup document",value:function(t){this.palette.EventDocumentMouseUp(t),this.control.EventDocumentMouseUp(t),this.checkInHtml(t.target)||0==this.checkColorPickerClass(t.target)&&this.hide()}},{key:"mousemove document",value:function(t){this.palette.EventDocumentMouseMove(t),this.control.EventDocumentMouseMove(t)}},{key:"initializeEvent",value:function(){this.initializeEventMachin(),this.palette.initializeEvent(),this.control.initializeEvent(),this.information.initializeEvent(),this.currentColorSets.initializeEvent(),this.colorSetsChooser.initializeEvent(),this.contextMenu.initializeEvent()}},{key:"currentFormat",value:function(){this.information.currentFormat()}},{key:"toggleColorChooser",value:function(){this.colorSetsChooser.toggle()}},{key:"refreshColorSetsChooser",value:function(){this.colorSetsChooser.refresh()}},{key:"getColorSetsList",value:function(){return this.colorSetsList.getColorSetsList()}},{key:"setCurrentColorSets",value:function(t){this.colorSetsList.setCurrentColorSets(t),this.currentColorSets.refresh()}},{key:"setColorSets",value:function(t){this.colorSetsList.setUserList(t)}},{key:"destroy",value:function(){d(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"destroy",this).call(this),this.control.destroy(),this.palette.destroy(),this.information.destroy(),this.colorSetsChooser.destroy(),this.colorSetsList.destroy(),this.currentColorSets.destroy(),this.contextMenu.destroy(),this.colorpickerCallback=void 0}}]),e}(),st="codemirror-colorview",lt="codemirror-colorview-background",ct=["comment"];function ht(t,e){"setValue"==e.origin?(t.state.colorpicker.close_color_picker(),t.state.colorpicker.init_color_update(),t.state.colorpicker.style_color_update()):t.state.colorpicker.style_color_update(t.getCursor().line)}function ut(t,e){t.state.colorpicker.isUpdate||(t.state.colorpicker.isUpdate=!0,t.state.colorpicker.close_color_picker(),t.state.colorpicker.init_color_update(),t.state.colorpicker.style_color_update())}function ft(t,e){ht(t,{origin:"setValue"})}function vt(t,e){t.state.colorpicker.keyup(e)}function gt(t,e){t.state.colorpicker.is_edit_mode()&&t.state.colorpicker.check_mousedown(e)}function dt(t,e){ht(t,{origin:"setValue"})}function pt(t){t.state.colorpicker.close_color_picker()}var mt=function(){function t(e,r){v(this,t),r="boolean"==typeof r?{mode:"edit"}:Object.assign({mode:"edit"},r||{}),this.opt=r,this.cm=e,this.markers={},this.excluded_token=this.opt.excluded_token||ct,this.opt.colorpicker?this.colorpicker=this.opt.colorpicker(this.opt):this.colorpicker=new at(this.opt),this.init_event()}return g(t,[{key:"init_event",value:function(){var t,e,r,i,n;this.cm.on("mousedown",gt),this.cm.on("keyup",vt),this.cm.on("change",ht),this.cm.on("update",ut),this.cm.on("refresh",ft),this.onPasteCallback=(t=this.cm,e=dt,function(r){e.call(this,t,r)}),this.cm.getWrapperElement().addEventListener("paste",this.onPasteCallback),this.is_edit_mode()&&this.cm.on("scroll",(r=pt,i=50,n=void 0,function(t,e){n&&clearTimeout(n),n=setTimeout(function(){r(t,e)},i||300)}))}},{key:"is_edit_mode",value:function(){return"edit"==this.opt.mode}},{key:"is_view_mode",value:function(){return"view"==this.opt.mode}},{key:"destroy",value:function(){this.cm.off("mousedown",gt),this.cm.off("keyup",vt),this.cm.off("change",ht),this.cm.getWrapperElement().removeEventListener("paste",this.onPasteCallback),this.is_edit_mode()&&this.cm.off("scroll")}},{key:"hasClass",value:function(t,e){return!!t.className&&(" "+t.className+" ").indexOf(" "+e+" ")>-1}},{key:"check_mousedown",value:function(t){this.hasClass(t.target,lt)?this.open_color_picker(t.target.parentNode):this.close_color_picker()}},{key:"popup_color_picker",value:function(t){var e=this.cm.getCursor(),r=this,i={lineNo:e.line,ch:e.ch,color:t||"#FFFFFF",isShortCut:!0};Object.keys(this.markers).forEach(function(t){if(("#"+t).indexOf("#"+i.lineNo+":")>-1){var e=r.markers[t];e.ch<=i.ch&&i.ch<=e.ch+e.color.length&&(i.ch=e.ch,i.color=e.color,i.nameColor=e.nameColor)}}),this.open_color_picker(i)}},{key:"open_color_picker",value:function(t){var e=t.lineNo,r=t.ch,i=t.nameColor,n=t.color;if(this.colorpicker){var o=this,a=n,s=this.cm.charCoords({line:e,ch:r});this.colorpicker.show({left:s.left,top:s.bottom,isShortCut:t.isShortCut||!1,hideDelay:o.opt.hideDelay||2e3},i||n,function(t){o.cm.replaceRange(t,{line:e,ch:r},{line:e,ch:r+a.length},"*colorpicker"),a=t})}}},{key:"close_color_picker",value:function(t){this.colorpicker&&this.colorpicker.hide()}},{key:"key",value:function(t,e){return[t,e].join(":")}},{key:"keyup",value:function(t){this.colorpicker&&("Escape"==t.key?this.colorpicker.hide():0==this.colorpicker.isShortCut&&this.colorpicker.hide())}},{key:"init_color_update",value:function(){this.markers={}}},{key:"style_color_update",value:function(t){if(t)this.match(t);else for(var e=this.cm.lineCount(),r=0;r-1)&&(delete this.markers[s],n[o].marker.clear())}}},{key:"match_result",value:function(t){return w.matches(t.text)}},{key:"submatch",value:function(t,e){var r=this;this.empty_marker(t,e);var i={next:0};this.match_result(e).forEach(function(n){r.render(i,t,e,n.color,n.nameColor)})}},{key:"match",value:function(t){var e=this.cm.getLineHandle(t),r=this;this.cm.operation(function(){r.submatch(t,e)})}},{key:"make_element",value:function(){var t=document.createElement("div");return t.className=st,this.is_edit_mode()?t.title="open color picker":t.title="",t.back_element=this.make_background_element(),t.appendChild(t.back_element),t}},{key:"make_background_element",value:function(){var t=document.createElement("div");return t.className=lt,t}},{key:"set_state",value:function(t,e,r,i){var n=this.create_marker(t,e);return n.lineNo=t,n.ch=e,n.color=r,n.nameColor=i,n}},{key:"create_marker",value:function(t,e){var r=this.key(t,e);return this.markers[r]||(this.markers[r]=this.make_element()),this.markers[r]}},{key:"has_marker",value:function(t,e){var r=this.key(t,e);return!!this.markers[r]}},{key:"update_element",value:function(t,e){t.back_element.style.backgroundColor=e}},{key:"set_mark",value:function(t,e,r){this.cm.setBookmark({line:t,ch:e},{widget:r,handleMouseEvents:!0})}},{key:"is_excluded_token",value:function(t,e){for(var r=this.cm.getTokenTypeAt({line:t,ch:e}),i=0,n=0,o=this.excluded_token.length;n0}},{key:"render",value:function(t,e,r,i,n){var o=r.text.indexOf(i,t.next);if(!0!==this.is_excluded_token(e,o)){if(t.next=o+i.length,this.has_marker(e,o))return this.update_element(this.create_marker(e,o),n||i),void this.set_state(e,o,i,n);var a=this.create_marker(e,o);this.update_element(a,n||i),this.set_state(e,o,i,n||i),this.set_mark(e,o,a)}}}]),t}();return t&&t.defineOption("colorpicker",!1,function(e,r,i){i&&i!=t.Init&&e.state.colorpicker&&(e.state.colorpicker.destroy(),e.state.colorpicker=null),r&&(e.state.colorpicker=new mt(e,r))}),{Color:w,ColorNames:r,ColorPicker:at,ImageFilter:F,HueColor:_,Canvas:u,ImageLoader:k}}(CodeMirror); +var CodeMirrorColorPicker=function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb(0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb(0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb(0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb(95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(237, 20, 61)",cyan:"rgb(0, 255, 255)",darkblue:"rgb(0, 0, 139)",darkcyan:"rgb(0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgrey:"rgb(169, 169, 169)",darkgreen:"rgb(0, 100, 0)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb(85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb(72, 61, 139)",darkslategray:"rgb(47, 79, 79)",darkslategrey:"rgb(47, 79, 79)",darkturquoise:"rgb(0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb(0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb(30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb(34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb(75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgreen:"rgb(144, 238, 144)",lightgray:"rgb(211, 211, 211)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb(32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb(0, 255, 0)",limegreen:"rgb(50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb(0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb(60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb(0, 250, 154)",mediumturquoise:"rgb(72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb(25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb(0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",rebeccapurple:"rgb(102, 51, 153)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb(65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb(46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb(0, 255, 127)",steelblue:"rgb(70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb(0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb(64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)",transparent:"rgba(0, 0, 0, 0)"};var r={isColorName:function(t){return!!e[t]},getColorByName:function(t){return e[t]}};function i(t,e){if(t.length!==e.length)return!1;for(var r=0,i=t.length;r0)u=s(h);else u=e[Math.floor(a()*e.length)];o=!i(u,c),n[l]=u}return o}function c(t,e,r){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:10,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"linear";t=t,e=e||Math.max(2,Math.ceil(Math.sqrt(t.length/2)));var s=r||"euclidean";"string"==typeof s&&(s=n[s]);for(var c=0,u=function(){return(c=(9301*c+49297)%233280)/233280},f=function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"linear";return o[r](t.length,e).map(function(e){return t[e]})}(t,e,a),v=!0,g=0;v;){if(v=h(e,t,l(e,t,f,s),f,!1,u),++g%i==0)break}return f}var u={create:function(t,e){var r=document.createElement("canvas");return r.width=t||0,r.height=e||0,r},drawPixels:function(t){var e=this.create(t.width,t.height),r=e.getContext("2d"),i=r.getImageData(0,0,e.width,e.height);return i.data.set(t.pixels),r.putImageData(i,0,0),e},createHistogram:function(t,e,r,i){var n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{black:!0,red:!1,green:!1,blue:!1},o=this.create(t,e),a=o.getContext("2d");a.clearRect(0,0,t,e),a.fillStyle="white",a.fillRect(0,0,t,e),a.globalAlpha=.7;var s={black:!1};n.black?s.black=!1:s.black=!0,n.red?s.red=!1:s.red=!0,n.green?s.green=!1:s.green=!0,n.blue?s.blue=!1:s.blue=!0,Object.keys(r).forEach(function(i){if(!s[i]){var n=r[i],o=Math.max.apply(Math,n),l=t/n.length;a.fillStyle=i,n.forEach(function(t,r){var i=e*(t/o),n=r*l;a.fillRect(n,e-i,l,i)})}}),"function"==typeof i&&i(o)},getHistogram:function(t){for(var e,r,i=new Array(256),n=new Array(256),o=new Array(256),a=new Array(256),s=0;s<256;s++)i[s]=0,n[s]=0,o[s]=0,a[s]=0;return r=function(t,e){var r=Math.round(x.brightness(t[e],t[e+1],t[e+2]));i[r]++,n[t[e]]++,o[t[e+1]]++,a[t[e+2]]++},function(t,e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{};v(this,t),this.isLoaded=!1,this.imageUrl=e,this.opt=r,this.initialize()}return g(t,[{key:"initialize",value:function(){this.canvas=this.createCanvas(),this.context=this.canvas.getContext("2d")}},{key:"createCanvas",value:function(){return document.createElement("canvas")}},{key:"load",value:function(t){this.loadImage(t)}},{key:"loadImage",value:function(t){var e=this,r=this.context,i=new Image;i.onload=function(){var n=i.height/i.width;e.opt.canvasWidth&&e.opt.canvasHeight?(e.canvas.width=e.opt.canvasWidth,e.canvas.height=e.opt.canvasHeight):(e.canvas.width=e.opt.maxWidth?e.opt.maxWidth:i.width,e.canvas.height=e.canvas.width*n),r.drawImage(i,0,0,i.width,i.height,0,0,e.canvas.width,e.canvas.height),e.isLoaded=!0,t&&t()},this.getImageUrl(function(t){i.src=t})}},{key:"getImageUrl",value:function(t){if("string"==typeof this.imageUrl)return t(this.imageUrl);if(this.imageUrl instanceof Blob){var e=new FileReader;e.onload=function(e){t(e.target.result)},e.readAsDataURL(this.imageUrl)}}},{key:"getRGBA",value:function(t,e,r,i){return[t,e,r,i]}},{key:"toArray",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=this.context.getImageData(0,0,this.canvas.width,this.canvas.height),i=r.width,n=r.height,o={pixels:new Uint8ClampedArray(r.data),width:i,height:n};return t&&(o=t(o)),u.drawPixels(o).toDataURL(e.outputFormat||"image/png")}},{key:"toHistogram",value:function(t){var e=this.context.getImageData(0,0,this.canvas.width,this.canvas.height),r=e.width,i=e.height,n={pixels:new Uint8ClampedArray(e.data),width:r,height:i};return u.getHistogram(n)}},{key:"toRGB",value:function(){for(var t=this.context.getImageData(0,0,this.canvas.width,this.canvas.height).data,e=[],r=0,i=t.length;r-1||e[n].indexOf("rgb")>-1||e[n].indexOf("hsl")>-1)i.push({color:e[n]});else{var a=r.getColorByName(e[n]);a&&i.push({color:e[n],nameColor:a})}var s={next:0};return i.forEach(function(e){var r=t.indexOf(e.color,s.next);e.startIndex=r,e.endIndex=r+e.color.length,s.next=e.endIndex}),i},convertMatches:function(t){var e=this.matches(t);return e.forEach(function(e,r){t=t.replace(e.color,"@"+r)}),{str:t,matches:e}},convertMatchesArray:function(t){var e=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:",",i=this.convertMatches(t);return i.str.split(r).map(function(t,r){return t=e.trim(t),i.matches[r]&&(t=t.replace("@"+r,i.matches[r].color)),t})},reverseMatches:function(t,e){return e.forEach(function(e,r){t=t.replace("@"+r,e.color)}),t},trim:function(t){return t.replace(/^\s+|\s+$/g,"")},round:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return Math.round(t*e)/e},format:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgba(0, 0, 0, 0)";return Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),"hex"==e?this.hex(t):"rgb"==e?this.rgb(t,r):"hsl"==e?this.hsl(t):t},hex:function(t){Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]});var e=t.r.toString(16);t.r<16&&(e="0"+e);var r=t.g.toString(16);t.g<16&&(r="0"+r);var i=t.b.toString(16);return t.b<16&&(i="0"+i),"#"+e+r+i},rgb:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"rgba(0, 0, 0, 0)";if(Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),void 0!==t)return 1==t.a||void 0===t.a?isNaN(t.r)?e:"rgb("+t.r+","+t.g+","+t.b+")":"rgba("+t.r+","+t.g+","+t.b+","+t.a+")"},hsl:function(t){return Array.isArray(t)&&(t={r:t[0],g:t[1],b:t[2],a:t[3]}),1==t.a||void 0===t.a?"hsl("+t.h+","+t.s+"%,"+t.l+"%)":"hsla("+t.h+","+t.s+"%,"+t.l+"%,"+t.a+")"},parse:function(t){if("string"==typeof t){if(r.isColorName(t)&&(t=r.getColorByName(t)),t.indexOf("rgb(")>-1){for(var e=0,i=(o=t.replace("rgb(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("rgba(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("hsl(","").replace(")","").split(",")).length;e-1){for(e=0,i=(o=t.replace("hsla(","").replace(")","").split(",")).length;e>16,g:(65280&t)>>8,b:(255&t)>>0,a:1};return n=Object.assign(n,this.RGBtoHSL(n))}if(0<=t&&t<=4294967295){n={type:"hex",r:(4278190080&t)>>24,g:(16711680&t)>>16,b:(65280&t)>>8,a:(255&t)/255};return n=Object.assign(n,this.RGBtoHSL(n))}}return t},HSVtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.v}var n=t,o=r;360==n&&(n=0);var a=e*o,s=a*(1-Math.abs(n/60%2-1)),l=o-a,h=[];return 0<=n&&n<60?h=[a,s,0]:60<=n&&n<120?h=[s,a,0]:120<=n&&n<180?h=[0,a,s]:180<=n&&n<240?h=[0,s,a]:240<=n&&n<300?h=[s,0,a]:300<=n&&n<360&&(h=[a,0,s]),{r:this.round(255*(h[0]+l)),g:this.round(255*(h[1]+l)),b:this.round(255*(h[2]+l))}},RGBtoHSV:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255,s=Math.max(n,o,a),l=s-Math.min(n,o,a),h=0;0==l?h=0:s==n?h=(o-a)/l%6*60:s==o?h=60*((a-n)/l+2):s==a&&(h=60*((n-o)/l+4)),h<0&&(h=360+h);return{h:h,s:0==s?0:l/s,v:s}},HSVtoHSL:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.v}var n=this.HSVtoRGB(t,e,r);return this.RGBtoHSL(n.r,n.g,n.b)},RGBtoCMYK:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255,s=1-Math.max(n,o,a);return{c:(1-n-s)/(1-s),m:(1-o-s)/(1-s),y:(1-a-s)/(1-s),k:s}},CMYKtoRGB:function(t,e,r,i){if(1==arguments.length){var n=arguments[0];t=n.c,e=n.m,r=n.y,i=n.k}return{r:255*(1-t)*(1-i),g:255*(1-e)*(1-i),b:255*(1-r)*(1-i)}},RGBtoHSL:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}t/=255,e/=255,r/=255;var n,o,a=Math.max(t,e,r),s=Math.min(t,e,r),l=(a+s)/2;if(a==s)n=o=0;else{var h=a-s;switch(o=l>.5?h/(2-a-s):h/(a+s),a){case t:n=(e-r)/h+(e1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t},HSLtoHSV:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,i.v}var n=this.HSLtoRGB(t,e,r);return this.RGBtoHSV(n.r,n.g,n.b)},HSLtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.h,e=i.s,r=i.l}var n,o,a;if(t/=360,r/=100,0==(e/=100))n=o=a=r;else{var s=r<.5?r*(1+e):r+e-r*e,l=2*r-s;n=this.HUEtoRGB(l,s,t+1/3),o=this.HUEtoRGB(l,s,t),a=this.HUEtoRGB(l,s,t-1/3)}return{r:this.round(255*n),g:this.round(255*o),b:this.round(255*a)}},c:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray((t+e+r)/3>90?0:255)},gray:function(t){return{r:t,g:t,b:t}},RGBtoSimpleGray:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray(Math.ceil((t+e+r)/3))},RGBtoGray:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.gray(this.RGBtoYCrCb(t,e,r).y)},brightness:function(t,e,r){return Math.ceil(.2126*t+.7152*e+.0722*r)},RGBtoYCrCb:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=this.brightness(t,e,r);return{y:n,cr:.713*(t-n),cb:.564*(r-n)}},YCrCbtoRGB:function(t,e,r,i){if(1==arguments.length){var n=arguments[0];t=n.y,e=n.cr,r=n.cb;i=(i=n.bit)||0}var o=t+1.402*(e-i),a=t-.344*(r-i)-.714*(e-i),s=t+1.772*(r-i);return{r:Math.ceil(o),g:Math.ceil(a),b:Math.ceil(s)}},ReverseRGB:function(t){return t>.0031308?1.055*Math.pow(t,1/2.4)-.055:12.92*t},XYZtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.x,e=i.y,r=i.z}var n=t/100,o=e/100,a=r/100,s=3.2406*n+-1.5372*o+-.4986*a,l=-.9689*n+1.8758*o+.0415*a,h=.0557*n+-.204*o+1.057*a;return s=this.ReverseRGB(s),l=this.ReverseRGB(l),h=this.ReverseRGB(h),{r:this.round(255*s),g:this.round(255*l),b:this.round(255*h)}},PivotRGB:function(t){return 100*(t>.04045?Math.pow((t+.055)/1.055,2.4):t/12.92)},RGBtoXYZ:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}var n=t/255,o=e/255,a=r/255;return{x:.4124*(n=this.PivotRGB(n))+.3576*(o=this.PivotRGB(o))+.1805*(a=this.PivotRGB(a)),y:.2126*n+.7152*o+.0722*a,z:.0193*n+.1192*o+.9505*a}},ReverseXyz:function(t){return Math.pow(t,3)>.008856?Math.pow(t,3):(t-16/116)/7.787},LABtoXYZ:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.l,e=i.a,r=i.b}var n=(t+16)/116,o=e/500+n,a=n-r/200;return n=this.ReverseXyz(n),{x:95.047*(o=this.ReverseXyz(o)),y:100*n,z:108.883*(a=this.ReverseXyz(a))}},PivotXyz:function(t){return t>.008856?Math.pow(t,1/3):(7.787*t+16)/116},XYZtoLAB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.x,e=i.y,r=i.z}var n=t/95.047,o=e/100,a=r/108.883;return n=this.PivotXyz(n),{l:116*(o=this.PivotXyz(o))-16,a:500*(n-o),b:200*(o-(a=this.PivotXyz(a)))}},RGBtoLAB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.r,e=i.g,r=i.b}return this.XYZtoLAB(this.RGBtoXYZ(t,e,r))},LABtoRGB:function(t,e,r){if(1==arguments.length){var i=arguments[0];t=i.l,e=i.a,r=i.b}return this.XYZtoRGB(this.LABtoXYZ(t,e,r))},blend:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex",n=this.parse(t),o=this.parse(e);return this.interpolateRGB(n,o,r,i)},mix:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex";return this.blend(t,e,r,i)},contrast:function(t){t=this.parse(t);var e=(Math.round(299*t.r)+Math.round(587*t.g)+Math.round(114*t.b))/1e3;return e},contrastColor:function(t){return this.contrast(t)>=128?"black":"white"},interpolateRGB:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hex",n={r:this.round(t.r+(e.r-t.r)*r),g:this.round(t.g+(e.g-t.g)*r),b:this.round(t.b+(e.b-t.b)*r),a:this.round(t.a+(e.a-t.a)*r,100)};return this.format(n,n.a<1?"rgb":i)},scale:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5;if(!t)return[];"string"==typeof t&&(t=this.convertMatchesArray(t));for(var r=(t=t||[]).length,i=[],n=0;n0){var i=(1-t.filter(function(t){return"*"!=t[1]&&1!=t[1]}).map(function(t){return t[1]}).reduce(function(t,e){return t+e},0))/r;t.forEach(function(e,r){"*"==e[1]&&r>0&&(t.length-1==r||(e[1]=i))})}return t},gradient:function(t){for(var e=[],r=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:10)-((t=this.parseGradient(t)).length-1),i=r,n=1,o=t.length;n1&&void 0!==arguments[1]?arguments[1]:"h",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:9,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"rgb",n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1,a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:100,s=this.parse(t),l=this.RGBtoHSV(s),h=(o-n)*a/r,c=[],u=1;u<=r;u++)l[e]=Math.abs((a-h*u)/a),c.push(this.format(this.HSVtoRGB(l),i));return c},scaleH:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:360;return this.scaleHSV(t,"h",e,r,i,n,1)},scaleS:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;return this.scaleHSV(t,"s",e,r,i,n,100)},scaleV:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:9,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"rgb",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;return this.scaleHSV(t,"v",e,r,i,n,100)},palette:function(t){var e=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"hex";return t.length>r&&(t=c(t,r)),t.map(function(t){return e.format(t,i)})},ImageToRGB:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments[2];if(r){if(r){var i;(i=new C(t,e)).loadImage(function(){"function"==typeof r&&r(i.toRGB())})}}else(i=new C(t)).loadImage(function(){"function"==typeof e&&e(i.toRGB())})},ImageToURL:function(t,e,r){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},n=new C(t);n.loadImage(function(){"function"==typeof r&&r(n.toArray(e,i))})},histogram:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=new C(t);i.loadImage(function(){"function"==typeof e&&e(i.toHistogram(r))})},ImageToHistogram:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{width:200,height:100},i=new C(t);i.loadImage(function(){u.createHistogram(r.width||200,r.height||100,i.toHistogram(r),function(t){"function"==typeof e&&e(t.toDataURL("image/png"))},r)})}};x.scale.parula=function(t){return x.scale(["#352a87","#0f5cdd","#00b5a6","#ffc337","#fdff00"],t)},x.scale.jet=function(t){return x.scale(["#00008f","#0020ff","#00ffff","#51ff77","#fdff00","#ff0000","#800000"],t)},x.scale.hsv=function(t){return x.scale(["#ff0000","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff","#ff0000"],t)},x.scale.hot=function(t){return x.scale(["#0b0000","#ff0000","#ffff00","#ffffff"],t)},x.scale.pink=function(t){return x.scale(["#1e0000","#bd7b7b","#e7e5b2","#ffffff"],t)},x.scale.bone=function(t){return x.scale(["#000000","#4a4a68","#a6c6c6","#ffffff"],t)},x.scale.copper=function(t){return x.scale(["#000000","#3d2618","#9d623e","#ffa167","#ffc77f"],t)};var _=[{rgb:"#ff0000",start:0},{rgb:"#ffff00",start:.17},{rgb:"#00ff00",start:.33},{rgb:"#00ffff",start:.5},{rgb:"#0000ff",start:.67},{rgb:"#ff00ff",start:.83},{rgb:"#ff0000",start:1}];!function(){for(var t=0,e=_.length;t=t){e=_[i-1],r=_[i];break}return e&&r?x.interpolateRGB(e,r,(t-e.start)/(r.start-e.start)):_[0].rgb}},S={identity:function(){return[1,0,0,0,1,0,0,0,1]},stretching:function(t){return[t,0,0,0,1,0,0,0,1]},squeezing:function(t){return[t,0,0,0,1/t,0,0,0,1]},scale:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return[t=t||0===t?t:1,0,0,0,e=e||0===e?e:1,0,0,0,1]},scaleX:function(t){return this.scale(t)},scaleY:function(t){return this.scale(1,t)},translate:function(t,e){return[1,0,t,0,1,e,0,0,1]},rotate:function(t){var e=this.radian(t);return[Math.cos(e),-Math.sin(e),0,Math.sin(e),Math.cos(e),0,0,0,1]},rotate90:function(){return[0,-1,0,1,0,0,0,0,1]},rotate180:function(){return[-1,0,0,0,-1,0,0,0,1]},rotate270:function(){return[0,1,0,-1,0,0,0,0,1]},radian:function(t){return t*Math.PI/180},skew:function(t,e){var r=this.radian(t),i=this.radian(e);return[1,Math.tan(r),0,Math.tan(i),1,0,0,0,1]},skewX:function(t){var e=this.radian(t);return[1,Math.tan(e),0,0,1,0,0,0,1]},skewY:function(t){var e=this.radian(t);return[1,0,0,Math.tan(e),1,0,0,0,1]},shear1:function(t){return[1,-Math.tan(this.radian(t)/2),0,0,1,0,0,0,1]},shear2:function(t){return[1,0,0,Math.sin(this.radian(t)),1,0,0,0,1]}},M={CONSTANT:S,radian:function(t){return S.radian(t)},multiply:function(t,e){return[t[0]*e[0]+t[1]*e[1]+t[2]*e[2],t[3]*e[0]+t[4]*e[1]+t[5]*e[2],t[6]*e[0]+t[7]*e[1]+t[8]*e[2]]},identity:function(t){return this.multiply(S.identity(),t)},translate:function(t,e,r){return this.multiply(S.translate(t,e),r)},rotate:function(t,e){return this.multiply(S.rotate(t),e)},shear1:function(t,e){return this.multiply(S.shear1(t),e)},shear2:function(t,e){return this.multiply(S.shear2(t),e)},rotateShear:function(t,e){var r=e;return r=this.shear1(t,r),r=this.shear2(t,r),r=this.shear1(t,r)}};function H(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return t.map(function(t){return t*e})}function B(t,e,r){var i=t[e],n=t[e+1],o=t[e+2],a=t[e+3];t[e]=r[0]*i+r[1]*n+r[2]*o+r[3]*a,t[e+1]=r[4]*i+r[5]*n+r[6]*o+r[7]*a,t[e+2]=r[8]*i+r[9]*n+r[10]*o+r[11]*a,t[e+3]=r[12]*i+r[13]*n+r[14]*o+r[15]*a}function R(t,e,r){return{pixels:new Uint8ClampedArray(t),width:e,height:r}}function E(t){return"string"==typeof t&&(t=(t=t.replace(/deg/,"")).replace(/px/,"")),+t}var A=/(([\w_\-]+)(\(([^\)]*)\))?)+/gi;function O(t){return function(e){return function(t,e){for(var r=0,i=0;r0&&void 0!==arguments[0]?arguments[0]:3,e=Math.pow(t,2);return function(t,e){for(var r=new Array(e),i=0;i1&&void 0!==arguments[1])||arguments[1];return function(r){for(var i=r.pixels,n=r.width,o=r.height,a=Math.round(Math.sqrt(t.length)),s=Math.floor(a/2),l=n,h=o,c=l,u=h,f=new Uint8ClampedArray(i.length),v=e?1:0,g=0;g=0&&$=0&&S1&&void 0!==arguments[1]?arguments[1]:"center",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"center";return function(i){var n=R(i.pixels.length,i.width,i.height),o=i.width,a=i.height;"center"==e&&(e=Math.floor(o/2)),"center"==r&&(r=Math.floor(a/2));var s=M.CONSTANT.translate(-e,-r),l=M.CONSTANT.translate(e,r),h=M.CONSTANT.shear1(t),c=M.CONSTANT.shear2(t);return F(function(t,e,r,n){var u=M.multiply(s,[r,n,1]);u=M.multiply(h,u).map(Math.round),u=M.multiply(c,u).map(Math.round),u=M.multiply(h,u).map(Math.round),u=M.multiply(l,u);var f=b(u,2),v=f[0],g=f[1];if(!(v<0||g<0||v>o-1||g>a-1)){var d=4*(g*o+v);t[d]=i.pixels[e],t[d+1]=i.pixels[e+1],t[d+2]=i.pixels[e+2],t[d+3]=i.pixels[e+3]}})(n)}}function z(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:200,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];t=E(t);var i=(e=E(e))/100;return O(function(e,n){var o=i*x.brightness(e[n],e[n+1],e[n+2])>=t?255:0;r?0==o&&(e[n]=e[n+1]=e[n+2]=0):e[n]=e[n+1]=e[n+2]=Math.round(o)})}function j(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([1,2,1,2,4,2,1,2,1],1/16*((t=E(t))/100)))}function V(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([1,4,6,4,1,4,16,24,16,4,6,24,36,24,6,4,16,24,16,4,1,4,6,4,1],1/256*((t=E(t))/100)))}function U(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=E(t),P([5,5,5,-3,0,-3,-3,-3,-3])}function X(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=E(t),P([5,-3,-3,5,0,-3,5,-3,-3])}function Y(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],(t=E(t))/100))}function q(){return P(H([1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1],1/9))}function K(){return P(H([1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1],1/9))}function W(){return P(H([1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1],1/9))}function Z(){return P([-1,-2,-1,0,0,0,1,2,1])}function J(){return P([-1,0,1,-2,0,2,-1,0,1])}var Q=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],tt=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function et(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}function rt(t,e,r){return r?function(t,e,r,i){if(isNaN(i)||i<1)return t;i|=0;var n,o,a,s,l,h,c,u,f,v,g,d,p,m,y,b,k,C,w,x,_,$,S,M,H=t.pixels,B=t.width,R=t.height,E=i+i+1,A=B-1,O=R-1,I=i+1,L=I*(I+1)/2,F=new et,G=F;for(a=1;a>z,0!=S?(S=255/S,H[h]=(u*T>>z)*S,H[h+1]=(f*T>>z)*S,H[h+2]=(v*T>>z)*S):H[h]=H[h+1]=H[h+2]=0,u-=d,f-=p,v-=m,g-=y,d-=N.r,p-=N.g,m-=N.b,y-=N.a,s=c+((s=n+i+1)>z,S>0?(S=255/S,H[s]=(u*T>>z)*S,H[s+1]=(f*T>>z)*S,H[s+2]=(v*T>>z)*S):H[s]=H[s+1]=H[s+2]=0,u-=d,f-=p,v-=m,g-=y,d-=N.r,p-=N.g,m-=N.b,y-=N.a,s=n+((s=o+I)0&&void 0!==arguments[0]?arguments[0]:10,e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return t=E(t),function(r){return rt(r,t,e)}}function nt(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:256;return P(H([1,4,6,4,1,4,16,24,16,4,6,24,-476,24,6,4,16,24,16,4,1,4,6,4,1],-1/(t=E(t))))}var ot=d({},{crop:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments[2],i=arguments[3],n=R(r*i*4,r,i);return function(o){for(var a=e,s=0;a0&&void 0!==arguments[0]?arguments[0]:0;return t=E(t),t%=360,function(e){if(0==t)return e;if(90==t||270==t)var r=R(e.pixels.length,e.height,e.width);else{if(180!=t)return T(t)(e);r=R(e.pixels.length,e.width,e.height)}return e.width,e.height,F(function(i,n,o,a){if(90==t)var s=4*(o*r.width+(r.width-1-a));else 270==t?s=4*((r.height-1-o)*r.width+a):180==t&&(s=4*((r.height-1-a)*r.width+(r.width-1-o)));r.pixels[s]=e.pixels[n],r.pixels[s+1]=e.pixels[n+1],r.pixels[s+2]=e.pixels[n+2],r.pixels[s+3]=e.pixels[n+3]})(e),r}},rotateDegree:T,"rotate-degree":T},{bitonal:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:100;return t=x.parse(t),e=x.parse(e),O(function(i,n){i[n]+i[n+1]+i[n+2]<=r?(i[n]=t.r,i[n+1]=t.g,i[n+2]=t.b):(i[n]=e.r,i[n+1]=e.g,i[n+2]=e.b)})},brightness:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;t=E(t);var e=Math.floor(t/100*255);return O(function(t,r){t[r]+=e,t[r+1]+=e,t[r+2]+=e})},clip:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;t=E(t);var e=2.55*Math.abs(t);return O(function(t,r){for(var i=r,n=r+2;i<=n;i++)t[i]>255-e?t[i]=255:t[i]0&&void 0!==arguments[0]?arguments[0]:0;t=E(t);var e=Math.max((128+t)/128,0);return O(function(t,r){t[r]=t[r]*e,t[r+1]=t[r+1]*e,t[r+2]=t[r+2]*e})},gamma:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=E(t),O(function(e,r){e[r]=255*Math.pow(e[r]/255,t),e[r+1]=255*Math.pow(e[r+1]/255,t),e[r+2]=255*Math.pow(e[r+2]/255,t)})},gradient:function(){var t=[].concat(Array.prototype.slice.call(arguments));1===t.length&&"string"==typeof t[0]&&(t=x.convertMatchesArray(t[0]));var e=(t=t.map(function(t){return x.matches(t).length?{type:"param",value:t}:{type:"scale",value:t}})).filter(function(t){return"scale"==t.type})[0];e=e?+e.value:256,t=t.filter(function(t){return"param"==t.type}).map(function(t){return t.value}).join(",");var r=x.gradient(t,e).map(function(t){return x.parse(t)});return O(function(t,i){var n=D(x.brightness(t[i],t[i+1],t[i+2])),o=D(Math.floor(n*(e/256))),a=r[o];t[i]=a.r,t[i+1]=a.g,t[i+2]=a.b,t[i+3]=D(Math.floor(256*a.a))})},grayscale:function(t){var e=(t=E(t))/100;return e>1&&(e=1),O(function(t,r){B(t,r,[.2126+.7874*(1-e),.7152-.7152*(1-e),.0722-.0722*(1-e),0,.2126-.2126*(1-e),.7152+.2848*(1-e),.0722-.0722*(1-e),0,.2126-.2126*(1-e),.7152-.7152*(1-e),.0722+.9278*(1-e),0,0,0,0,1])})},hue:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:360;return t=E(t),O(function(e,r){var i=e[r],n=e[r+1],o=e[r+2],a=Color.RGBtoHSV(i,n,o),s=a.h;s+=Math.abs(t),s%=360,a.h=s;var l=Color.HSVtoRGB(a);e[r]=l.r,e[r+1]=l.g,e[r+2]=l.b})},invert:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=E(t))/100;return O(function(t,r){t[r]=(255-t[r])*e,t[r+1]=(255-t[r+1])*e,t[r+2]=(255-t[r+2])*e})},noise:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return t=E(t),O(function(e,r){var i=5*Math.abs(t),n=-i,o=i,a=Math.round(n+Math.random()*(o-n));e[r]+=a,e[r+1]+=a,e[r+2]+=a})},opacity:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=E(t))/100;return O(function(t,r){t[r+3]*=e})},saturation:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=E(t))/100,r=1-Math.abs(e);return O(function(t,e){B(t,e,[r,0,0,0,0,r,0,0,0,0,r,0,0,0,0,r])})},sepia:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,e=(t=E(t))/100;return e>1&&(e=1),O(function(t,r){B(t,r,[.393+.607*(1-e),.769-.769*(1-e),.189-.189*(1-e),0,.349-.349*(1-e),.686+.314*(1-e),.168-.168*(1-e),0,.272-.272*(1-e),.534-.534*(1-e),.131+.869*(1-e),0,0,0,0,1])})},shade:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return t=E(t),e=E(e),r=E(r),O(function(i,n){i[n]*=t,i[n+1]*=e,i[n+2]*=r})},solarize:function(t,e,r){return t=E(t),e=E(e),r=E(r),O(function(i,n){i[n]0&&void 0!==arguments[0]?arguments[0]:200,arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,!1)},"threshold-color":z},{blur:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:3;return P(G(t=E(t)))},emboss:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:4;return P([-2*(t=E(t)),-t,0,-t,1,t,0,t,2*t])},gaussianBlur:j,"gaussian-blur":j,gaussianBlur5x:V,"gaussian-blur-5x":V,grayscale2:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([.3,.3,.3,0,0,.59,.59,.59,0,0,.11,.11,.11,0,0,0,0,0,0,0,0,0,0,0,0],(t=E(t))/100))},identity:function(){return P([0,0,0,0,1,0,0,0,0])},kirschHorizontal:U,"kirsch-horizontal":U,kirschVertical:X,"kirsch-vertical":X,laplacian:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([-1,-1,-1,-1,8,-1,-1,-1,-1],(t=E(t))/100))},laplacian5x:Y,"laplacian-5x":Y,motionBlur:q,"motion-blur":q,motionBlur2:K,"motion-blur-2":K,motionBlur3:W,"motion-blur-3":W,negative:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([-1,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,0,1,0,1,1,1,1,1],(t=E(t))/100))},random:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[9,16,25,36,49,64,81,100].sort(function(t,e){return.5-Math.random()})[0];return t=E(t),function(t,r,i){return P(function(t,e,r){for(var i=[],n=1;n<=r;n++){var o=Math.random()*(e-t)+t,a=Math.floor(10*Math.random())%2==0?-1:1;i.push(a*o)}i.sort();var s=Math.floor(r/2),l=i[s];return i[s]=i[0],i[0]=l,i}(-1,5,e))(t,r,i)}},sepia2:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([.393,.349,.272,0,0,.769,.686,.534,0,0,.189,.168,.131,0,0,0,0,0,0,0,0,0,0,0,0],(t=E(t))/100))},sharpen:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([0,-1,0,-1,5,-1,0,-1,0],(t=E(t))/100))},sobelHorizontal:Z,"sobel-horizontal":Z,sobelVertical:J,"sobel-vertical":J,stackBlur:it,"stack-blur":it,transparency:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100;return P(H([1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,.3,0,0,0,0,0,1],(t=E(t))/100))},unsharpMasking:nt,"unsharp-masking":nt});Object.assign(ot,{pack:O,packXY:F,swapColor:L});var at=ot;at.filter=function(t){return at.merge(N(t).map(function(t){return t.arr}))},at.multi=function(){for(var t=arguments.length,e=Array(t),r=0;r1?r-1:0),n=1;n1&&void 0!==arguments[1]?arguments[1]:1,r=[],i=0;i0&&void 0!==arguments[0]?arguments[0]:100;return at.filter("grayscale laplacian("+t)},at.laplacian5x.grayscale=function(){return at.filter("grayscale laplacian5x")},at.kirsch=function(){return at.filter("kirsch-horizontal kirsch-vertical")},at.kirsch.grayscale=function(){return at.filter("grayscale kirsch")},at.sobel=function(){return at.filter("sobel-horizontal sobel-vertical")},at.sobel.grayscale=function(){return at.filter("grayscale sobel")},at.vintage=function(){return at.filter("brightness(15) saturation(-20) gamma(1.8)")};var st=0,lt=[],ht=function(){function t(e,r,i){if(v(this,t),"string"!=typeof e)this.el=e;else{var n=document.createElement(e);for(var o in this.uniqId=st++,r&&(n.className=r),i=i||{})n.setAttribute(o,i[o]);this.el=n}}return g(t,[{key:"attr",value:function(t,e){return 1==arguments.length?this.el.getAttribute(t):(this.el.setAttribute(t,e),this)}},{key:"closest",value:function(e){for(var r=this,i=!1;!(i=r.hasClass(e));){if(!r.el.parentNode)return null;r=new t(r.el.parentNode)}return i?r:null}},{key:"removeClass",value:function(t){this.el.className=(" "+this.el.className+" ").replace(" "+t+" "," ").trim()}},{key:"hasClass",value:function(t){return!!this.el.className&&(" "+this.el.className+" ").indexOf(" "+t+" ")>-1}},{key:"addClass",value:function(t){this.hasClass(t)||(this.el.className=this.el.className+" "+t)}},{key:"toggleClass",value:function(t){this.hasClass(t)?this.removeClass(t):this.addClass(t)}},{key:"html",value:function(t){return"string"==typeof t?this.el.innerHTML=t:this.empty().append(t),this}},{key:"empty",value:function(){return this.html("")}},{key:"append",value:function(t){return"string"==typeof t?this.el.appendChild(document.createTextNode(t)):this.el.appendChild(t.el||t),this}},{key:"appendTo",value:function(t){return(t.el?t.el:t).appendChild(this.el),this}},{key:"remove",value:function(){return this.el.parentNode&&this.el.parentNode.removeChild(this.el),this}},{key:"text",value:function(){return this.el.textContent}},{key:"css",value:function(t,e){var r=this;if(2==arguments.length)this.el.style[t]=e;else if(1==arguments.length){if("string"==typeof t)return getComputedStyle(this.el)[t];var i=t||{};Object.keys(i).forEach(function(t){r.el.style[t]=i[t]})}return this}},{key:"cssFloat",value:function(t){return parseFloat(this.css(t))}},{key:"cssInt",value:function(t){return parseInt(this.css(t))}},{key:"offset",value:function(){var t=this.el.getBoundingClientRect();return{top:t.top+document.documentElement.scrollTop,left:t.left+document.documentElement.scrollLeft}}},{key:"position",value:function(){return this.el.style.top?{top:parseFloat(this.css("top")),left:parseFloat(this.css("left"))}:this.el.getBoundingClientRect()}},{key:"width",value:function(){return this.el.offsetWidth}},{key:"contentWidth",value:function(){return this.width()-this.cssFloat("padding-left")-this.cssFloat("padding-right")}},{key:"height",value:function(){return this.el.offsetHeight}},{key:"contentHeight",value:function(){return this.height()-this.cssFloat("padding-top")-this.cssFloat("padding-bottom")}},{key:"dataKey",value:function(t){return this.uniqId+"."+t}},{key:"data",value:function(t,e){if(2!=arguments.length){if(1==arguments.length)return lt[this.dataKey(t)];var r=Object.keys(lt),i=this.uniqId+".";return r.filter(function(t){return 0==t.indexOf(i)}).map(function(t){return lt[t]})}return lt[this.dataKey(t)]=e,this}},{key:"val",value:function(t){return 0==arguments.length?this.el.value:(1==arguments.length&&(this.el.value=t),this)}},{key:"int",value:function(){return parseInt(this.val(),10)}},{key:"float",value:function(){return parseFloat(this.val())}},{key:"show",value:function(){return this.css("display","block")}},{key:"hide",value:function(){return this.css("display","none")}},{key:"toggle",value:function(){return"none"==this.css("display")?this.show():this.hide()}},{key:"scrollTop",value:function(){return this.el===document.body?document.documentElement.scrollTop:this.el.scrollTop}},{key:"scrollLeft",value:function(){return this.el===document.body?document.documentElement.scrollLeft:this.el.scrollLeft}},{key:"on",value:function(t,e,r,i){return this.el.addEventListener(t,e,r,i),this}},{key:"off",value:function(t,e){return this.el.removeEventListener(t,e),this}},{key:"getElement",value:function(){return this.el}},{key:"createChild",value:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=new t(e,r,i);return o.css(n),this.append(o),o}}]),t}(),ct={addEvent:function(t,e,r){t.addEventListener(e,r)},removeEvent:function(t,e,r){t.removeEventListener(e,r)},pos:function(t){return t.touches&&t.touches[0]?t.touches[0]:t}},ut=function(){function t(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};v(this,t),this.masterObj=e,this.settingObj=r}return g(t,[{key:"set",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;this.settingObj[t]=e||r}},{key:"init",value:function(t){if(!this.has(t)){var e=t.split("."),r=this.masterObj[e[0]]||this.masterObj,i=e.pop();if(r[i]){for(var n=arguments.length,o=Array(n>1?n-1:0),a=1;a1&&void 0!==arguments[1]?arguments[1]:"";return this.init(t,e),this.settingObj[t]||e}},{key:"has",value:function(t){return!!this.settingObj[t]}}]),t}(),ft=/^(click|mouse(down|up|move|enter|leave)|key(down|up|press)|contextmenu|change|input)/gi,vt=["Control","Shift","Alt","Meta"],gt=function(){function t(){v(this,t),this.state=new ut(this)}return g(t,[{key:"initializeEvent",value:function(){this.initializeEventMachin()}},{key:"destroy",value:function(){this.destroyEventMachin()}},{key:"destroyEventMachin",value:function(){this.removeEventAll()}},{key:"initializeEventMachin",value:function(){this.filterProps(ft).forEach(this.parseEvent.bind(this))}},{key:"filterProps",value:function(t){return Object.getOwnPropertyNames(this.__proto__).filter(function(e){return e.match(t)})}},{key:"parseEvent",value:function(t){var e=t.split(" ");this.bindingEvent(e,this[t].bind(this))}},{key:"getDefaultDomElement",value:function(t){var e=void 0;return(e=t?this[t]||window[t]:this.el||this.$el||this.$root)instanceof ht?e.getElement():e}},{key:"getDefaultEventObject",value:function(t){var e=this,r=t.split("."),i=r.shift(),n=r.includes("Control"),o=r.includes("Shift"),a=r.includes("Alt"),s=r.includes("Meta"),l=(r=r.filter(function(t){return!1===vt.includes(t)})).filter(function(t){return!!e[t]});return{eventName:i,isControl:n,isShift:o,isAlt:a,isMeta:s,codes:r=r.filter(function(t){return!1===l.includes(t)}).map(function(t){return t.toLowerCase()}),checkMethodList:l}}},{key:"bindingEvent",value:function(t,e){var r,i=(r=t,Array.isArray(r)?r:Array.from(r)),n=i[0],o=i[1],a=i.slice(2);o=this.getDefaultDomElement(o);var s=this.getDefaultEventObject(n);s.dom=o,s.delegate=a.join(" "),this.addEvent(s,e)}},{key:"matchPath",value:function(t,e){return t?t.matches(e)?t:this.matchPath(t.parentElement,e):null}},{key:"getBindings",value:function(){return this._bindings||this.initBindings(),this._bindings}},{key:"addBinding",value:function(t){this.getBindings().push(t)}},{key:"initBindings",value:function(){this._bindings=[]}},{key:"checkEventType",value:function(t,e){var r=this,i=!t.ctrlKey||e.isControl,n=!t.shiftKey||e.isShift,o=!t.altKey||e.isAlt,a=!t.metaKey||e.isMeta,s=!0;e.codes.length&&(s=e.codes.includes(t.code.toLowerCase())||e.codes.includes(t.key.toLowerCase()));var l=!0;return e.checkMethodList.length&&(l=e.checkMethodList.every(function(e){return r[e].call(r,t)})),i&&o&&n&&a&&s&&l}},{key:"makeCallback",value:function(t,e){var r=this;return t.delegate?function(i){if(r.checkEventType(i,t)){var n=r.matchPath(i.target||i.srcElement,t.delegate);if(n)return i.delegateTarget=n,i.$delegateTarget=new ht(n),e(i)}}:function(i){if(r.checkEventType(i,t))return e(i)}}},{key:"addEvent",value:function(t,e){t.callback=this.makeCallback(t,e),this.addBinding(t),ct.addEvent(t.dom,t.eventName,t.callback)}},{key:"removeEventAll",value:function(){var t=this;this.getBindings().forEach(function(e){t.removeEvent(e)}),this.initBindings()}},{key:"removeEvent",value:function(t){var e=t.eventName,r=t.dom,i=t.callback;ct.removeEvent(r,e,i)}}]),t}(),dt=function(t){function e(t){v(this,e);var r=y(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return m(e,gt),g(e,[{key:"initialize",value:function(){this.$el=new ht("div","control"),this.$hue=this.$el.createChild("div","hue"),this.$opacity=this.$el.createChild("div","opacity"),this.$controlPattern=this.$el.createChild("div","empty"),this.$controlColor=this.$el.createChild("div","color"),this.$hueContainer=this.$hue.createChild("div","hue-container"),this.$drag_bar=this.$hueContainer.createChild("div","drag-bar"),this.drag_bar_pos={},this.$opacityContainer=this.$opacity.createChild("div","opacity-container"),this.$opacityColorBar=this.$opacityContainer.createChild("div","color-bar"),this.$opacity_drag_bar=this.$opacityContainer.createChild("div","drag-bar2"),this.opacity_drag_bar_pos={}}},{key:"setBackgroundColor",value:function(t){this.$controlColor.css("background-color",t)}},{key:"refresh",value:function(){this.setColorUI()}},{key:"setColorUI",value:function(){var t=this.state.get("$el.width")*this.colorpicker.currentS,e=this.state.get("$el.height")*(1-this.colorpicker.currentV);this.$drag_pointer.css({left:t+"px",top:e+"px"})}},{key:"setOpacityColorBar",value:function(t){var e=x.parse(t);e.a=0;var r=x.format(e,"rgb");e.a=1;var i=x.format(e,"rgb");this.$opacityColorBar.css("background","linear-gradient(to right, "+r+", "+i+")")}},{key:"setOpacity",value:function(t){var e,r=this.$opacityContainer.offset().left,i=r+this.state.get("$opacityContainer.width"),n=ct.pos(t).clientX;e=ni?100:(n-r)/(i-r)*100;var o=this.state.get("$opacityContainer.width")*(e/100);this.$opacity_drag_bar.css({left:o-Math.ceil(this.state.get("$opacity_drag_bar.width")/2)+"px"}),this.opacity_drag_bar_pos={x:o},this.colorpicker.setCurrentA(this.caculateOpacity()),this.colorpicker.currentFormat(),this.colorpicker.setInputColor()}},{key:"setInputColor",value:function(){this.setBackgroundColor(this.colorpicker.getFormattedColor("rgb"));var t=this.colorpicker.convertRGB(),e=x.format(t,"rgb");this.setOpacityColorBar(e)}},{key:"setColorUI",value:function(){var t=this.state.get("$hueContainer.width")*(this.colorpicker.currentH/360);this.$drag_bar.css({left:t-7.5+"px"}),this.drag_bar_pos={x:t};var e=this.state.get("$opacityContainer.width")*(this.colorpicker.currentA||0);this.$opacity_drag_bar.css({left:e-7.5+"px"}),this.opacity_drag_bar_pos={x:e}}},{key:"caculateH",value:function(){return{h:(this.drag_bar_pos||{x:0}).x/this.state.get("$hueContainer.width")*360}}},{key:"caculateOpacity",value:function(){var t=this.opacity_drag_bar_pos||{x:0},e=Math.round(t.x/this.state.get("$opacityContainer.width")*100)/100;return isNaN(e)?1:e}},{key:"EventDocumentMouseMove",value:function(t){this.isHueDown&&this.setHueColor(t),this.isOpacityDown&&this.setOpacity(t)}},{key:"EventDocumentMouseUp",value:function(t){this.isHueDown=!1,this.isOpacityDown=!1}},{key:"setControlColor",value:function(t){this.$controlColor.css("background-color",t)}},{key:"setHueColor",value:function(t){var e,r=this.$hueContainer.offset().left,i=r+this.state.get("$hueContainer.width"),n=t?ct.pos(t).clientX:r+(i-r)*(this.colorpicker.currentH/360);e=ni?100:(n-r)/(i-r)*100;var o=this.state.get("$hueContainer.width")*(e/100);this.$drag_bar.css({left:o-Math.ceil(this.state.get("$drag_bar.width")/2)+"px"}),this.drag_bar_pos={x:o};var a=$.checkHueColor(e/100);this.colorpicker.setBackgroundColor(a),this.colorpicker.setCurrentH(e/100*360),this.colorpicker.setInputColor()}},{key:"setOnlyHueColor",value:function(){var t,e=this.$hueContainer.offset().left,r=e+this.state.get("$hueContainer.width"),i=e+(r-e)*(this.colorpicker.currentH/360);t=ir?100:(i-e)/(r-e)*100;var n=this.state.get("$hueContainer.width")*(t/100);this.$drag_bar.css({left:n-Math.ceil(this.state.get("$drag_bar.width")/2)+"px"}),this.drag_bar_pos={x:n};var o=$.checkHueColor(t/100);this.colorpicker.setBackgroundColor(o),this.colorpicker.setCurrentH(t/100*360)}},{key:"mousedown $drag_bar",value:function(t){t.preventDefault(),this.isHueDown=!0}},{key:"mousedown $opacity_drag_bar",value:function(t){t.preventDefault(),this.isOpacityDown=!0}},{key:"mousedown $hueContainer",value:function(t){this.isHueDown=!0,this.setHueColor(t)}},{key:"mousedown $opacityContainer",value:function(t){this.isOpacityDown=!0,this.setOpacity(t)}}]),e}(),pt=function(t){function e(t){v(this,e);var r=y(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return m(e,gt),g(e,[{key:"initialize",value:function(){this.$el=new ht("div","information hex"),this.$informationChange=this.$el.createChild("div","information-change"),this.$formatChangeButton=this.$informationChange.createChild("button","format-change-button arrow-button",{type:"button"}),this.$el.append(this.makeInputFieldHex()),this.$el.append(this.makeInputFieldRgb()),this.$el.append(this.makeInputFieldHsl()),this.format="hex"}},{key:"makeInputFieldHex",value:function(){var t=new ht("div","information-item hex"),e=t.createChild("div","input-field hex");return this.$hexCode=e.createChild("input","input",{type:"text"}),e.createChild("div","title").html("HEX"),t}},{key:"makeInputFieldRgb",value:function(){var t=new ht("div","information-item rgb"),e=t.createChild("div","input-field rgb-r");return this.$rgb_r=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("R"),e=t.createChild("div","input-field rgb-g"),this.$rgb_g=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("G"),e=t.createChild("div","input-field rgb-b"),this.$rgb_b=e.createChild("input","input",{type:"number",step:1,min:0,max:255}),e.createChild("div","title").html("B"),e=t.createChild("div","input-field rgb-a"),this.$rgb_a=e.createChild("input","input",{type:"number",step:.01,min:0,max:1}),e.createChild("div","title").html("A"),t}},{key:"makeInputFieldHsl",value:function(){var t=new ht("div","information-item hsl"),e=t.createChild("div","input-field hsl-h");return this.$hsl_h=e.createChild("input","input",{type:"number",step:1,min:0,max:360}),e.createChild("div","title").html("H"),e=t.createChild("div","input-field hsl-s"),this.$hsl_s=e.createChild("input","input",{type:"number",step:1,min:0,max:100}),e.createChild("div","postfix").html("%"),e.createChild("div","title").html("S"),e=t.createChild("div","input-field hsl-l"),this.$hsl_l=e.createChild("input","input",{type:"number",step:1,min:0,max:100}),e.createChild("div","postfix").html("%"),e.createChild("div","title").html("L"),e=t.createChild("div","input-field hsl-a"),this.$hsl_a=e.createChild("input","input",{type:"number",step:.01,min:0,max:1}),e.createChild("div","title").html("A"),t}},{key:"currentFormat",value:function(){var t=this.format||"hex";if(this.colorpicker.currentA<1&&"hex"==t){this.$el.removeClass(t),this.$el.addClass("rgb"),this.format="rgb",this.colorpicker.setInputColor()}}},{key:"setCurrentFormat",value:function(t){this.format=t,this.initFormat()}},{key:"initFormat",value:function(){var t=this.format||"hex";this.$el.removeClass("hex"),this.$el.removeClass("rgb"),this.$el.removeClass("hsl"),this.$el.addClass(t)}},{key:"nextFormat",value:function(){var t=this.format||"hex",e="hex";"hex"==t?e="rgb":"rgb"==t?e="hsl":"hsl"==t&&(e=1==this.colorpicker.currentA?"hex":"rgb"),this.$el.removeClass(t),this.$el.addClass(e),this.format=e,this.setInputColor(),this.colorpicker.changeInputColorAfterNextFormat()}},{key:"setRGBInput",value:function(t,e,r){this.$rgb_r.val(t),this.$rgb_g.val(e),this.$rgb_b.val(r),this.$rgb_a.val(this.colorpicker.currentA)}},{key:"setHSLInput",value:function(t,e,r){this.$hsl_h.val(t),this.$hsl_s.val(e),this.$hsl_l.val(r),this.$hsl_a.val(this.colorpicker.currentA)}},{key:"getHexFormat",value:function(){return x.format({r:this.$rgb_r.int(),g:this.$rgb_g.int(),b:this.$rgb_b.int()},"hex",this.colorpicker.opt.color)}},{key:"getRgbFormat",value:function(){return x.format({r:this.$rgb_r.int(),g:this.$rgb_g.int(),b:this.$rgb_b.int(),a:this.$rgb_a.float()},"rgb",this.colorpicker.opt.color)}},{key:"getHslFormat",value:function(){return x.format({h:this.$hsl_h.val(),s:this.$hsl_s.val(),l:this.$hsl_l.val(),a:this.$hsl_a.float()},"hsl",this.colorpicker.opt.color)}},{key:"convertRGB",value:function(){return this.colorpicker.convertRGB()}},{key:"convertHEX",value:function(){return this.colorpicker.convertHEX()}},{key:"convertHSL",value:function(){return this.colorpicker.convertHSL()}},{key:"getFormattedColor",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return"hex"==(t=t||this.getFormat())?this.$hexCode.val():"rgb"==t?this.getRgbFormat(e):"hsl"==t?this.getHslFormat(e):void 0}},{key:"getFormat",value:function(){return this.format||"hex"}},{key:"setInputColor",value:function(){var t=this.getFormat(),e=null;if("hex"==t){this.$hexCode.val(this.convertHEX());e=this.convertRGB();this.setRGBInput(e.r,e.g,e.b,e.a)}else if("rgb"==t){e=this.convertRGB();this.setRGBInput(e.r,e.g,e.b,e.a),this.$hexCode.val(this.convertHEX())}else if("hsl"==t){var r=this.convertHSL();this.setHSLInput(r.h,r.s,r.l,r.a)}}},{key:"checkNumberKey",value:function(t){return ct.checkNumberKey(t)}},{key:"checkNotNumberKey",value:function(t){return!ct.checkNumberKey(t)}},{key:"changeRgbColor",value:function(){this.colorpicker.changeInformationColor(this.getRgbFormat())}},{key:"changeHslColor",value:function(){this.colorpicker.changeInformationColor(this.getHslFormat())}},{key:"change $rgb_r",value:function(t){this.changeRgbColor()}},{key:"change $rgb_g",value:function(t){this.changeRgbColor()}},{key:"change $rgb_b",value:function(t){this.changeRgbColor()}},{key:"change $rgb_a",value:function(t){this.changeRgbColor()}},{key:"change $hsl_h",value:function(t){this.changeHslColor()}},{key:"change $hsl_s",value:function(t){this.changeHslColor()}},{key:"change $hsl_l",value:function(t){this.changeHslColor()}},{key:"change $hsl_a",value:function(t){this.changeHslColor()}},{key:"keydown $hexCode",value:function(t){if(t.which<65||t.which>70)return this.checkNumberKey(t)}},{key:"keyup $hexCode",value:function(t){var e=this.$hexCode.val();"#"==e.charAt(0)&&7==e.length&&(this.colorpicker.changeInformationColor(e),this.setInputColor())}},{key:"click $formatChangeButton",value:function(t){this.nextFormat()}},{key:"refresh",value:function(){}}]),e}(),mt=function(t){function e(t){v(this,e);var r=y(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return m(e,gt),g(e,[{key:"initialize",value:function(){this.$el=new ht("div","color"),this.$saturation=this.$el.createChild("div","saturation"),this.$value=this.$saturation.createChild("div","value"),this.$drag_pointer=this.$value.createChild("div","drag-pointer")}},{key:"setBackgroundColor",value:function(t){this.$el.css("background-color",t)}},{key:"refresh",value:function(){this.setColorUI()}},{key:"caculateSV",value:function(){var t=this.drag_pointer_pos||{x:0,y:0},e=this.state.get("$el.width"),r=this.state.get("$el.height");return{s:t.x/e,v:(r-t.y)/r,width:e,height:r}}},{key:"setColorUI",value:function(){var t=this.state.get("$el.width")*this.colorpicker.currentS,e=this.state.get("$el.height")*(1-this.colorpicker.currentV);this.$drag_pointer.css({left:t-5+"px",top:e-5+"px"}),this.drag_pointer_pos={x:t,y:e}}},{key:"setMainColor",value:function(t){t.preventDefault();var e=this.$el.position(),r=this.state.get("$el.contentWidth"),i=this.state.get("$el.contentHeight"),n=t.clientX-e.left,o=t.clientY-e.top;n<0?n=0:n>r&&(n=r),o<0?o=0:o>i&&(o=i),this.$drag_pointer.css({left:n-5+"px",top:o-5+"px"}),this.drag_pointer_pos={x:n,y:o},this.colorpicker.caculateHSV(),this.colorpicker.setInputColor()}},{key:"EventDocumentMouseUp",value:function(t){this.isDown=!1}},{key:"EventDocumentMouseMove",value:function(t){this.isDown&&this.setMainColor(t)}},{key:"mousedown",value:function(t){this.isDown=!0,this.setMainColor(t)}},{key:"mouseup",value:function(t){this.isDown=!1}}]),e}(),yt="data-colorsets-index",bt=function(t){function e(t){v(this,e);var r=y(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return r.colorpicker=t,r.initialize(),r}return m(e,gt),g(e,[{key:"initialize",value:function(){this.$el=new ht("div","color-chooser");var t=this.$el.createChild("div","color-chooser-container"),e=t.createChild("div","colorsets-item colorsets-item-header");e.createChild("h1","title").html("Color Paletts"),this.$toggleButton=e.createChild("span","items").html("×"),this.$colorsetsList=t.createChild("div","colorsets-list"),this.refresh()}},{key:"refresh",value:function(){this.$colorsetsList.html(this.makeColorSetsList())}},{key:"makeColorItemList",value:function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5,r=new ht("div"),i=0;i1&&void 0!==arguments[1]&&arguments[1];if("object"==(void 0===t?"undefined":f(t))){if(!t.r||!t.g||!t.b)return;e?this.callbackColorValue(x.format(t,"hex")):this.initColor(x.format(t,"hex"))}else"string"==typeof t&&(e?this.callbackColorValue(t):this.initColor(t))}},{key:"getColor",value:function(t){this.caculateHSV();var e=this.convertRGB();return t?x.format(e,t):e}},{key:"definePositionForArrow",value:function(t,e,r){}},{key:"definePosition",value:function(t){var e=this.$root.width(),r=this.$root.height(),i=t.left-this.$body.scrollLeft();e+i>window.innerWidth&&(i-=e+i-window.innerWidth),i<0&&(i=0);var n=t.top-this.$body.scrollTop();r+n>window.innerHeight&&(n-=r+n-window.innerHeight),n<0&&(n=0),this.$root.css({left:i+"px",top:n+"px"})}},{key:"getInitalizePosition",value:function(){return"inline"==this.opt.position?{position:"relative",left:"auto",top:"auto",display:"inline-block"}:{position:"fixed",left:"-10000px",top:"-10000px"}}},{key:"show",value:function(t,e,r){this.destroy(),this.initializeEvent(),this.$root.appendTo(this.$body),this.$root.css(this.getInitalizePosition()).show(),this.definePosition(t),this.isColorPickerShow=!0,this.isShortCut=t.isShortCut||!1,this.initColor(e),this.colorpickerCallback=r,this.hideDelay=t.hideDelay||2e3,this.hideDelay>0&&this.setHideDelay(this.hideDelay)}},{key:"setHideDelay",value:function(t){var e=this;t=t||0,this.$root.off("mouseenter"),this.$root.off("mouseleave"),this.$root.on("mouseenter",function(){clearTimeout(e.timerCloseColorPicker)}),this.$root.on("mouseleave",function(){clearTimeout(e.timerCloseColorPicker),e.timerCloseColorPicker=setTimeout(e.hide.bind(e),t)}),clearTimeout(this.timerCloseColorPicker),this.timerCloseColorPicker=setTimeout(this.hide.bind(this),t)}},{key:"hide",value:function(){this.isColorPickerShow&&(this.destroy(),this.$root.hide(),this.$root.remove(),this.isColorPickerShow=!1)}},{key:"convertRGB",value:function(){return x.HSVtoRGB(this.currentH,this.currentS,this.currentV)}},{key:"convertHEX",value:function(){return x.format(this.convertRGB(),"hex")}},{key:"convertHSL",value:function(){return x.HSVtoHSL(this.currentH,this.currentS,this.currentV)}},{key:"getCurrentColor",value:function(){return this.information.getFormattedColor()}},{key:"getFormattedColor",value:function(t){if("rgb"==(t=t||"hex"))return(r=this.convertRGB()).a=this.currentA,x.format(r,"rgb");if("hsl"==t){var e=this.convertHSL();return e.a=this.currentA,x.format(e,"hsl")}var r=this.convertRGB();return x.format(r,"hex")}},{key:"setInputColor",value:function(t){this.information.setInputColor(t),this.control.setInputColor(t),this.callbackColorValue()}},{key:"changeInputColorAfterNextFormat",value:function(){this.control.setInputColor(),this.callbackColorValue()}},{key:"callbackColorValue",value:function(t){t=t||this.getCurrentColor(),isNaN(this.currentA)||("function"==typeof this.opt.onChange&&this.opt.onChange.call(this,t),"function"==typeof this.colorpickerCallback&&this.colorpickerCallback(t))}},{key:"caculateHSV",value:function(){var t=this.palette.caculateSV(),e=this.control.caculateH(),r=t.s,i=t.v,n=e.h;0==t.width&&(n=0,r=0,i=0),this.currentH=n,this.currentS=r,this.currentV=i}},{key:"setColorUI",value:function(){this.control.setColorUI(),this.palette.setColorUI()}},{key:"setCurrentHSV",value:function(t,e,r,i){this.currentA=i,this.currentH=t,this.currentS=e,this.currentV=r}},{key:"setCurrentH",value:function(t){this.currentH=t}},{key:"setCurrentA",value:function(t){this.currentA=t}},{key:"setBackgroundColor",value:function(t){this.palette.setBackgroundColor(t)}},{key:"setCurrentFormat",value:function(t){this.format=t,this.information.setCurrentFormat(t)}},{key:"getHSV",value:function(t){return"hsl"==t.type?x.HSLtoHSV(t):x.RGBtoHSV(t)}},{key:"initColor",value:function(t,e){var r=t||"#FF0000",i=x.parse(r);e=e||i.type,this.setCurrentFormat(e);var n=this.getHSV(i);this.setCurrentHSV(n.h,n.s,n.v,i.a),this.setColorUI(),this.setHueColor(),this.setInputColor()}},{key:"changeInformationColor",value:function(t){var e=t||"#FF0000",r=x.parse(e),i=this.getHSV(r);this.setCurrentHSV(i.h,i.s,i.v,r.a),this.setColorUI(),this.setHueColor(),this.control.setInputColor(),this.callbackColorValue()}},{key:"setHueColor",value:function(){this.control.setOnlyHueColor()}},{key:"checkColorPickerClass",value:function(t){var e=new ht(t).closest("codemirror-colorview"),r=new ht(t).closest("codemirror-colorpicker"),i=new ht(t).closest("CodeMirror");t.nodeName;return!!(r||e||i)}},{key:"checkInHtml",value:function(t){return"HTML"==t.nodeName}},{key:"mouseup document",value:function(t){this.palette.EventDocumentMouseUp(t),this.control.EventDocumentMouseUp(t),this.checkInHtml(t.target)||0==this.checkColorPickerClass(t.target)&&this.hide()}},{key:"mousemove document",value:function(t){this.palette.EventDocumentMouseMove(t),this.control.EventDocumentMouseMove(t)}},{key:"initializeEvent",value:function(){this.initializeEventMachin(),this.palette.initializeEvent(),this.control.initializeEvent(),this.information.initializeEvent(),this.currentColorSets.initializeEvent(),this.colorSetsChooser.initializeEvent(),this.contextMenu.initializeEvent()}},{key:"currentFormat",value:function(){this.information.currentFormat()}},{key:"toggleColorChooser",value:function(){this.colorSetsChooser.toggle()}},{key:"refreshColorSetsChooser",value:function(){this.colorSetsChooser.refresh()}},{key:"getColorSetsList",value:function(){return this.colorSetsList.getColorSetsList()}},{key:"setCurrentColorSets",value:function(t){this.colorSetsList.setCurrentColorSets(t),this.currentColorSets.refresh()}},{key:"setColorSets",value:function(t){this.colorSetsList.setUserList(t)}},{key:"destroy",value:function(){p(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"destroy",this).call(this),this.control.destroy(),this.palette.destroy(),this.information.destroy(),this.colorSetsChooser.destroy(),this.colorSetsList.destroy(),this.currentColorSets.destroy(),this.contextMenu.destroy(),this.colorpickerCallback=void 0}}]),e}(),$t="codemirror-colorview",St="codemirror-colorview-background",Mt=["comment"];function Ht(t,e){"setValue"==e.origin?(t.state.colorpicker.close_color_picker(),t.state.colorpicker.init_color_update(),t.state.colorpicker.style_color_update()):t.state.colorpicker.style_color_update(t.getCursor().line)}function Bt(t,e){t.state.colorpicker.isUpdate||(t.state.colorpicker.isUpdate=!0,t.state.colorpicker.close_color_picker(),t.state.colorpicker.init_color_update(),t.state.colorpicker.style_color_update())}function Rt(t,e){Ht(t,{origin:"setValue"})}function Et(t,e){t.state.colorpicker.keyup(e)}function At(t,e){t.state.colorpicker.is_edit_mode()&&t.state.colorpicker.check_mousedown(e)}function Ot(t,e){Ht(t,{origin:"setValue"})}function It(t){t.state.colorpicker.close_color_picker()}var Lt=function(){function t(e,r){v(this,t),r="boolean"==typeof r?{mode:"edit"}:Object.assign({mode:"edit"},r||{}),this.opt=r,this.cm=e,this.markers={},this.excluded_token=this.opt.excluded_token||Mt,this.opt.colorpicker?this.colorpicker=this.opt.colorpicker(this.opt):this.colorpicker=new _t(this.opt),this.init_event()}return g(t,[{key:"init_event",value:function(){var t,e,r,i,n;this.cm.on("mousedown",At),this.cm.on("keyup",Et),this.cm.on("change",Ht),this.cm.on("update",Bt),this.cm.on("refresh",Rt),this.onPasteCallback=(t=this.cm,e=Ot,function(r){e.call(this,t,r)}),this.cm.getWrapperElement().addEventListener("paste",this.onPasteCallback),this.is_edit_mode()&&this.cm.on("scroll",(r=It,i=50,n=void 0,function(t,e){n&&clearTimeout(n),n=setTimeout(function(){r(t,e)},i||300)}))}},{key:"is_edit_mode",value:function(){return"edit"==this.opt.mode}},{key:"is_view_mode",value:function(){return"view"==this.opt.mode}},{key:"destroy",value:function(){this.cm.off("mousedown",At),this.cm.off("keyup",Et),this.cm.off("change",Ht),this.cm.getWrapperElement().removeEventListener("paste",this.onPasteCallback),this.is_edit_mode()&&this.cm.off("scroll")}},{key:"hasClass",value:function(t,e){return!!t.className&&(" "+t.className+" ").indexOf(" "+e+" ")>-1}},{key:"check_mousedown",value:function(t){this.hasClass(t.target,St)?this.open_color_picker(t.target.parentNode):this.close_color_picker()}},{key:"popup_color_picker",value:function(t){var e=this.cm.getCursor(),r=this,i={lineNo:e.line,ch:e.ch,color:t||"#FFFFFF",isShortCut:!0};Object.keys(this.markers).forEach(function(t){if(("#"+t).indexOf("#"+i.lineNo+":")>-1){var e=r.markers[t];e.ch<=i.ch&&i.ch<=e.ch+e.color.length&&(i.ch=e.ch,i.color=e.color,i.nameColor=e.nameColor)}}),this.open_color_picker(i)}},{key:"open_color_picker",value:function(t){var e=t.lineNo,r=t.ch,i=t.nameColor,n=t.color;if(this.colorpicker){var o=this,a=n,s=this.cm.charCoords({line:e,ch:r});this.colorpicker.show({left:s.left,top:s.bottom,isShortCut:t.isShortCut||!1,hideDelay:o.opt.hideDelay||2e3},i||n,function(t){o.cm.replaceRange(t,{line:e,ch:r},{line:e,ch:r+a.length},"*colorpicker"),a=t})}}},{key:"close_color_picker",value:function(t){this.colorpicker&&this.colorpicker.hide()}},{key:"key",value:function(t,e){return[t,e].join(":")}},{key:"keyup",value:function(t){this.colorpicker&&("Escape"==t.key?this.colorpicker.hide():0==this.colorpicker.isShortCut&&this.colorpicker.hide())}},{key:"init_color_update",value:function(){this.markers={}}},{key:"style_color_update",value:function(t){if(t)this.match(t);else for(var e=this.cm.lineCount(),r=0;r-1)&&(delete this.markers[s],n[o].marker.clear())}}},{key:"match_result",value:function(t){return x.matches(t.text)}},{key:"submatch",value:function(t,e){var r=this;this.empty_marker(t,e);var i={next:0};this.match_result(e).forEach(function(n){r.render(i,t,e,n.color,n.nameColor)})}},{key:"match",value:function(t){var e=this.cm.getLineHandle(t),r=this;this.cm.operation(function(){r.submatch(t,e)})}},{key:"make_element",value:function(){var t=document.createElement("div");return t.className=$t,this.is_edit_mode()?t.title="open color picker":t.title="",t.back_element=this.make_background_element(),t.appendChild(t.back_element),t}},{key:"make_background_element",value:function(){var t=document.createElement("div");return t.className=St,t}},{key:"set_state",value:function(t,e,r,i){var n=this.create_marker(t,e);return n.lineNo=t,n.ch=e,n.color=r,n.nameColor=i,n}},{key:"create_marker",value:function(t,e){var r=this.key(t,e);return this.markers[r]||(this.markers[r]=this.make_element()),this.markers[r]}},{key:"has_marker",value:function(t,e){var r=this.key(t,e);return!!this.markers[r]}},{key:"update_element",value:function(t,e){t.back_element.style.backgroundColor=e}},{key:"set_mark",value:function(t,e,r){this.cm.setBookmark({line:t,ch:e},{widget:r,handleMouseEvents:!0})}},{key:"is_excluded_token",value:function(t,e){for(var r=this.cm.getTokenTypeAt({line:t,ch:e}),i=0,n=0,o=this.excluded_token.length;n0}},{key:"render",value:function(t,e,r,i,n){var o=r.text.indexOf(i,t.next);if(!0!==this.is_excluded_token(e,o)){if(t.next=o+i.length,this.has_marker(e,o))return this.update_element(this.create_marker(e,o),n||i),void this.set_state(e,o,i,n);var a=this.create_marker(e,o);this.update_element(a,n||i),this.set_state(e,o,i,n||i),this.set_mark(e,o,a)}}}]),t}();return t&&t.defineOption("colorpicker",!1,function(e,r,i){i&&i!=t.Init&&e.state.colorpicker&&(e.state.colorpicker.destroy(),e.state.colorpicker=null),r&&(e.state.colorpicker=new Lt(e,r))}),{Color:x,ColorNames:r,ColorPicker:_t,ImageFilter:ot,HueColor:$,Canvas:u,ImageLoader:C}}(CodeMirror); diff --git a/package.json b/package.json index bd34f49..af6629d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codemirror-colorpicker", - "version": "1.7.20", + "version": "1.8.0", "description": "colorpicker for codemirror", "main": "./dist/codemirror-colorpicker.js", "scripts": { diff --git a/src/util/ImageFilter.js b/src/util/ImageFilter.js index 2e28a51..251fab4 100644 --- a/src/util/ImageFilter.js +++ b/src/util/ImageFilter.js @@ -1,226 +1,26 @@ // TODO: worker run -import Color from './Color' -import Canvas from './Canvas' -import StackBlur from './blur/StackBlur' -import Matrix from './Matrix' - -function weight(arr, num = 1) { - return arr.map(i => { - return i * num; - }) -} - -function repeat (value, num) { - let arr = new Array(num) - for(let i = 0; i < num; i++) { - arr[i] = value - } - return arr; -} - -function colorMatrix(pixels, i, matrix) { - var r = pixels[i], g = pixels[i + 1], b = pixels[i + 2], a = pixels[i + 3]; - - pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; - pixels[i+1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; - pixels[i+2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; - pixels[i+3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; - -} - -function makeFilter(filter) { - - if (typeof filter == 'function') { - return filter; - } - - if (typeof filter == 'string') { - filter = [filter]; - } - - const filterName = filter.shift(); - - if (typeof filterName == 'function') { - return filterName; - } - - const params = filter; - - const filterFunction = F[filterName]; - - if (!filterFunction) { - throw new Error(`${filterName} is not filter. please check filter name.`) - } - return filterFunction.apply(filterFunction, params); -} - -function each(len, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex); - } -} - -function eachXY(len, width, callback) { - for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { - callback(i, xyIndex % width, Math.floor(xyIndex / width) ); - } -} - -function createRandRange(min, max, count) { - var result = []; - - for (var i = 1; i <= count; i++) { - var num = Math.random() * (max - min) + min; - var sign = (Math.floor(Math.random() * 10) % 2 == 0) ? -1 : 1; - result.push(sign * num); - } - - result.sort(); - - const centerIndex = Math.floor(count / 2); - var a = result[centerIndex]; - result[centerIndex] = result[0]; - result[0] = a; - - return result; -} - -function createRandomCount() { - return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { - return 0.5 - Math.random(); - })[0]; -} - -function createBitmap(length, width, height) { - return { pixels: new Uint8ClampedArray(length), width, height } -} - -function getBitmap(bitmap, area) { - return Canvas.getBitmap(bitmap, area); -} - -function putBitmap(bitmap, subBitmap, area) { - return Canvas.putBitmap(bitmap, subBitmap, area); -} - -function parseParamNumber (param) { - if (typeof param === 'string') { - param = param.replace(/deg/, '') - param = param.replace(/px/, '') - } - return +param -} - -let F = {}; -let ImageFilter = F - -const filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; -const filter_split = ' ' - - -const pack = F.pack = function pack(callback) { - return function (bitmap) { - each(bitmap.pixels.length, (i, xyIndex) => { - callback(bitmap.pixels, i, xyIndex) - }) - return bitmap; - } -} - - -const ColorListIndex = [0, 1, 2, 3] - -const swapColor = F.swapColor = function swapColor (pixels, startIndex, endIndex) { - - ColorListIndex.forEach(i => { - var temp = pixels[startIndex + i] - pixels[startIndex + i] = pixels[endIndex + i] - pixels[endIndex + i] = temp - }) -} - -const packXY = F.packXY = function packXY(callback) { - return function (bitmap) { - eachXY(bitmap.pixels.length, bitmap.width, (i, x, y) => { - callback(bitmap.pixels, i, x, y) - }) - return bitmap; - } -} - -F.matches = function (str) { - var ret = Color.convertMatches(str) - const matches = ret.str.match(filter_regexp); - let result = []; - - if (!matches) { - return result; - } - - result = matches.map((it) => { - return { filter: it, origin: Color.reverseMatches(it, ret.matches) } - }) - - var pos = { next: 0 } - result = result.map(item => { - - const startIndex = str.indexOf(item.origin, pos.next); - - item.startIndex = startIndex; - item.endIndex = startIndex + item.origin.length; - - item.arr = this.parseFilter(item.origin) - - pos.next = item.endIndex; - - return item - }).filter(it => { - if (!it.arr.length) return false - return !!F[it.arr[0]] - }) - - return result; -} - -/** - * Filter Parser - * - * F.parseFilter('blur(30)') == ['blue', '30'] - * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] - * - * @param {String} filterString - */ -F.parseFilter = function (filterString) { - - var ret = Color.convertMatches(filterString) - const matches = ret.str.match(filter_regexp); - - if (!matches[0]) { - return [] - } - - var arr = matches[0].split('(') - - var filterName = arr.shift() - var filterParams = [] - - if (!F[filterName.toLowerCase()]) { - return [] - } - - if (arr.length) { - filterParams = arr.shift().split(')')[0].split(',').map(f => { - return Color.reverseMatches(f, ret.matches) - }) - } - - var result = [filterName, ...filterParams].map(Color.trim) - - return result -} +import { + makeFilter, + getBitmap, + putBitmap, + pack, + packXY, + swapColor, + matches +} from './filter/functions' + +import ImageFilter from './filter/index' + +Object.assign(ImageFilter, { + pack, + packXY, + swapColor +}) + +let F = ImageFilter F.filter = function (str) { - return F.merge(F.matches(str).map(it => { + return F.merge(matches(str).map(it => { return it.arr })) } @@ -233,8 +33,8 @@ F.filter = function (str) { * */ F.multi = function (...filters) { - filters = filters.map(f => { - return makeFilter(f); + filters = filters.map(filter => { + return makeFilter(filter, F); }) return function (bitmap) { @@ -256,7 +56,7 @@ F.merge = function (filters) { * F.partial({x,y,width,height}, 'filter' ) * * @param {{x, y, width, height}} area - * @param {*} filters + * @param {*} filters */ F.partial = function (area, ...filters) { var allFilter = null @@ -281,764 +81,21 @@ F.counter = function (filter, count = 1) { return F.multi(...filters); } -// Image manupulate -F.resize = function (dstWidth, dstHeight) { - return function (bitmap) { - - var c = Canvas.drawPixels(bitmap); - var context = c.getContext('2d'); - - c.width = dstWidth; - c.height = dstHeight; - - return { - pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), - width: dstWidth, - height: dstHeight - } - } -} - -F.crop = function (startX = 0, startY = 0, width, height) { - - const newBitmap = createBitmap(width * height * 4, width, height) - - return function (bitmap) { - for (var y = startY, realY = 0; y < height; y++, realY++) { - for (var x = startX, realX = 0; x < width; x++, realX++) { - newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x] - } - } - - return newBitmap; - } -} - - -F.flipH = function flipH () { - return function (bitmap) { - - const width = bitmap.width - const height = bitmap.height - const isCenter = width % 2 == 1 ? 1 : 0 - - const halfWidth = isCenter ? Math.floor(width / 2) : width / 2 ; - - for (var y = 0; y < height; y++) { - for (var x = 0; x < halfWidth; x++) { - - var startIndex = (y * width + x) * 4 - var endIndex = (y * width + (width -1 - x) ) * 4 - swapColor(bitmap.pixels, startIndex, endIndex) - - } - } - - return bitmap; - } -} - -F.flipV = function flipV () { - return function (bitmap) { - - const width = bitmap.width - const height = bitmap.height - const isCenter = height % 2 == 1 ? 1 : 0 - - const halfHeight = isCenter ? Math.floor(height / 2) : height / 2 ; - - for (var y = 0; y < halfHeight; y++) { - for (var x = 0; x < width; x++) { - - var startIndex = (y * width + x) * 4 - var endIndex = ((height -1 - y) * width + x ) * 4 - swapColor(bitmap.pixels, startIndex, endIndex) - - } - } - - return bitmap; - } -} - -F.radian = function (degree) { - return Matrix.CONSTANT.radian(degree) -} - -F['rotate-degree'] = F.rotateDegree = function (angle, cx = 'center', cy = 'center') { - // const r = F.radian(angle) - - return function (bitmap) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height) - const width = bitmap.width - const height = bitmap.height - - if (cx == 'center') { - cx = Math.floor(width / 2); - } - - if (cy == 'center') { - cy = Math.floor(height/ 2); - } - - const translateMatrix = Matrix.CONSTANT.translate(-cx, -cy) - const translateMatrix2 = Matrix.CONSTANT.translate(cx, cy) - const shear1Matrix = Matrix.CONSTANT.shear1(angle) - const shear2Matrix = Matrix.CONSTANT.shear2(angle) - - return packXY((pixels, i, x, y) => { - // console.log(x, y, i) - let arr = Matrix.multiply(translateMatrix, [x, y, 1]) - - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round) - arr = Matrix.multiply(shear2Matrix, arr).map(Math.round) - arr = Matrix.multiply(shear1Matrix, arr).map(Math.round) - arr = Matrix.multiply(translateMatrix2, arr) - - const [x1, y1] = arr - - if (x1 < 0) return; - if (y1 < 0) return; - if (x1 > width-1) return; - if (y1 > height-1) return; - - var endIndex = (y1 * width + x1) * 4 - - pixels[endIndex] = bitmap.pixels[i] - pixels[endIndex+1] = bitmap.pixels[i+1] - pixels[endIndex+2] = bitmap.pixels[i+2] - pixels[endIndex+3] = bitmap.pixels[i+3] - - })(newBitmap) - } -} - - -F.rotate = function rotate (degree = 0) { - degree = parseParamNumber(degree) - degree = degree % 360 - return function (bitmap) { - - if (degree == 0) return bitmap - - if (degree == 90 || degree == 270) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width) - } else if (degree == 180) { - var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height) - } else { - return F.rotateDegree(degree)(bitmap) - } - - const width = bitmap.width - const height = bitmap.height - - packXY((pixels, i, x, y) => { - - if (degree == 90) { - var endIndex = (x * newBitmap.width + (newBitmap.width -1 - y) ) * 4 - } else if (degree == 270) { - var endIndex = ( (newBitmap.height -1 -x) * newBitmap.width + y ) * 4 - } else if (degree == 180) { - var endIndex = ((newBitmap.height -1 -y) * newBitmap.width + (newBitmap.width -1 -x)) * 4 - } - - // console.log(startIndex, endIndex) - - newBitmap.pixels[endIndex] = bitmap.pixels[i] - newBitmap.pixels[endIndex+1] = bitmap.pixels[i+1] - newBitmap.pixels[endIndex+2] = bitmap.pixels[i+2] - newBitmap.pixels[endIndex+3] = bitmap.pixels[i+3] - - })(bitmap) - - return newBitmap - } -} - -// Pixel based - - -F.grayscale = function (amount) { - amount = parseParamNumber(amount) - let C = amount / 100; - - if (C > 1) C = 1; - - return pack((pixels, i) => { - - colorMatrix(pixels, i, [ - (0.2126 + 0.7874 * (1 - C)), (0.7152 - 0.7152 * (1 - C)), (0.0722 - 0.0722 * (1 - C)), 0, - (0.2126 - 0.2126 * (1 - C)), (0.7152 + 0.2848 * (1 - C)), (0.0722 - 0.0722 * (1 - C)), 0, - (0.2126 - 0.2126 * (1 - C)), (0.7152 - 0.7152 * (1 - C)), (0.0722 + 0.9278 * (1 - C)), 0, - 0, 0, 0, 1 - ]) - }); -} - -/* - * @param {Number} amount 0..360 - */ -F.hue = function (amount = 360) { - amount = parseParamNumber(amount) - return pack((pixels, i) => { - var r = pixels[i], g = pixels[i + 1], b = pixels[i + 2]; - - var hsv = Color.RGBtoHSV(r, g, b); - - // 0 ~ 360 - var h = hsv.h; - h += Math.abs(amount) - h = h % 360 - hsv.h = h - - var rgb = Color.HSVtoRGB(hsv); - - pixels[i] = rgb.r; - pixels[i + 1] = rgb.g; - pixels[i + 2] = rgb.b; - - }) -} - - -F.shade = function (r = 1, g = 1, b = 1) { - r = parseParamNumber(r) - g = parseParamNumber(g) - b = parseParamNumber(b) - return pack((pixels, i) => { - pixels[i] *= r; - pixels[i + 1] *= g; - pixels[i + 2] *= b; - }) - -} - -F.bitonal = function (darkColor, lightColor, threshold = 100) { - darkColor = Color.parse(darkColor); - lightColor = Color.parse(lightColor); - return pack((pixels, i) => { - - if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { - pixels[i] = darkColor.r; - pixels[i + 1] = darkColor.g; - pixels[i + 2] = darkColor.b; - } else { - pixels[i] = lightColor.r; - pixels[i + 1] = lightColor.g; - pixels[i + 2] = lightColor.b; - } - }) -} - - -/** - * F.gradient('red', 'blue', 'yellow', 'white', 10) - * F.gradient('red, blue, yellow, white, 10') - */ -F.duotone = function () { - // 전체 매개변수 기준으로 파싱 - // 색이 아닌 것 기준으로 scale 변수로 인식 - - let params = [...arguments]; - - if (params.length === 1 && typeof params[0] === 'string') { - params = Color.convertMatchesArray(params[0]) - } - - params = params.map(arg => { - const res = Color.matches(arg) - - if (!res.length) { - return { type: 'scale', value : arg } - } - - return { type: 'param', value : arg } - }) - - let scale = params.filter(it => { return it.type == 'scale' })[0] - scale = scale ? +scale.value : 256 - - params = params.filter(it => { return it.type == 'param' }).map( it => { - return it.value - }).join(',') - - let colors = Color.gradient(params, scale).map(c => { return Color.parse(c) }) - - return pack((pixels, i) => { - const colorIndex = F.clamp(Color.brightness(pixels[i] , pixels[i + 1] , pixels[i + 2])) - const newColorIndex = F.clamp(Math.floor(colorIndex * (scale / 256))) - const color = colors[newColorIndex] - - pixels[i] = color.r; - pixels[i + 1] = color.g; - pixels[i + 2] = color.b; - pixels[i + 3] = F.clamp(Math.floor(color.a * 256)); - }) -} - -F.gradient = F.duotone; - -F.tint = function (redTint = 1, greenTint = 1, blueTint = 1) { - redTint = parseParamNumber(redTint) - greenTint = parseParamNumber(greenTint) - blueTint = parseParamNumber(blueTint) - return pack((pixels, i) => { - pixels[i] += (255 - pixels[i]) * redTint; - pixels[i + 1] += (255 - pixels[i + 1]) * greenTint; - pixels[i + 2] += (255 - pixels[i + 2]) * blueTint; - }) - -} - -F.clamp = function (num) { - return Math.min(255, num) -} -/** - * - * @param {*} amount min = -128, max = 128 - */ -F.contrast = function (amount = 0) { - amount = parseParamNumber(amount) - const C = Math.max((128 + amount) / 128, 0); - - return pack((pixels, i) => { - pixels[i] = pixels[i] * C - pixels[i+1] = pixels[i+1] * C - pixels[i+2] = pixels[i+2] * C - }) -} - -F.invert = function (amount = 100) { - amount = parseParamNumber(amount) - const C = amount / 100; - - return pack((pixels, i) => { - - pixels[i] = (255 - pixels[i]) * C ; - pixels[i + 1] = (255 - pixels[i + 1]) * C; - pixels[i + 2] = (255 - pixels[i + 2]) * C; - - }) -} - -F.opacity = function (amount = 100) { - amount = parseParamNumber(amount) - const C = amount / 100; - - return pack((pixels, i) => { - pixels[i + 3] *= C; - }) -} - -/** - * change the relative darkness of (a part of an image) by overexposure to light. - * @param {*} r - * @param {*} g - * @param {*} b - */ -F.solarize = function (r, g, b) { - r = parseParamNumber(r) - g = parseParamNumber(g) - b = parseParamNumber(b) - return pack((pixels, i) => { - if (pixels[i] < r) pixels[i] = 255 - pixels[i]; - if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; - if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; - }) - -} - -/* - * @param {Number} amount 0..100 - */ -F.sepia = function (amount = 100) { - amount = parseParamNumber(amount) - let C = amount / 100; - if (C > 1) C = 1; - - return pack((pixels, i) => { - - colorMatrix(pixels, i, [ - (0.393 + 0.607 * (1 - C)), (0.769 - 0.769 * (1 - C)), (0.189 - 0.189 * (1 - C)), 0, - (0.349 - 0.349 * (1 - C)), (0.686 + 0.314 * (1 - C)), (0.168 - 0.168 * (1 - C)), 0, - (0.272 - 0.272 * (1 - C)), (0.534 - 0.534 * (1 - C)), (0.131 + 0.869 * (1 - C)), 0, - 0, 0, 0, 1 - ]) - }) -} - -F.gamma = function (amount = 1) { - amount = parseParamNumber(amount) - return pack((pixels, i) => { - pixels[i] = Math.pow(pixels[i] / 255, amount) * 255 - pixels[i+1] = Math.pow(pixels[i+1] / 255, amount) * 255 - pixels[i+2] = Math.pow(pixels[i+2] / 255, amount) * 255 - }) -} - -/** - * - * @param {Number} amount 1..100 - */ -F.noise = function (amount = 1) { - amount = parseParamNumber(amount) - return pack((pixels, i) => { - const C = Math.abs(amount) * 5 - const min = -C - const max = C - const noiseValue = Math.round(min + (Math.random() * (max - min))) - pixels[i] += noiseValue - pixels[i+1] += noiseValue - pixels[i+2] += noiseValue - }) -} - -/** - * - * @param {Number} amount from 0 to 100 - */ -F.clip = function (amount = 0) { - amount = parseParamNumber(amount) - const C = Math.abs(amount) * 2.55 - - return pack((pixels, i) => { - - for(var start = i, end = i + 2; start <= end; start++) { - if (pixels[start] > 255 - C) { - pixels[start] = 255 - } else if (pixels[start] < C) { - pixels[start] = 0 - } - } - - }) -} - -/* - * @param {Number} amount -100..100 , value < 0 is darken, value > 0 is brighten - */ -F.brightness = function (amount = 1) { - amount = parseParamNumber(amount) - const C = Math.floor(255 * (amount / 100)); - - return pack((pixels, i) => { - pixels[i] += C; - pixels[i + 1] += C; - pixels[i + 2] += C; - }) -} - -/* - * @param {Number} amount -100..100 - */ -F.saturation = function (amount = 100) { - amount = parseParamNumber(amount) - const C = amount / 100 - const L = 1 - Math.abs(C); - return pack((pixels, i) => { - - colorMatrix(pixels, i, [ - L, 0, 0, 0, - 0, L, 0, 0, - 0, 0, L, 0, - 0, 0, 0, L - ]); - }) - -} - - -/* - * @param {Number} amount 0..100 - */ -F.threshold = function (scale = 200, amount = 100) { - return F.thresholdColor(scale, amount, false) -} - -F['threshold-color'] = F.thresholdColor = function (scale = 200, amount = 100, hasColor = true) { - scale = parseParamNumber(scale) - amount = parseParamNumber(amount) - const C = amount / 100; - return pack((pixels, i) => { - var v = (C * Color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) ) >= scale ? 255 : 0; - - if (hasColor) { - - if (v == 0) { - pixels[i] = pixels[i + 1] = pixels[i + 2] = 0 - } - - } else { - pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v) - } - - }) -} - -// Matrix based - -F.convolution = function (weights, opaque = true) { - return function ({ pixels, width, height }) { - const side = Math.round(Math.sqrt(weights.length)); - const halfSide = Math.floor(side / 2); - - var w = width; - var h = height; - var sw = w; - var sh = h; - let dst = new Uint8ClampedArray(pixels.length); - const alphaFac = opaque ? 1 : 0; - - for (var y = 0; y < h; y++) { - for (var x = 0; x < w; x++) { - const sy = y; - const sx = x; - const dstIndex = (y * w + x) * 4; - - var r = 0, g = 0, b = 0, a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { - - const scy = sy + cy - halfSide; - const scx = sx + cx - halfSide; - - if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { - var srcIndex = (scy * sw + scx) * 4; - var wt = weights[cy * side + cx]; - r += pixels[srcIndex] * wt; - g += pixels[srcIndex + 1] * wt; - b += pixels[srcIndex + 2] * wt; - a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. - } - } - } - - dst[dstIndex] = r; - dst[dstIndex + 1] = g; - dst[dstIndex + 2] = b; - dst[dstIndex + 3] = a + alphaFac * (255 - a); - } - } - - return { pixels: dst, width: sw, height: sh }; - } -} - -F.identity = function () { - return F.convolution([ - 0, 0, 0, - 0, 1, 0, - 0, 0, 0 - ]); -} - -F.random = function (amount = 10, count = createRandomCount()) { - amount = parseParamNumber(amount) - return function (pixels, width, height) { - var rand = createRandRange(-1, 5, count); - return F.convolution(rand)(pixels, width, height); - } -} - - -F.grayscale2 = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - 0.3, 0.3, 0.3, 0, 0, - 0.59, 0.59, 0.59, 0, 0, - 0.11, 0.11, 0.11, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 - ], amount / 100)); -} - -F.sepia2 = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - 0.393, 0.349, 0.272, 0, 0, - 0.769, 0.686, 0.534, 0, 0, - 0.189, 0.168, 0.131, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 - ], amount / 100)); -} - -F.negative = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - -1, 0, 0, 0, 0, - 0, -1, 0, 0, 0, - 0, 0, -1, 0, 0, - 0, 0, 0, 1, 0, - 1, 1, 1, 1, 1 - ], amount / 100)); -} - -F.sharpen = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - 0, -1, 0, - -1, 5, -1, - 0, -1, 0 - ], amount / 100)); -} - -F['motion-blur'] = F.motionBlur = function () { - return F.convolution(weight([ - 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, - ], 1 / 9)); -} - -F['motion-blur-2'] = F.motionBlur2 = function () { - return F.convolution(weight([ - 1, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 1, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 1, - ], 1 / 9)); -} - -F['motion-blur-3'] = F.motionBlur3 = function () { - return F.convolution(weight([ - 1, 0, 0, 0, 1, 0, 0, 0, 1, - 0, 1, 0, 0, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 1, - ], 1 / 9)); -} - -function createBlurMatrix (amount = 3) { - const count = Math.pow(amount, 2) - const value = 1/count - return repeat (value, count) -} /** - * - * @param {Number} amount from 3 to 100 + * multi filter */ -F.blur = function (amount = 3, hasAlphaChannel = true) { - amount = parseParamNumber(amount) - - return F.convolution(createBlurMatrix(amount)) -} - -F['stack-blur'] = F.stackBlur = function (radius = 10, hasAlphaChannel = true) { - radius = parseParamNumber(radius) - - return function (bitmap) { - return StackBlur(bitmap, radius, hasAlphaChannel ) - } -} - -F['gaussian-blur'] = F.gaussianBlur = function (amount = 100) { - amount = parseParamNumber(amount) - const C = amount / 100; - - return F.convolution(weight([ - 1, 2, 1, - 2, 4, 2, - 1, 2, 1 - ], (1/16) * C )); -} - -F['gaussian-blur-5x'] = F.gaussianBlur5x = function (amount = 100) { - amount = parseParamNumber(amount) - const C = amount / 100; - return F.convolution(weight([ - 1, 4, 6, 4, 1, - 4, 16, 24, 16, 4, - 6, 24, 36, 24, 6, - 4, 16, 24, 16, 4, - 1, 4, 6, 4, 1 - ], (1/256) * C )); -} -F['unsharp-masking'] = F.unsharpMasking = function (amount = 256) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - 1, 4, 6, 4, 1, - 4, 16, 24, 16, 4, - 6, 24, -476, 24, 6, - 4, 16, 24, 16, 4, - 1, 4, 6, 4, 1 - ], -1 / amount)); -} - -F.transparency = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0.3, 0, - 0, 0, 0, 0, 1, - ], amount / 100)); -} - -F.laplacian = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - -1, -1, -1, - -1, 8, -1, - -1, -1, -1 - ], amount / 100)); -} F.laplacian.grayscale = function (amount = 100) { return F.filter(`grayscale laplacian(${amount}`) } -F.laplacian5x = function (amount = 100) { - amount = parseParamNumber(amount) - return F.convolution(weight([ - -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, - -1, -1, 24, -1, -1, - -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1 - ], amount / 100)); -} F.laplacian5x.grayscale = function () { return F.filter('grayscale laplacian5x'); } -F['kirsch-horizontal'] = F.kirschHorizontal = function (count = 1) { - count = parseParamNumber(count) - return F.convolution([ - 5, 5, 5, - -3, 0, -3, - -3, -3, -3 - ]); -} - -F['kirsch-vertical'] = F.kirschVertical = function (count = 1) { - count = parseParamNumber(count) - return F.convolution([ - 5, -3, -3, - 5, 0, -3, - 5, -3, -3 - ]); -} F.kirsch = function () { return F.filter('kirsch-horizontal kirsch-vertical'); @@ -1048,22 +105,6 @@ F.kirsch.grayscale = function () { return F.filter('grayscale kirsch'); } -F['sobel-horizontal'] = F.sobelHorizontal = function () { - return F.convolution([ - -1, -2, -1, - 0, 0, 0, - 1, 2, 1 - ]); -} - -F['sobel-vertical'] = F.sobelVertical = function () { - return F.convolution([ - -1, 0, 1, - -2, 0, 2, - -1, 0, 1 - ]); -} - F.sobel = function () { return F.filter('sobel-horizontal sobel-vertical'); } @@ -1072,24 +113,6 @@ F.sobel.grayscale = function () { return F.filter('grayscale sobel'); } -/* - * carve, mold, or stamp a design on (a surface) so that it stands out in relief. - * - * @param {Number} amount 0.0 .. 4.0 - */ -F.emboss = function (amount = 4) { - amount = parseParamNumber(amount) - return F.convolution([ - amount * (-2.0), -amount, 0.0, - -amount, 1.0, amount, - 0.0, amount, amount * 2.0, - ]); -} - -/** - * multi filter - */ - F.vintage = function () { return F.filter(`brightness(15) saturation(-20) gamma(1.8)`) } diff --git a/src/util/filter/functions.js b/src/util/filter/functions.js new file mode 100644 index 0000000..71de287 --- /dev/null +++ b/src/util/filter/functions.js @@ -0,0 +1,274 @@ +import Canvas from '../Canvas' +import Matrix from '../Matrix' + +export function weight(arr, num = 1) { + return arr.map(i => { + return i * num; + }) +} + +export function repeat (value, num) { + let arr = new Array(num) + for(let i = 0; i < num; i++) { + arr[i] = value + } + return arr; +} + +export function colorMatrix(pixels, i, matrix) { + var r = pixels[i], g = pixels[i + 1], b = pixels[i + 2], a = pixels[i + 3]; + + pixels[i] = matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[3] * a; + pixels[i+1] = matrix[4] * r + matrix[5] * g + matrix[6] * b + matrix[7] * a; + pixels[i+2] = matrix[8] * r + matrix[9] * g + matrix[10] * b + matrix[11] * a; + pixels[i+3] = matrix[12] * r + matrix[13] * g + matrix[14] * b + matrix[15] * a; + +} + +export function makeFilter(filter, F) { + + if (typeof filter == 'function') { + return filter; + } + + if (typeof filter == 'string') { + filter = [filter]; + } + + const filterName = filter.shift(); + + if (typeof filterName == 'function') { + return filterName; + } + + const params = filter; + + const filterFunction = F[filterName]; + + if (!filterFunction) { + throw new Error(`${filterName} is not filter. please check filter name.`) + } + return filterFunction.apply(filterFunction, params); +} + +export function each(len, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex); + } +} + +export function eachXY(len, width, callback) { + for (var i = 0, xyIndex = 0; i < len; i += 4, xyIndex++) { + callback(i, xyIndex % width, Math.floor(xyIndex / width) ); + } +} + +export function createRandRange(min, max, count) { + var result = []; + + for (var i = 1; i <= count; i++) { + var num = Math.random() * (max - min) + min; + var sign = (Math.floor(Math.random() * 10) % 2 == 0) ? -1 : 1; + result.push(sign * num); + } + + result.sort(); + + const centerIndex = Math.floor(count / 2); + var a = result[centerIndex]; + result[centerIndex] = result[0]; + result[0] = a; + + return result; +} + +export function createRandomCount() { + return [3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10].sort(function (a, b) { + return 0.5 - Math.random(); + })[0]; +} + +export function createBitmap(length, width, height) { + return { pixels: new Uint8ClampedArray(length), width, height } +} + +export function getBitmap(bitmap, area) { + return Canvas.getBitmap(bitmap, area); +} + +export function putBitmap(bitmap, subBitmap, area) { + return Canvas.putBitmap(bitmap, subBitmap, area); +} + +export function parseParamNumber (param) { + if (typeof param === 'string') { + param = param.replace(/deg/, '') + param = param.replace(/px/, '') + } + return +param +} + +const filter_regexp = /(([\w_\-]+)(\(([^\)]*)\))?)+/gi; +const filter_split = ' ' + +export { filter_regexp, filter_split } + +export function pack(callback) { + return function (bitmap) { + each(bitmap.pixels.length, (i, xyIndex) => { + callback(bitmap.pixels, i, xyIndex) + }) + return bitmap; + } +} + + +const ColorListIndex = [0, 1, 2, 3] + +export function swapColor (pixels, startIndex, endIndex) { + + ColorListIndex.forEach(i => { + var temp = pixels[startIndex + i] + pixels[startIndex + i] = pixels[endIndex + i] + pixels[endIndex + i] = temp + }) +} + +export function packXY(callback) { + return function (bitmap) { + eachXY(bitmap.pixels.length, bitmap.width, (i, x, y) => { + callback(bitmap.pixels, i, x, y) + }) + return bitmap; + } +} + +export function radian (degree) { + return Matrix.CONSTANT.radian(degree) +} + + +export function createBlurMatrix (amount = 3) { + const count = Math.pow(amount, 2) + const value = 1/count + return repeat (value, count) +} + +export function convolution(weights, opaque = true) { + return function ({ pixels, width, height }) { + const side = Math.round(Math.sqrt(weights.length)); + const halfSide = Math.floor(side / 2); + + var w = width; + var h = height; + var sw = w; + var sh = h; + let dst = new Uint8ClampedArray(pixels.length); + const alphaFac = opaque ? 1 : 0; + + for (var y = 0; y < h; y++) { + for (var x = 0; x < w; x++) { + const sy = y; + const sx = x; + const dstIndex = (y * w + x) * 4; + + var r = 0, g = 0, b = 0, a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + + const scy = sy + cy - halfSide; + const scx = sx + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + var srcIndex = (scy * sw + scx) * 4; + var wt = weights[cy * side + cx]; + r += pixels[srcIndex] * wt; + g += pixels[srcIndex + 1] * wt; + b += pixels[srcIndex + 2] * wt; + a += pixels[srcIndex + 3] * wt; // weight 를 곱한 값을 계속 더한다. + } + } + } + + dst[dstIndex] = r; + dst[dstIndex + 1] = g; + dst[dstIndex + 2] = b; + dst[dstIndex + 3] = a + alphaFac * (255 - a); + } + } + + return { pixels: dst, width: sw, height: sh }; + } +} + + +export function matches (str) { + var ret = Color.convertMatches(str) + const matches = ret.str.match(filter_regexp); + let result = []; + + if (!matches) { + return result; + } + + result = matches.map((it) => { + return { filter: it, origin: Color.reverseMatches(it, ret.matches) } + }) + + var pos = { next: 0 } + result = result.map(item => { + + const startIndex = str.indexOf(item.origin, pos.next); + + item.startIndex = startIndex; + item.endIndex = startIndex + item.origin.length; + + item.arr = parseFilter(item.origin) + + pos.next = item.endIndex; + + return item + }).filter(it => { + if (!it.arr.length) return false + return true + }) + + return result; +} + +/** + * Filter Parser + * + * F.parseFilter('blur(30)') == ['blue', '30'] + * F.parseFilter('gradient(white, black, 3)') == ['gradient', 'white', 'black', '3'] + * + * @param {String} filterString + */ +export function parseFilter (filterString) { + + var ret = Color.convertMatches(filterString) + const matches = ret.str.match(filter_regexp); + + if (!matches[0]) { + return [] + } + + var arr = matches[0].split('(') + + var filterName = arr.shift() + var filterParams = [] + + if (arr.length) { + filterParams = arr.shift().split(')')[0].split(',').map(f => { + return Color.reverseMatches(f, ret.matches) + }) + } + + var result = [filterName, ...filterParams].map(Color.trim) + + return result +} + +export function clamp (num) {ß + return Math.min(255, num) +} diff --git a/src/util/filter/image/crop.js b/src/util/filter/image/crop.js new file mode 100644 index 0000000..67a4bf1 --- /dev/null +++ b/src/util/filter/image/crop.js @@ -0,0 +1,16 @@ +import { createBitmap } from '../functions' + +export default function crop (startX = 0, startY = 0, width, height) { + + const newBitmap = createBitmap(width * height * 4, width, height) + + return function (bitmap) { + for (var y = startY, realY = 0; y < height; y++, realY++) { + for (var x = startX, realX = 0; x < width; x++, realX++) { + newBitmap.pixels[realY * width * realX] = bitmap.pixels[y * width * x] + } + } + + return newBitmap; + } +} diff --git a/src/util/filter/image/flipH.js b/src/util/filter/image/flipH.js new file mode 100644 index 0000000..f379bb2 --- /dev/null +++ b/src/util/filter/image/flipH.js @@ -0,0 +1,23 @@ +import {swapColor} from '../functions' +export default function flipH () { + return function (bitmap) { + + const width = bitmap.width + const height = bitmap.height + const isCenter = width % 2 == 1 ? 1 : 0 + + const halfWidth = isCenter ? Math.floor(width / 2) : width / 2 ; + + for (var y = 0; y < height; y++) { + for (var x = 0; x < halfWidth; x++) { + + var startIndex = (y * width + x) * 4 + var endIndex = (y * width + (width -1 - x) ) * 4 + swapColor(bitmap.pixels, startIndex, endIndex) + + } + } + + return bitmap; + } +} diff --git a/src/util/filter/image/flipV.js b/src/util/filter/image/flipV.js new file mode 100644 index 0000000..c91bda7 --- /dev/null +++ b/src/util/filter/image/flipV.js @@ -0,0 +1,25 @@ +import { + swapColor +} from '../functions' +export default function flipV () { + return function (bitmap) { + + const width = bitmap.width + const height = bitmap.height + const isCenter = height % 2 == 1 ? 1 : 0 + + const halfHeight = isCenter ? Math.floor(height / 2) : height / 2 ; + + for (var y = 0; y < halfHeight; y++) { + for (var x = 0; x < width; x++) { + + var startIndex = (y * width + x) * 4 + var endIndex = ((height -1 - y) * width + x ) * 4 + swapColor(bitmap.pixels, startIndex, endIndex) + + } + } + + return bitmap; + } +} \ No newline at end of file diff --git a/src/util/filter/image/index.js b/src/util/filter/image/index.js new file mode 100644 index 0000000..0b26e2f --- /dev/null +++ b/src/util/filter/image/index.js @@ -0,0 +1,16 @@ +import crop from './crop' +import resize from './resize' +import flipV from './flipV' +import flipH from './flipH' +import rotate from './rotate' +import rotateDegree from './rotateDegree' + +export default { + crop, + resize, + flipH, + flipV, + rotate, + rotateDegree, + 'rotate-degree' : rotateDegree +} \ No newline at end of file diff --git a/src/util/filter/image/resize.js b/src/util/filter/image/resize.js new file mode 100644 index 0000000..133dd65 --- /dev/null +++ b/src/util/filter/image/resize.js @@ -0,0 +1,18 @@ +import Canvas from '../../Canvas' +// Image manupulate +export default function resize (dstWidth, dstHeight) { + return function (bitmap) { + + var c = Canvas.drawPixels(bitmap); + var context = c.getContext('2d'); + + c.width = dstWidth; + c.height = dstHeight; + + return { + pixels: new Uint8ClampedArray(context.getImageData(0, 0, dstWidth, dstHeight).data), + width: dstWidth, + height: dstHeight + } + } +} \ No newline at end of file diff --git a/src/util/filter/image/rotate.js b/src/util/filter/image/rotate.js new file mode 100644 index 0000000..ab2a50b --- /dev/null +++ b/src/util/filter/image/rotate.js @@ -0,0 +1,46 @@ +import { + parseParamNumber, + packXY, + createBitmap +} from '../functions' + +import rotateDegree from './rotateDegree' + +export default function rotate (degree = 0) { + degree = parseParamNumber(degree) + degree = degree % 360 + return function (bitmap) { + + if (degree == 0) return bitmap + + if (degree == 90 || degree == 270) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.height, bitmap.width) + } else if (degree == 180) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height) + } else { + return rotateDegree(degree)(bitmap) + } + + const width = bitmap.width + const height = bitmap.height + + packXY((pixels, i, x, y) => { + + if (degree == 90) { + var endIndex = (x * newBitmap.width + (newBitmap.width -1 - y) ) * 4 + } else if (degree == 270) { + var endIndex = ( (newBitmap.height -1 -x) * newBitmap.width + y ) * 4 + } else if (degree == 180) { + var endIndex = ((newBitmap.height -1 -y) * newBitmap.width + (newBitmap.width -1 -x)) * 4 + } + + newBitmap.pixels[endIndex] = bitmap.pixels[i] + newBitmap.pixels[endIndex+1] = bitmap.pixels[i+1] + newBitmap.pixels[endIndex+2] = bitmap.pixels[i+2] + newBitmap.pixels[endIndex+3] = bitmap.pixels[i+3] + + })(bitmap) + + return newBitmap + } +} \ No newline at end of file diff --git a/src/util/filter/image/rotateDegree.js b/src/util/filter/image/rotateDegree.js new file mode 100644 index 0000000..883c5e8 --- /dev/null +++ b/src/util/filter/image/rotateDegree.js @@ -0,0 +1,53 @@ +import Matrix from '../../Matrix' +import { + createBitmap, + packXY +} from '../functions' + +export default function rotateDegree(angle, cx = 'center', cy = 'center') { + // const r = F.radian(angle) + + return function (bitmap) { + var newBitmap = createBitmap(bitmap.pixels.length, bitmap.width, bitmap.height) + const width = bitmap.width + const height = bitmap.height + + if (cx == 'center') { + cx = Math.floor(width / 2); + } + + if (cy == 'center') { + cy = Math.floor(height/ 2); + } + + const translateMatrix = Matrix.CONSTANT.translate(-cx, -cy) + const translateMatrix2 = Matrix.CONSTANT.translate(cx, cy) + const shear1Matrix = Matrix.CONSTANT.shear1(angle) + const shear2Matrix = Matrix.CONSTANT.shear2(angle) + + return packXY((pixels, i, x, y) => { + // console.log(x, y, i) + let arr = Matrix.multiply(translateMatrix, [x, y, 1]) + + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round) + arr = Matrix.multiply(shear2Matrix, arr).map(Math.round) + arr = Matrix.multiply(shear1Matrix, arr).map(Math.round) + arr = Matrix.multiply(translateMatrix2, arr) + + const [x1, y1] = arr + + if (x1 < 0) return; + if (y1 < 0) return; + if (x1 > width-1) return; + if (y1 > height-1) return; + + var endIndex = (y1 * width + x1) * 4 + + pixels[endIndex] = bitmap.pixels[i] + pixels[endIndex+1] = bitmap.pixels[i+1] + pixels[endIndex+2] = bitmap.pixels[i+2] + pixels[endIndex+3] = bitmap.pixels[i+3] + + })(newBitmap) + } +} \ No newline at end of file diff --git a/src/util/filter/index.js b/src/util/filter/index.js new file mode 100644 index 0000000..3d6599d --- /dev/null +++ b/src/util/filter/index.js @@ -0,0 +1,9 @@ +import image from './image/index' +import pixel from './pixel/index' +import matrix from './matrix/index' + +export default { + ...image, + ...pixel, + ...matrix +} \ No newline at end of file diff --git a/src/util/filter/matrix/blur.js b/src/util/filter/matrix/blur.js new file mode 100644 index 0000000..4026f1f --- /dev/null +++ b/src/util/filter/matrix/blur.js @@ -0,0 +1,12 @@ +import { + convolution, + parseParamNumber, + createBlurMatrix +} from '../functions' + +export default function (amount = 3, hasAlphaChannel = true) { + + amount = parseParamNumber(amount) + + return convolution(createBlurMatrix(amount)) +} \ No newline at end of file diff --git a/src/util/filter/matrix/emboss.js b/src/util/filter/matrix/emboss.js new file mode 100644 index 0000000..cbc7c51 --- /dev/null +++ b/src/util/filter/matrix/emboss.js @@ -0,0 +1,17 @@ +import { + parseParamNumber, + convolution +} from '../functions' +/* + * carve, mold, or stamp a design on (a surface) so that it stands out in relief. + * + * @param {Number} amount 0.0 .. 4.0 + */ +export default function emboss (amount = 4) { + amount = parseParamNumber(amount) + return convolution([ + amount * (-2.0), -amount, 0.0, + -amount, 1.0, amount, + 0.0, amount, amount * 2.0, + ]); +} diff --git a/src/util/filter/matrix/gaussian-blur-5x.js b/src/util/filter/matrix/gaussian-blur-5x.js new file mode 100644 index 0000000..77053c4 --- /dev/null +++ b/src/util/filter/matrix/gaussian-blur-5x.js @@ -0,0 +1,17 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function gaussianBlur5x (amount = 100) { + amount = parseParamNumber(amount) + const C = amount / 100; + return convolution(weight([ + 1, 4, 6, 4, 1, + 4, 16, 24, 16, 4, + 6, 24, 36, 24, 6, + 4, 16, 24, 16, 4, + 1, 4, 6, 4, 1 + ], (1/256) * C )); +} \ No newline at end of file diff --git a/src/util/filter/matrix/gaussian-blur.js b/src/util/filter/matrix/gaussian-blur.js new file mode 100644 index 0000000..32c2a46 --- /dev/null +++ b/src/util/filter/matrix/gaussian-blur.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function gaussianBlur (amount = 100) { + amount = parseParamNumber(amount) + const C = amount / 100; + + return convolution(weight([ + 1, 2, 1, + 2, 4, 2, + 1, 2, 1 + ], (1/16) * C )); +} \ No newline at end of file diff --git a/src/util/filter/matrix/grayscale2.js b/src/util/filter/matrix/grayscale2.js new file mode 100644 index 0000000..46ce4b7 --- /dev/null +++ b/src/util/filter/matrix/grayscale2.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function grayscale2 (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + 0.3, 0.3, 0.3, 0, 0, + 0.59, 0.59, 0.59, 0, 0, + 0.11, 0.11, 0.11, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], amount / 100)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/identity.js b/src/util/filter/matrix/identity.js new file mode 100644 index 0000000..a58c911 --- /dev/null +++ b/src/util/filter/matrix/identity.js @@ -0,0 +1,11 @@ +import { + convolution +} from '../functions' + +export default function identity () { + return convolution([ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ]); +} \ No newline at end of file diff --git a/src/util/filter/matrix/index.js b/src/util/filter/matrix/index.js new file mode 100644 index 0000000..d8090e0 --- /dev/null +++ b/src/util/filter/matrix/index.js @@ -0,0 +1,60 @@ +import blur from './blur' +import emboss from './emboss' +import gaussianBlur from './gaussian-blur' +import gaussianBlur5x from './gaussian-blur-5x' +import grayscale2 from './grayscale2' +import identity from './identity' +import kirschHorizontal from './kirsch-horizontal' +import kirschVertical from './kirsch-vertical' +import laplacian from './laplacian' +import laplacian5x from './laplacian-5x' +import motionBlur from './motion-blur' +import motionBlur2 from './motion-blur-2' +import motionBlur3 from './motion-blur-3' +import negative from './negative' +import random from './random' +import sepia2 from './sepia2' +import sharpen from './sharpen' +import sobelHorizontal from './sobel-horizontal' +import sobelVertical from './sobel-vertical' +import stackBlur from './stack-blur' +import transparency from './transparency' +import unsharpMasking from './unsharp-masking' + + +export default { + blur, + emboss, + gaussianBlur, + 'gaussian-blur': gaussianBlur, + gaussianBlur5x, + 'gaussian-blur-5x': gaussianBlur5x, + grayscale2, + identity, + kirschHorizontal, + 'kirsch-horizontal': kirschHorizontal, + kirschVertical, + 'kirsch-vertical': kirschVertical, + laplacian, + laplacian5x, + 'laplacian-5x': laplacian5x, + motionBlur, + 'motion-blur': motionBlur, + motionBlur2, + 'motion-blur-2': motionBlur2, + motionBlur3, + 'motion-blur-3': motionBlur3, + negative, + random, + sepia2, + sharpen, + sobelHorizontal, + 'sobel-horizontal': sobelHorizontal, + sobelVertical, + 'sobel-vertical': sobelVertical, + stackBlur, + 'stack-blur': stackBlur, + transparency, + unsharpMasking, + 'unsharp-masking': unsharpMasking +} \ No newline at end of file diff --git a/src/util/filter/matrix/kirsch-horizontal.js b/src/util/filter/matrix/kirsch-horizontal.js new file mode 100644 index 0000000..485d773 --- /dev/null +++ b/src/util/filter/matrix/kirsch-horizontal.js @@ -0,0 +1,13 @@ +import { + parseParamNumber, + convolution +} from '../functions' + +export default function kirschHorizontal (count = 1) { + count = parseParamNumber(count) + return convolution([ + 5, 5, 5, + -3, 0, -3, + -3, -3, -3 + ]); +} \ No newline at end of file diff --git a/src/util/filter/matrix/kirsch-vertical.js b/src/util/filter/matrix/kirsch-vertical.js new file mode 100644 index 0000000..801ee10 --- /dev/null +++ b/src/util/filter/matrix/kirsch-vertical.js @@ -0,0 +1,13 @@ +import { + parseParamNumber, + convolution +} from '../functions' + +export default function kirschVertical (count = 1) { + count = parseParamNumber(count) + return convolution([ + 5, -3, -3, + 5, 0, -3, + 5, -3, -3 + ]); +} \ No newline at end of file diff --git a/src/util/filter/matrix/laplacian-5x.js b/src/util/filter/matrix/laplacian-5x.js new file mode 100644 index 0000000..ed56a20 --- /dev/null +++ b/src/util/filter/matrix/laplacian-5x.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function laplacian5x (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, 24, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1 + ], amount / 100)); +} diff --git a/src/util/filter/matrix/laplacian.js b/src/util/filter/matrix/laplacian.js new file mode 100644 index 0000000..21902a3 --- /dev/null +++ b/src/util/filter/matrix/laplacian.js @@ -0,0 +1,14 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function laplacian (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + -1, -1, -1, + -1, 8, -1, + -1, -1, -1 + ], amount / 100)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/motion-blur-2.js b/src/util/filter/matrix/motion-blur-2.js new file mode 100644 index 0000000..8e8d31c --- /dev/null +++ b/src/util/filter/matrix/motion-blur-2.js @@ -0,0 +1,18 @@ +import { + convolution, + weight +} from '../functions' + +export default function motionBlur2 () { + return convolution(weight([ + 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, + ], 1 / 9)); +} diff --git a/src/util/filter/matrix/motion-blur-3.js b/src/util/filter/matrix/motion-blur-3.js new file mode 100644 index 0000000..aadf3ea --- /dev/null +++ b/src/util/filter/matrix/motion-blur-3.js @@ -0,0 +1,19 @@ +import { + convolution, + weight +} from '../functions' + + +export default function motionBlur3 () { + return convolution(weight([ + 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 1, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 1, + ], 1 / 9)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/motion-blur.js b/src/util/filter/matrix/motion-blur.js new file mode 100644 index 0000000..642eb6f --- /dev/null +++ b/src/util/filter/matrix/motion-blur.js @@ -0,0 +1,18 @@ +import { + convolution, + weight +} from '../functions' + +export default function motionBlur () { + return convolution(weight([ + 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, + ], 1 / 9)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/negative.js b/src/util/filter/matrix/negative.js new file mode 100644 index 0000000..c782952 --- /dev/null +++ b/src/util/filter/matrix/negative.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function negative (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + -1, 0, 0, 0, 0, + 0, -1, 0, 0, 0, + 0, 0, -1, 0, 0, + 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1 + ], amount / 100)); +} diff --git a/src/util/filter/matrix/random.js b/src/util/filter/matrix/random.js new file mode 100644 index 0000000..be5bd27 --- /dev/null +++ b/src/util/filter/matrix/random.js @@ -0,0 +1,14 @@ +import { + createRandomCount, + parseParamNumber, + createRandRange, + convolution +} from '../functions' + +export default function random (amount = 10, count = createRandomCount()) { + amount = parseParamNumber(amount) + return function (pixels, width, height) { + var rand = createRandRange(-1, 5, count); + return convolution(rand)(pixels, width, height); + } +} diff --git a/src/util/filter/matrix/sepia2.js b/src/util/filter/matrix/sepia2.js new file mode 100644 index 0000000..1358d6e --- /dev/null +++ b/src/util/filter/matrix/sepia2.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function sepia2 (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + 0.393, 0.349, 0.272, 0, 0, + 0.769, 0.686, 0.534, 0, 0, + 0.189, 0.168, 0.131, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], amount / 100)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/sharpen.js b/src/util/filter/matrix/sharpen.js new file mode 100644 index 0000000..f8bad0d --- /dev/null +++ b/src/util/filter/matrix/sharpen.js @@ -0,0 +1,14 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function sharpen (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + ], amount / 100)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/sobel-horizontal.js b/src/util/filter/matrix/sobel-horizontal.js new file mode 100644 index 0000000..85e4f95 --- /dev/null +++ b/src/util/filter/matrix/sobel-horizontal.js @@ -0,0 +1,11 @@ +import { + convolution +} from '../functions' + +export default function sobelHorizontal () { + return convolution([ + -1, -2, -1, + 0, 0, 0, + 1, 2, 1 + ]); +} diff --git a/src/util/filter/matrix/sobel-vertical.js b/src/util/filter/matrix/sobel-vertical.js new file mode 100644 index 0000000..bd3b005 --- /dev/null +++ b/src/util/filter/matrix/sobel-vertical.js @@ -0,0 +1,11 @@ +import { + convolution +} from '../functions' + +export default function sobelVertical () { + return convolution([ + -1, 0, 1, + -2, 0, 2, + -1, 0, 1 + ]); +} diff --git a/src/util/filter/matrix/stack-blur.js b/src/util/filter/matrix/stack-blur.js new file mode 100644 index 0000000..c81ec1e --- /dev/null +++ b/src/util/filter/matrix/stack-blur.js @@ -0,0 +1,13 @@ +import { + parseParamNumber +} from '../functions' + +import StackBlur from '../../blur/StackBlur' + +export default function (radius = 10, hasAlphaChannel = true) { + radius = parseParamNumber(radius) + + return function (bitmap) { + return StackBlur(bitmap, radius, hasAlphaChannel ) + } +} \ No newline at end of file diff --git a/src/util/filter/matrix/transparency.js b/src/util/filter/matrix/transparency.js new file mode 100644 index 0000000..25a74f8 --- /dev/null +++ b/src/util/filter/matrix/transparency.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function transparency (amount = 100) { + amount = parseParamNumber(amount) + return convolution(weight([ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0.3, 0, + 0, 0, 0, 0, 1, + ], amount / 100)); +} \ No newline at end of file diff --git a/src/util/filter/matrix/unsharp-masking.js b/src/util/filter/matrix/unsharp-masking.js new file mode 100644 index 0000000..70a31d4 --- /dev/null +++ b/src/util/filter/matrix/unsharp-masking.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + convolution, + weight +} from '../functions' + +export default function unsharpMasking (amount = 256) { + amount = parseParamNumber(amount) + return convolution(weight([ + 1, 4, 6, 4, 1, + 4, 16, 24, 16, 4, + 6, 24, -476, 24, 6, + 4, 16, 24, 16, 4, + 1, 4, 6, 4, 1 + ], -1 / amount)); +} \ No newline at end of file diff --git a/src/util/filter/pixel/bitonal.js b/src/util/filter/pixel/bitonal.js new file mode 100644 index 0000000..82a45d9 --- /dev/null +++ b/src/util/filter/pixel/bitonal.js @@ -0,0 +1,20 @@ +import Color from '../../Color' +import { pack } from '../functions' + + +export default function bitonal(darkColor, lightColor, threshold = 100) { + darkColor = Color.parse(darkColor); + lightColor = Color.parse(lightColor); + return pack((pixels, i) => { + + if (pixels[i] + pixels[i + 1] + pixels[i + 2] <= threshold) { + pixels[i] = darkColor.r; + pixels[i + 1] = darkColor.g; + pixels[i + 2] = darkColor.b; + } else { + pixels[i] = lightColor.r; + pixels[i + 1] = lightColor.g; + pixels[i + 2] = lightColor.b; + } + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/brightness.js b/src/util/filter/pixel/brightness.js new file mode 100644 index 0000000..2c720b0 --- /dev/null +++ b/src/util/filter/pixel/brightness.js @@ -0,0 +1,18 @@ +import { + parseParamNumber, + pack +} from '../functions' + +/* + * @param {Number} amount -100..100 , value < 0 is darken, value > 0 is brighten + */ +export default function brightness (amount = 1) { + amount = parseParamNumber(amount) + const C = Math.floor(255 * (amount / 100)); + + return pack((pixels, i) => { + pixels[i] += C; + pixels[i + 1] += C; + pixels[i + 2] += C; + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/clip.js b/src/util/filter/pixel/clip.js new file mode 100644 index 0000000..32a2a91 --- /dev/null +++ b/src/util/filter/pixel/clip.js @@ -0,0 +1,25 @@ +import { + parseParamNumber, + pack +} from '../functions' + +/** + * + * @param {Number} amount from 0 to 100 + */ +export default function clip (amount = 0) { + amount = parseParamNumber(amount) + const C = Math.abs(amount) * 2.55 + + return pack((pixels, i) => { + + for(var start = i, end = i + 2; start <= end; start++) { + if (pixels[start] > 255 - C) { + pixels[start] = 255 + } else if (pixels[start] < C) { + pixels[start] = 0 + } + } + + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/contrast.js b/src/util/filter/pixel/contrast.js new file mode 100644 index 0000000..efc2717 --- /dev/null +++ b/src/util/filter/pixel/contrast.js @@ -0,0 +1,18 @@ +import { + parseParamNumber, + pack +} from '../functions' +/** + * + * @param {*} amount min = -128, max = 128 + */ +export default function contrast(amount = 0) { + amount = parseParamNumber(amount) + const C = Math.max((128 + amount) / 128, 0); + + return pack((pixels, i) => { + pixels[i] = pixels[i] * C + pixels[i+1] = pixels[i+1] * C + pixels[i+2] = pixels[i+2] * C + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/gamma.js b/src/util/filter/pixel/gamma.js new file mode 100644 index 0000000..fec69a3 --- /dev/null +++ b/src/util/filter/pixel/gamma.js @@ -0,0 +1,13 @@ +import { + parseParamNumber, + pack +} from '../functions' + +export default function gamma (amount = 1) { + amount = parseParamNumber(amount) + return pack((pixels, i) => { + pixels[i] = Math.pow(pixels[i] / 255, amount) * 255 + pixels[i+1] = Math.pow(pixels[i+1] / 255, amount) * 255 + pixels[i+2] = Math.pow(pixels[i+2] / 255, amount) * 255 + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/gradient.js b/src/util/filter/pixel/gradient.js new file mode 100644 index 0000000..4f0a0c9 --- /dev/null +++ b/src/util/filter/pixel/gradient.js @@ -0,0 +1,49 @@ +import Color from '../../Color' +import { + clamp, + pack +} from '../functions' +/** + * F.gradient('red', 'blue', 'yellow', 'white', 10) + * F.gradient('red, blue, yellow, white, 10') + */ +export default function gradient () { + // 전체 매개변수 기준으로 파싱 + // 색이 아닌 것 기준으로 scale 변수로 인식 + + let params = [...arguments]; + + if (params.length === 1 && typeof params[0] === 'string') { + params = Color.convertMatchesArray(params[0]) + } + + params = params.map(arg => { + const res = Color.matches(arg) + + if (!res.length) { + return { type: 'scale', value : arg } + } + + return { type: 'param', value : arg } + }) + + let scale = params.filter(it => { return it.type == 'scale' })[0] + scale = scale ? +scale.value : 256 + + params = params.filter(it => { return it.type == 'param' }).map( it => { + return it.value + }).join(',') + + let colors = Color.gradient(params, scale).map(c => { return Color.parse(c) }) + + return pack((pixels, i) => { + const colorIndex = clamp(Color.brightness(pixels[i] , pixels[i + 1] , pixels[i + 2])) + const newColorIndex = clamp(Math.floor(colorIndex * (scale / 256))) + const color = colors[newColorIndex] + + pixels[i] = color.r; + pixels[i + 1] = color.g; + pixels[i + 2] = color.b; + pixels[i + 3] = clamp(Math.floor(color.a * 256)); + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/grayscale.js b/src/util/filter/pixel/grayscale.js new file mode 100644 index 0000000..427c252 --- /dev/null +++ b/src/util/filter/pixel/grayscale.js @@ -0,0 +1,22 @@ +import { + parseParamNumber, + pack, + colorMatrix +} from '../functions' + +export default function grayscale (amount) { + amount = parseParamNumber(amount) + let C = amount / 100; + + if (C > 1) C = 1; + + return pack((pixels, i) => { + + colorMatrix(pixels, i, [ + (0.2126 + 0.7874 * (1 - C)), (0.7152 - 0.7152 * (1 - C)), (0.0722 - 0.0722 * (1 - C)), 0, + (0.2126 - 0.2126 * (1 - C)), (0.7152 + 0.2848 * (1 - C)), (0.0722 - 0.0722 * (1 - C)), 0, + (0.2126 - 0.2126 * (1 - C)), (0.7152 - 0.7152 * (1 - C)), (0.0722 + 0.9278 * (1 - C)), 0, + 0, 0, 0, 1 + ]) + }); +} \ No newline at end of file diff --git a/src/util/filter/pixel/hue.js b/src/util/filter/pixel/hue.js new file mode 100644 index 0000000..f1a4615 --- /dev/null +++ b/src/util/filter/pixel/hue.js @@ -0,0 +1,29 @@ +import { + parseParamNumber, + pack +} from '../functions' + +/* + * @param {Number} amount 0..360 + */ +export default function hue (amount = 360) { + amount = parseParamNumber(amount) + return pack((pixels, i) => { + var r = pixels[i], g = pixels[i + 1], b = pixels[i + 2]; + + var hsv = Color.RGBtoHSV(r, g, b); + + // 0 ~ 360 + var h = hsv.h; + h += Math.abs(amount) + h = h % 360 + hsv.h = h + + var rgb = Color.HSVtoRGB(hsv); + + pixels[i] = rgb.r; + pixels[i + 1] = rgb.g; + pixels[i + 2] = rgb.b; + + }) +} diff --git a/src/util/filter/pixel/index.js b/src/util/filter/pixel/index.js new file mode 100644 index 0000000..9f4c2bd --- /dev/null +++ b/src/util/filter/pixel/index.js @@ -0,0 +1,38 @@ + +import bitonal from './bitonal' +import brightness from './brightness' +import clip from './clip' +import contrast from './contrast' +import gamma from './gamma' +import gradient from './gradient' +import grayscale from './grayscale' +import hue from './hue' +import invert from './invert' +import noise from './noise' +import opacity from './opacity' +import saturation from './saturation' +import sepia from './sepia' +import shade from './shade' +import solarize from './solarize' +import threshold from './threshold' +import thresholdColor from './threshold-color' + +export default { + bitonal, + brightness, + clip, + contrast, + gamma, + gradient, + grayscale, + hue, + invert, + noise, + opacity, + saturation, + sepia, + shade, + solarize, + threshold, + 'threshold-color': thresholdColor, +} \ No newline at end of file diff --git a/src/util/filter/pixel/invert.js b/src/util/filter/pixel/invert.js new file mode 100644 index 0000000..18ced3a --- /dev/null +++ b/src/util/filter/pixel/invert.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + pack +} from '../functions' +export default function invert (amount = 100) { + amount = parseParamNumber(amount) + const C = amount / 100; + + return pack((pixels, i) => { + + pixels[i] = (255 - pixels[i]) * C ; + pixels[i + 1] = (255 - pixels[i + 1]) * C; + pixels[i + 2] = (255 - pixels[i + 2]) * C; + + }) +} diff --git a/src/util/filter/pixel/noise.js b/src/util/filter/pixel/noise.js new file mode 100644 index 0000000..7be281a --- /dev/null +++ b/src/util/filter/pixel/noise.js @@ -0,0 +1,21 @@ +import { + parseParamNumber, + pack +} from '../functions' + +/** + * + * @param {Number} amount 1..100 + */ +export default function noise (amount = 1) { + amount = parseParamNumber(amount) + return pack((pixels, i) => { + const C = Math.abs(amount) * 5 + const min = -C + const max = C + const noiseValue = Math.round(min + (Math.random() * (max - min))) + pixels[i] += noiseValue + pixels[i+1] += noiseValue + pixels[i+2] += noiseValue + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/opacity.js b/src/util/filter/pixel/opacity.js new file mode 100644 index 0000000..b58c9e7 --- /dev/null +++ b/src/util/filter/pixel/opacity.js @@ -0,0 +1,14 @@ +import { + parseParamNumber, + pack +} from '../functions' + + +export default function opacity (amount = 100) { + amount = parseParamNumber(amount) + const C = amount / 100; + + return pack((pixels, i) => { + pixels[i + 3] *= C; + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/saturation.js b/src/util/filter/pixel/saturation.js new file mode 100644 index 0000000..8911e99 --- /dev/null +++ b/src/util/filter/pixel/saturation.js @@ -0,0 +1,24 @@ +import { + parseParamNumber, + pack, + colorMatrix +} from '../functions' + +/* + * @param {Number} amount -100..100 + */ +export default function saturation (amount = 100) { + amount = parseParamNumber(amount) + const C = amount / 100 + const L = 1 - Math.abs(C); + return pack((pixels, i) => { + + colorMatrix(pixels, i, [ + L, 0, 0, 0, + 0, L, 0, 0, + 0, 0, L, 0, + 0, 0, 0, L + ]); + }) + +} \ No newline at end of file diff --git a/src/util/filter/pixel/sepia.js b/src/util/filter/pixel/sepia.js new file mode 100644 index 0000000..7cb25d7 --- /dev/null +++ b/src/util/filter/pixel/sepia.js @@ -0,0 +1,24 @@ +import { + parseParamNumber, + pack, + colorMatrix +} from '../functions' + +/* + * @param {Number} amount 0..100 + */ +export default function sepia (amount = 100) { + amount = parseParamNumber(amount) + let C = amount / 100; + if (C > 1) C = 1; + + return pack((pixels, i) => { + + colorMatrix(pixels, i, [ + (0.393 + 0.607 * (1 - C)), (0.769 - 0.769 * (1 - C)), (0.189 - 0.189 * (1 - C)), 0, + (0.349 - 0.349 * (1 - C)), (0.686 + 0.314 * (1 - C)), (0.168 - 0.168 * (1 - C)), 0, + (0.272 - 0.272 * (1 - C)), (0.534 - 0.534 * (1 - C)), (0.131 + 0.869 * (1 - C)), 0, + 0, 0, 0, 1 + ]) + }) +} \ No newline at end of file diff --git a/src/util/filter/pixel/shade.js b/src/util/filter/pixel/shade.js new file mode 100644 index 0000000..e23992c --- /dev/null +++ b/src/util/filter/pixel/shade.js @@ -0,0 +1,16 @@ +import { + parseParamNumber, + pack +} from '../functions' + +export default function shade(r = 1, g = 1, b = 1) { + r = parseParamNumber(r) + g = parseParamNumber(g) + b = parseParamNumber(b) + return pack((pixels, i) => { + pixels[i] *= r; + pixels[i + 1] *= g; + pixels[i + 2] *= b; + }) + +} \ No newline at end of file diff --git a/src/util/filter/pixel/solarize.js b/src/util/filter/pixel/solarize.js new file mode 100644 index 0000000..b54fe4c --- /dev/null +++ b/src/util/filter/pixel/solarize.js @@ -0,0 +1,21 @@ +import { + parseParamNumber, + pack +} from '../functions' +/** + * change the relative darkness of (a part of an image) by overexposure to light. + * @param {*} r + * @param {*} g + * @param {*} b + */ +export default function solarize (r, g, b) { + r = parseParamNumber(r) + g = parseParamNumber(g) + b = parseParamNumber(b) + return pack((pixels, i) => { + if (pixels[i] < r) pixels[i] = 255 - pixels[i]; + if (pixels[i + 1] < g) pixels[i + 1] = 255 - pixels[i + 1]; + if (pixels[i + 2] < b) pixels[i + 2] = 255 - pixels[i + 2]; + }) + +} diff --git a/src/util/filter/pixel/threshold-color.js b/src/util/filter/pixel/threshold-color.js new file mode 100644 index 0000000..ce6c7dc --- /dev/null +++ b/src/util/filter/pixel/threshold-color.js @@ -0,0 +1,27 @@ +import Color from '../../Color' + +import { + parseParamNumber, + pack +} from '../functions' + + +export default function thresholdColor (scale = 200, amount = 100, hasColor = true) { + scale = parseParamNumber(scale) + amount = parseParamNumber(amount) + const C = amount / 100; + return pack((pixels, i) => { + var v = (C * Color.brightness(pixels[i], pixels[i + 1], pixels[i + 2]) ) >= scale ? 255 : 0; + + if (hasColor) { + + if (v == 0) { + pixels[i] = pixels[i + 1] = pixels[i + 2] = 0 + } + + } else { + pixels[i] = pixels[i + 1] = pixels[i + 2] = Math.round(v) + } + + }) +} diff --git a/src/util/filter/pixel/threshold.js b/src/util/filter/pixel/threshold.js new file mode 100644 index 0000000..158c618 --- /dev/null +++ b/src/util/filter/pixel/threshold.js @@ -0,0 +1,7 @@ +import thresholdColor from './threshold-color' +/* + * @param {Number} amount 0..100 + */ +export default function threshold (scale = 200, amount = 100) { + return thresholdColor(scale, amount, false) +} diff --git a/src/util/filter/pixel/tint.js b/src/util/filter/pixel/tint.js new file mode 100644 index 0000000..362d49f --- /dev/null +++ b/src/util/filter/pixel/tint.js @@ -0,0 +1,13 @@ + + +F.tint = function (redTint = 1, greenTint = 1, blueTint = 1) { + redTint = parseParamNumber(redTint) + greenTint = parseParamNumber(greenTint) + blueTint = parseParamNumber(blueTint) + return pack((pixels, i) => { + pixels[i] += (255 - pixels[i]) * redTint; + pixels[i + 1] += (255 - pixels[i + 1]) * greenTint; + pixels[i + 2] += (255 - pixels[i + 2]) * blueTint; + }) + +} \ No newline at end of file