========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41781073
========================================================

收集各种语言:C C++ Java C# JS 等等语言对图片的处理实现代码;包括高斯模糊、堆栈模糊、盒子模糊等等。

所有代码均开源;可拷贝使用。

项目地址

ImageCode

FastBlur.js

/*Superfast Blur - a fast Box Blur For CanvasVersion:    0.5
Author:     Mario Klingemann
Contact:    mario@quasimondo.com
Website:    http://www.quasimondo.com/BoxBlurForCanvas
Twitter:    @quasimondoIn 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.deOr support me on flattr:
https://flattr.com/thing/140066/Superfast-Blur-a-pretty-fast-Box-Blur-Effect-for-CanvasJavascriptCopyright (c) 2011 Mario KlingemannPermission 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:The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.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.
*/
var mul_table = [ 1,57,41,21,203,34,97,73,227,91,149,62,105,45,39,137,241,107,3,173,39,71,65,238,219,101,187,87,81,151,141,133,249,117,221,209,197,187,177,169,5,153,73,139,133,127,243,233,223,107,103,99,191,23,177,171,165,159,77,149,9,139,135,131,253,245,119,231,224,109,211,103,25,195,189,23,45,175,171,83,81,79,155,151,147,9,141,137,67,131,129,251,123,30,235,115,113,221,217,53,13,51,50,49,193,189,185,91,179,175,43,169,83,163,5,79,155,19,75,147,145,143,35,69,17,67,33,65,255,251,247,243,239,59,29,229,113,111,219,27,213,105,207,51,201,199,49,193,191,47,93,183,181,179,11,87,43,85,167,165,163,161,159,157,155,77,19,75,37,73,145,143,141,35,138,137,135,67,33,131,129,255,63,250,247,61,121,239,237,117,29,229,227,225,111,55,109,216,213,211,209,207,205,203,201,199,197,195,193,48,190,47,93,185,183,181,179,178,176,175,173,171,85,21,167,165,41,163,161,5,79,157,78,154,153,19,75,149,74,147,73,144,143,71,141,140,139,137,17,135,134,133,66,131,65,129,1];var shg_table = [0,9,10,10,14,12,14,14,16,15,16,15,16,15,15,17,18,17,12,18,16,17,17,19,19,18,19,18,18,19,19,19,20,19,20,20,20,20,20,20,15,20,19,20,20,20,21,21,21,20,20,20,21,18,21,21,21,21,20,21,17,21,21,21,22,22,21,22,22,21,22,21,19,22,22,19,20,22,22,21,21,21,22,22,22,18,22,22,21,22,22,23,22,20,23,22,22,23,23,21,19,21,21,21,23,23,23,22,23,23,21,23,22,23,18,22,23,20,22,23,23,23,21,22,20,22,21,22,24,24,24,24,24,22,21,24,23,23,24,21,24,23,24,22,24,24,22,24,24,22,23,24,24,24,20,23,22,23,24,24,24,24,24,24,24,23,21,23,22,23,24,24,24,22,24,24,24,23,22,24,24,25,23,25,25,23,24,25,25,24,22,25,25,25,24,23,24,25,25,25,25,25,25,25,25,25,25,25,25,23,25,23,24,25,25,25,25,25,25,25,25,25,24,22,25,25,23,25,25,20,24,25,24,25,25,22,24,25,24,25,24,25,25,24,25,25,25,25,22,25,25,25,24,25,24,25,18];function boxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations ){var img = document.getElementById( imageID );var w = img.naturalWidth;var h = img.naturalHeight;var canvas = document.getElementById( canvasID );canvas.style.width  = w + "px";canvas.style.height = h + "px";canvas.width = w;canvas.height = h;var context = canvas.getContext("2d");context.clearRect( 0, 0, w, h );context.drawImage( img, 0, 0 );if ( isNaN(radius) || radius < 1 ) return;if ( blurAlphaChannel ){boxBlurCanvasRGBA( canvasID, 0, 0, w, h, radius, iterations );} else {boxBlurCanvasRGB( canvasID, 0, 0, w, h, radius, iterations );}}function boxBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations ){if ( isNaN(radius) || radius < 1 ) return;radius |= 0;if ( isNaN(iterations) ) iterations = 1;iterations |= 0;if ( iterations > 3 ) iterations = 3;if ( iterations < 1 ) iterations = 1;var canvas  = document.getElementById( id );var context = canvas.getContext("2d");var imageData;try {try {imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {// NOTE: this part is supposedly only needed if you want to work with local files// so it might be okay to remove the whole try/catch block and just use// imageData = context.getImageData( top_x, top_y, width, height );try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {alert("Cannot access local image");throw new Error("unable to access local image data: " + e);return;}}} catch(e) {alert("Cannot access image");throw new Error("unable to access image data: " + e);return;}var pixels = imageData.data;var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx,pa;        var wm = width - 1;var hm = height - 1;var wh = width * height;var rad1 = radius + 1;var mul_sum = mul_table[radius];var shg_sum = shg_table[radius];var r = [];var g = [];var b = [];var a = [];var vmin = [];var vmax = [];while ( iterations-- > 0 ){yw = yi = 0;for ( y=0; y < height; y++ ){rsum = pixels[yw]   * rad1;gsum = pixels[yw+1] * rad1;bsum = pixels[yw+2] * rad1;asum = pixels[yw+3] * rad1;for( i = 1; i <= radius; i++ ){p = yw + (((i > wm ? wm : i )) << 2 );rsum += pixels[p++];gsum += pixels[p++];bsum += pixels[p++];asum += pixels[p]}for ( x = 0; x < width; x++ ) {r[yi] = rsum;g[yi] = gsum;b[yi] = bsum;a[yi] = asum;if( y==0) {vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );} p1 = yw + vmin[x];p2 = yw + vmax[x];rsum += pixels[p1++] - pixels[p2++];gsum += pixels[p1++] - pixels[p2++];bsum += pixels[p1++] - pixels[p2++];asum += pixels[p1]   - pixels[p2];yi++;}yw += ( width << 2 );}for ( x = 0; x < width; x++ ) {yp = x;rsum = r[yp] * rad1;gsum = g[yp] * rad1;bsum = b[yp] * rad1;asum = a[yp] * rad1;for( i = 1; i <= radius; i++ ) {yp += ( i > hm ? 0 : width );rsum += r[yp];gsum += g[yp];bsum += b[yp];asum += a[yp];}yi = x << 2;for ( y = 0; y < height; y++) {pixels[yi+3] = pa = (asum * mul_sum) >>> shg_sum;if ( pa > 0 ){pa = 255 / pa;pixels[yi]   = ((rsum * mul_sum) >>> shg_sum) * pa;pixels[yi+1] = ((gsum * mul_sum) >>> shg_sum) * pa;pixels[yi+2] = ((bsum * mul_sum) >>> shg_sum) * pa;} else {pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0;}                if( x == 0 ) {vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );} p1 = x + vmin[y];p2 = x + vmax[y];rsum += r[p1] - r[p2];gsum += g[p1] - g[p2];bsum += b[p1] - b[p2];asum += a[p1] - a[p2];yi += width << 2;}}}context.putImageData( imageData, top_x, top_y );}function boxBlurCanvasRGB( id, top_x, top_y, width, height, radius, iterations ){if ( isNaN(radius) || radius < 1 ) return;radius |= 0;if ( isNaN(iterations) ) iterations = 1;iterations |= 0;if ( iterations > 3 ) iterations = 3;if ( iterations < 1 ) iterations = 1;var canvas  = document.getElementById( id );var context = canvas.getContext("2d");var imageData;try {try {imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {// NOTE: this part is supposedly only needed if you want to work with local files// so it might be okay to remove the whole try/catch block and just use// imageData = context.getImageData( top_x, top_y, width, height );try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {alert("Cannot access local image");throw new Error("unable to access local image data: " + e);return;}}} catch(e) {alert("Cannot access image");throw new Error("unable to access image data: " + e);return;}var pixels = imageData.data;var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx;        var wm = width - 1;var hm = height - 1;var wh = width * height;var rad1 = radius + 1;var r = [];var g = [];var b = [];var mul_sum = mul_table[radius];var shg_sum = shg_table[radius];var vmin = [];var vmax = [];while ( iterations-- > 0 ){yw = yi = 0;for ( y=0; y < height; y++ ){rsum = pixels[yw]   * rad1;gsum = pixels[yw+1] * rad1;bsum = pixels[yw+2] * rad1;for( i = 1; i <= radius; i++ ){p = yw + (((i > wm ? wm : i )) << 2 );rsum += pixels[p++];gsum += pixels[p++];bsum += pixels[p++];}for ( x = 0; x < width; x++ ){r[yi] = rsum;g[yi] = gsum;b[yi] = bsum;if( y==0) {vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );} p1 = yw + vmin[x];p2 = yw + vmax[x];rsum += pixels[p1++] - pixels[p2++];gsum += pixels[p1++] - pixels[p2++];bsum += pixels[p1++] - pixels[p2++];yi++;}yw += ( width << 2 );}for ( x = 0; x < width; x++ ){yp = x;rsum = r[yp] * rad1;gsum = g[yp] * rad1;bsum = b[yp] * rad1;for( i = 1; i <= radius; i++ ){yp += ( i > hm ? 0 : width );rsum += r[yp];gsum += g[yp];bsum += b[yp];}yi = x << 2;for ( y = 0; y < height; y++){pixels[yi]   = (rsum * mul_sum) >>> shg_sum;pixels[yi+1] = (gsum * mul_sum) >>> shg_sum;pixels[yi+2] = (bsum * mul_sum) >>> shg_sum;if( x == 0 ) {vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );} p1 = x + vmin[y];p2 = x + vmax[y];rsum += r[p1] - r[p2];gsum += g[p1] - g[p2];bsum += b[p1] - b[p2];yi += width << 2;}}}context.putImageData( imageData, top_x, top_y );}

IntegralImage.js

/*Integral ImageVersion:     0.4
Author:     Mario Klingemann
Contact:    mario@quasimondo.com
Website:    http://www.quasimondo.com/IntegralImageForCanvas
Twitter:    @quasimondoIn 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.deCopyright (c) 2011 Mario KlingemannPermission 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:The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.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.
*/function integralBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations )
{var img = document.getElementById( imageID );var w = img.naturalWidth;var h = img.naturalHeight;var canvas = document.getElementById( canvasID );canvas.style.width  = w + "px";canvas.style.height = h + "px";canvas.width = w;canvas.height = h;var context = canvas.getContext("2d");context.clearRect( 0, 0, w, h );context.drawImage( img, 0, 0 );if ( isNaN(radius) || radius < 1 ) return;if ( blurAlphaChannel ){integralBlurCanvasRGBA( canvasID, 0, 0, w, h, radius, iterations );} else {integralBlurCanvasRGB( canvasID, 0, 0, w, h, radius, iterations );}
}function integralBlurCanvasRGB( id, top_x, top_y, width, height, radius, iterations )
{var ii = integralImageFromCanvasRGB( id, 0, 0, width, height );if ( ii == null ) return;var imageData = ii.imageData;var pixels    = imageData.pixels;var context   = ii.context;blurIntegralImageRGB( ii, radius );while ( --iterations > 0 ){ii = calculateIntegralImageRGB( pixels, width, height );ii.imageData = imageData;ii.context = context;blurIntegralImageRGB( ii, radius );}context.putImageData( imageData, top_x, top_y );}function integralBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations )
{var ii = integralImageFromCanvasRGBA( id, 0, 0, width, height );if ( ii == null ) return;var imageData = ii.imageData;var pixels    = ii.pixels;var context   = ii.context;blurIntegralImageRGBA( ii, radius );while ( --iterations > 0 ){ii = calculateIntegralImageRGBA( pixels, width, height );ii.imageData = imageData;ii.context = context;blurIntegralImageRGBA( ii, radius );}context.putImageData( imageData, top_x, top_y );}function updateCanvas( integralImage )
{integralImage.context.putImageData( integralImage.imageData, 0, 0 );
}function blurIntegralImageRGBA( integralImage, radius )
{var dx1,dx2,dy1,dy2,dy,idx1,idx2,idx3,idx4,area;var ii = integralImage;var width = ii.width;var height = ii.height;var pixels = ii.pixels;var i1 = 0;var i2 = 0;var r = ii.r;var g = ii.g;var b = ii.b;var a = ii.a;var pa;var iw = width + 1;for ( var y = 0; y < height; y++ ){dy1 = ( y < radius ? -y : -radius );dy2 = ( y >= height - radius ? height - y : radius );dy = dy2 - dy1;dy1 *= iw;dy2 *= iw;for ( var x = 0; x < width; x++ ){dx1 = ( x < radius ? -x : -radius );dx2 = ( x >= width - radius ? width - x : radius );area = 1 / ((dx2 - dx1) * dy);dx1 += i1;dx2 += i1;idx1 = dx1+dy1;idx2 = dx2+dy2;idx3 = dx1+dy2;idx4 = dx2+dy1;pa = (( a[idx1] + a[idx2] - a[idx3] - a[idx4] ) * area ) | 0;if ( pa > 0 ){pa = 255 / pa;pixels[i2++] = (( r[idx1] + r[idx2] - r[idx3] - r[idx4] ) * area * pa) | 0;pixels[i2++] = (( g[idx1] + g[idx2] - g[idx3] - g[idx4] ) * area * pa) | 0;pixels[i2++] = (( b[idx1] + b[idx2] - b[idx3] - b[idx4] ) * area * pa) | 0;pixels[i2++] = pa;} else {pixels[i2++] = pixels[i2++] = pixels[i2++] = pixels[i2++] = 0;}i1++;}i1++;}
}function blurIntegralImageRGB( integralImage, radius )
{var dx1,dx2,dy1,dy2,dy,idx1,idx2,idx3,idx4,area;var ii = integralImage;var width = ii.width;var height = ii.height;var pixels = ii.pixels;var i1 = 0;var i2 = 0;var r = ii.r;var g = ii.g;var b = ii.b;var iw = width + 1;for ( var y = 0; y < height; y++ ) {dy1 = ( y < radius ? -y : -radius );dy2 = ( y >= height - radius ? height - y -1 : radius );dy = dy2 - dy1;dy1 *= iw;dy2 *= iw;for ( var x = 0; x < width; x++ ) {dx1 = ( x < radius ? -x : -radius );dx2 = ( x >= width - radius ? width - x - 1: radius );area = 1 / ((dx2 - dx1) * dy);dx1 += i1;dx2 += i1;idx1 = dx1+dy1;idx2 = dx2+dy2;idx3 = dx1+dy2;idx4 = dx2+dy1;pixels[i2++] = (( r[idx1] + r[idx2] - r[idx3] - r[idx4] ) * area ) | 0;pixels[i2++] = (( g[idx1] + g[idx2] - g[idx3] - g[idx4] ) * area ) | 0;pixels[i2++] = (( b[idx1] + b[idx2] - b[idx3] - b[idx4] ) * area ) | 0;i2++i1++;}i1++;}}function integralImageFromImage( imageID, canvasID, includeAlphaChannel )
{var img = document.getElementById( imageID );var w = img.naturalWidth;var h = img.naturalHeight;var canvas = document.getElementById( canvasID );canvas.style.width  = w + "px";canvas.style.height = h + "px";canvas.width = w;canvas.height = h;var context = canvas.getContext("2d");context.clearRect( 0, 0, w, h );context.drawImage( img, 0, 0 );if ( includeAlphaChannel ){return integralImageFromCanvasRGBA( canvasID, 0, 0, w, h );} else {return integralImageFromCanvasRGB( canvasID, 0, 0, w, h );}
}function integralImageFromCanvasRGB( id, top_x, top_y, width, height )
{var pixelData = getCanvasPixels( id, top_x, top_y, width, height );if ( pixelData == null ) return;var ii = calculateIntegralImageRGB( pixelData.pixels, width, height );ii.context = pixelData.context;ii.imageData = pixelData.imageData;return ii;
}function integralImageFromCanvasRGBA( id, top_x, top_y, width, height )
{var pixelData = getCanvasPixels( id, top_x, top_y, width, height );if ( pixelData == null ) return;var ii = calculateIntegralImageRGBA( pixelData.pixels, width, height );ii.context = pixelData.context;ii.imageData = pixelData.imageData;return ii;
}function getCanvasPixels( canvasID, top_x, top_y, width, height )
{var result = { id:canvasID, top_x:top_x, top_y:top_y, width:width, height:height };result.canvas  = document.getElementById( canvasID );result.context = result.canvas.getContext("2d");try {result.imageData = result.context.getImageData( top_x, top_y, width, height );} catch(e) {//throw new Error("unable to access image data: " + e);return null;}result.pixels = result.imageData.data;return result;
}function calculateIntegralImageRGB( pixels, width, height )
{var r = [];var g = [];var b = [];var i = 0;var j = 0;for ( y=0; y < height; y++ ){rsum = pixels[i++];gsum = pixels[i++];bsum = pixels[i++];i++;for ( x = 0; x < width; x++ ){r[j]   = rsum;g[j]   = gsum;b[j++] = bsum;rsum += pixels[i++];gsum += pixels[i++];bsum += pixels[i++];i++;}r[j]   = rsum;g[j]   = gsum;b[j++] = bsum;i-=4;}var j1 =  width + 1;var w1 = j1;var k = j1 * ( height + 1 );var j2 = j1 - w1;while ( j1 < k ){r[j1] += r[j2];g[j1] += g[j2];b[j1] += b[j2];j1++,j2++;}return { r:r, g:g, b:b, width:width, height:height, pixels:pixels };}function calculateIntegralImageRGBA( pixels, width, height )
{   var r = [];var g = [];var b = [];var a = [];var i = 0;var j = 0;for ( y=0; y < height; y++ ){rsum = pixels[i++];gsum = pixels[i++];bsum = pixels[i++];asum = pixels[i++];for ( x = 0; x < width; x++ ){r[j]   = rsum;g[j]   = gsum;b[j]   = bsum;a[j++] = asum;rsum += pixels[i++];gsum += pixels[i++];bsum += pixels[i++];asum += pixels[i++];}r[j]   = rsum;g[j]   = gsum;b[j]   = bsum;a[j++] = asum;i-=4;}var j1 = width + 1;var w1 = j1;var k = j1 * ( height + 1 );var j2 = j1 - w1;while ( j1 < k ){r[j1] += r[j2];g[j1] += g[j2];b[j1] += b[j2];a[j1] += a[j2];j1++, j2++;}return { r:r, g:g, b:b, a:a, width:width, height:height, pixels:pixels };
}

stackblur.cpp

// The Stack Blur Algorithm was invented by Mario Klingemann,
// mario@quasimondo.com and described here:
// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php// This is C++ RGBA (32 bit color) multi-threaded version
// by Victor Laskin (victor.laskin@gmail.com)
// More details: http://vitiy.info/stackblur-algorithm-multi-threaded-blur-for-cpp// This code is using MVThread class from my cross-platform framework
// You can exchange it with any thread implementation you like// -------------------------------------- stackblur ----------------------------------------->static unsigned short const stackblur_mul[255] =
{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
};static unsigned char const stackblur_shr[255] =
{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
};/// Stackblur algorithm body
void stackblurJob(unsigned char* src,               ///< input image dataunsigned int w,                 ///< image widthunsigned int h,                  ///< image heightunsigned int radius,                ///< blur intensity (should be in 2..254 range)int cores,                        ///< total number of working threadsint core,                            ///< current thread numberint step,                          ///< step of processing (1,2)unsigned char* stack                ///< stack buffer)
{unsigned int x, y, xp, yp, i;unsigned int sp;unsigned int stack_start;unsigned char* stack_ptr;unsigned char* src_ptr;unsigned char* dst_ptr;unsigned long sum_r;unsigned long sum_g;unsigned long sum_b;unsigned long sum_a;unsigned long sum_in_r;unsigned long sum_in_g;unsigned long sum_in_b;unsigned long sum_in_a;unsigned long sum_out_r;unsigned long sum_out_g;unsigned long sum_out_b;unsigned long sum_out_a;unsigned int wm = w - 1;unsigned int hm = h - 1;unsigned int w4 = w * 4;unsigned int div = (radius * 2) + 1;unsigned int mul_sum = stackblur_mul[radius];unsigned char shr_sum = stackblur_shr[radius];if (step == 1){int minY = core * h / cores;int maxY = (core + 1) * h / cores;for(y = minY; y < maxY; y++){sum_r = sum_g = sum_b = sum_a =sum_in_r = sum_in_g = sum_in_b = sum_in_a =sum_out_r = sum_out_g = sum_out_b = sum_out_a = 0;src_ptr = src + w4 * y; // start of line (0,y)for(i = 0; i <= radius; i++){stack_ptr    = &stack[ 4 * i ];stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_r += src_ptr[0] * (i + 1);sum_g += src_ptr[1] * (i + 1);sum_b += src_ptr[2] * (i + 1);sum_a += src_ptr[3] * (i + 1);sum_out_r += src_ptr[0];sum_out_g += src_ptr[1];sum_out_b += src_ptr[2];sum_out_a += src_ptr[3];}for(i = 1; i <= radius; i++){if (i <= wm) src_ptr += 4;stack_ptr = &stack[ 4 * (i + radius) ];stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_r += src_ptr[0] * (radius + 1 - i);sum_g += src_ptr[1] * (radius + 1 - i);sum_b += src_ptr[2] * (radius + 1 - i);sum_a += src_ptr[3] * (radius + 1 - i);sum_in_r += src_ptr[0];sum_in_g += src_ptr[1];sum_in_b += src_ptr[2];sum_in_a += src_ptr[3];}sp = radius;xp = radius;if (xp > wm) xp = wm;src_ptr = src + 4 * (xp + y * w); //   img.pix_ptr(xp, y);dst_ptr = src + y * w4; // img.pix_ptr(0, y);for(x = 0; x < w; x++){dst_ptr[0] = (sum_r * mul_sum) >> shr_sum;dst_ptr[1] = (sum_g * mul_sum) >> shr_sum;dst_ptr[2] = (sum_b * mul_sum) >> shr_sum;dst_ptr[3] = (sum_a * mul_sum) >> shr_sum;dst_ptr += 4;sum_r -= sum_out_r;sum_g -= sum_out_g;sum_b -= sum_out_b;sum_a -= sum_out_a;stack_start = sp + div - radius;if (stack_start >= div) stack_start -= div;stack_ptr = &stack[4 * stack_start];sum_out_r -= stack_ptr[0];sum_out_g -= stack_ptr[1];sum_out_b -= stack_ptr[2];sum_out_a -= stack_ptr[3];if(xp < wm){src_ptr += 4;++xp;}stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_in_r += src_ptr[0];sum_in_g += src_ptr[1];sum_in_b += src_ptr[2];sum_in_a += src_ptr[3];sum_r    += sum_in_r;sum_g    += sum_in_g;sum_b    += sum_in_b;sum_a    += sum_in_a;++sp;if (sp >= div) sp = 0;stack_ptr = &stack[sp*4];sum_out_r += stack_ptr[0];sum_out_g += stack_ptr[1];sum_out_b += stack_ptr[2];sum_out_a += stack_ptr[3];sum_in_r  -= stack_ptr[0];sum_in_g  -= stack_ptr[1];sum_in_b  -= stack_ptr[2];sum_in_a  -= stack_ptr[3];}}}// step 2if (step == 2){int minX = core * w / cores;int maxX = (core + 1) * w / cores;for(x = minX; x < maxX; x++){sum_r =   sum_g =    sum_b =    sum_a =sum_in_r = sum_in_g = sum_in_b = sum_in_a =sum_out_r = sum_out_g = sum_out_b = sum_out_a = 0;src_ptr = src + 4 * x; // x,0for(i = 0; i <= radius; i++){stack_ptr    = &stack[i * 4];stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_r           += src_ptr[0] * (i + 1);sum_g           += src_ptr[1] * (i + 1);sum_b           += src_ptr[2] * (i + 1);sum_a           += src_ptr[3] * (i + 1);sum_out_r       += src_ptr[0];sum_out_g       += src_ptr[1];sum_out_b       += src_ptr[2];sum_out_a       += src_ptr[3];}for(i = 1; i <= radius; i++){if(i <= hm) src_ptr += w4; // +stridestack_ptr = &stack[4 * (i + radius)];stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_r += src_ptr[0] * (radius + 1 - i);sum_g += src_ptr[1] * (radius + 1 - i);sum_b += src_ptr[2] * (radius + 1 - i);sum_a += src_ptr[3] * (radius + 1 - i);sum_in_r += src_ptr[0];sum_in_g += src_ptr[1];sum_in_b += src_ptr[2];sum_in_a += src_ptr[3];}sp = radius;yp = radius;if (yp > hm) yp = hm;src_ptr = src + 4 * (x + yp * w); // img.pix_ptr(x, yp);dst_ptr = src + 4 * x;             // img.pix_ptr(x, 0);for(y = 0; y < h; y++){dst_ptr[0] = (sum_r * mul_sum) >> shr_sum;dst_ptr[1] = (sum_g * mul_sum) >> shr_sum;dst_ptr[2] = (sum_b * mul_sum) >> shr_sum;dst_ptr[3] = (sum_a * mul_sum) >> shr_sum;dst_ptr += w4;sum_r -= sum_out_r;sum_g -= sum_out_g;sum_b -= sum_out_b;sum_a -= sum_out_a;stack_start = sp + div - radius;if(stack_start >= div) stack_start -= div;stack_ptr = &stack[4 * stack_start];sum_out_r -= stack_ptr[0];sum_out_g -= stack_ptr[1];sum_out_b -= stack_ptr[2];sum_out_a -= stack_ptr[3];if(yp < hm){src_ptr += w4; // stride++yp;}stack_ptr[0] = src_ptr[0];stack_ptr[1] = src_ptr[1];stack_ptr[2] = src_ptr[2];stack_ptr[3] = src_ptr[3];sum_in_r += src_ptr[0];sum_in_g += src_ptr[1];sum_in_b += src_ptr[2];sum_in_a += src_ptr[3];sum_r    += sum_in_r;sum_g    += sum_in_g;sum_b    += sum_in_b;sum_a    += sum_in_a;++sp;if (sp >= div) sp = 0;stack_ptr = &stack[sp*4];sum_out_r += stack_ptr[0];sum_out_g += stack_ptr[1];sum_out_b += stack_ptr[2];sum_out_a += stack_ptr[3];sum_in_r  -= stack_ptr[0];sum_in_g  -= stack_ptr[1];sum_in_b  -= stack_ptr[2];sum_in_a  -= stack_ptr[3];}}}}class MVImageUtilsStackBlurTask : public MVThread
{
public:unsigned char* src;unsigned int w;unsigned int h;unsigned int radius;int cores;int core;int step;unsigned char* stack;inline MVImageUtilsStackBlurTask(unsigned char* src, unsigned int w, unsigned int h, unsigned int radius, int cores, int core, int step, unsigned char* stack){this->src = src;this->w = w;this->h = h;this->radius = radius;this->cores = cores;this->core = core;this->step = step;this->stack = stack;}inline void run(){stackblurJob(src, w, h, radius, cores, core, step, stack);}};/// Stackblur algorithm by Mario Klingemann
/// Details here:
/// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
/// C++ implemenation base from:
/// https://gist.github.com/benjamin9999/3809142
/// http://www.antigrain.com/__code/include/agg_blur.h.html
/// This version works only with RGBA color
void               stackblur(unsigned char* src,                ///< input image dataunsigned int w,                 ///< image widthunsigned int h,                  ///< image heightunsigned int radius,                ///< blur intensity (should be in 2..254 range)int cores = 1                        ///< number of threads (1 - normal single thread))
{if (radius > 254) return;if (radius < 2) return;unsigned int div = (radius * 2) + 1;unsigned char* stack = new unsigned char [div * 4 * cores];if (cores == 1){// no multithreadingstackblurJob(src, w, h, radius, 1, 0, 1, stack);stackblurJob(src, w, h, radius, 1, 0, 2, stack);}else{MVImageUtilsStackBlurTask** workers = new MVImageUtilsStackBlurTask*[cores];for (int i = 0; i < cores; i++){workers[i] = new MVImageUtilsStackBlurTask(src, w, h, radius, cores, i, 1, stack + div * 4 * i);workers[i]->start();}for (int i = 0; i < cores; i++)workers[i]->wait();for (int i = 0; i < cores; i++){workers[i]->step = 2;workers[i]->start();}for (int i = 0; i < cores; i++){workers[i]->wait();delete workers[i];}delete[] workers;}delete[] stack;
}

stackblur.txt

// Stack Blur v1.0
//
// Author: Mario Klingemann <mario@quasimondo.com>
// http://incubator.quasimondo.com
// created Feburary 29, 2004// This is a compromise between Gaussian Blur and Box blur
// It creates much better looking blurs than Box Blur, but is
// 7x faster than my Gaussian Blur implementation.
//
// I called it Stack Blur because this describes best how this
// filter works internally: it creates a kind of moving stack
// of colors whilst scanning through the image. Thereby it
// just has to add one new block of color to the right side
// of the stack and remove the leftmost color. The remaining
// colors on the topmost layer of the stack are either added on
// or reduced by one, depending on if they are on the right or
// on the left side of the stack.
//
// If you are using this algorithm in your code please add
// the following line:
//
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>PImage a;
PImage b;void setup()
{a=loadImage("dog.jpg");size(a.width, a.height);b=new PImage(a.width, a.height);fill(255);noStroke();frameRate(25);
}void draw()
{System.arraycopy(a.pixels,0,b.pixels,0,a.pixels.length);fastblur(b,mouseY/4);image(b, 0, 0);
}void fastblur(PImage img,int radius){if (radius<1){return;}int[] pix=img.pixels;int w=img.width;int h=img.height;int wm=w-1;int hm=h-1;int wh=w*h;int div=radius+radius+1;int r[]=new int[wh];int g[]=new int[wh];int b[]=new int[wh];int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;int vmin[] = new int[max(w,h)];int divsum=(div+1)>>1;divsum*=divsum;int dv[]=new int[256*divsum];for (i=0;i<256*divsum;i++){dv[i]=(i/divsum);}yw=yi=0;int[][] stack=new int[div][3];int stackpointer;int stackstart;int[] sir;int rbs;int r1=radius+1;int routsum,goutsum,boutsum;int rinsum,ginsum,binsum;for (y=0;y<h;y++){rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;for(i=-radius;i<=radius;i++){p=pix[yi+min(wm,max(i,0))];sir=stack[i+radius];sir[0]=(p & 0xff0000)>>16;sir[1]=(p & 0x00ff00)>>8;sir[2]=(p & 0x0000ff);rbs=r1-abs(i);rsum+=sir[0]*rbs;gsum+=sir[1]*rbs;bsum+=sir[2]*rbs;if (i>0){rinsum+=sir[0];ginsum+=sir[1];binsum+=sir[2];} else {routsum+=sir[0];goutsum+=sir[1];boutsum+=sir[2];}}stackpointer=radius;for (x=0;x<w;x++){r[yi]=dv[rsum];g[yi]=dv[gsum];b[yi]=dv[bsum];rsum-=routsum;gsum-=goutsum;bsum-=boutsum;stackstart=stackpointer-radius+div;sir=stack[stackstart%div];routsum-=sir[0];goutsum-=sir[1];boutsum-=sir[2];if(y==0){vmin[x]=min(x+radius+1,wm);}p=pix[yw+vmin[x]];sir[0]=(p & 0xff0000)>>16;sir[1]=(p & 0x00ff00)>>8;sir[2]=(p & 0x0000ff);rinsum+=sir[0];ginsum+=sir[1];binsum+=sir[2];rsum+=rinsum;gsum+=ginsum;bsum+=binsum;stackpointer=(stackpointer+1)%div;sir=stack[(stackpointer)%div];routsum+=sir[0];goutsum+=sir[1];boutsum+=sir[2];rinsum-=sir[0];ginsum-=sir[1];binsum-=sir[2];yi++;}yw+=w;}for (x=0;x<w;x++){rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;yp=-radius*w;for(i=-radius;i<=radius;i++){yi=max(0,yp)+x;sir=stack[i+radius];sir[0]=r[yi];sir[1]=g[yi];sir[2]=b[yi];rbs=r1-abs(i);rsum+=r[yi]*rbs;gsum+=g[yi]*rbs;bsum+=b[yi]*rbs;if (i>0){rinsum+=sir[0];ginsum+=sir[1];binsum+=sir[2];} else {routsum+=sir[0];goutsum+=sir[1];boutsum+=sir[2];}if(i<hm){yp+=w;}}yi=x;stackpointer=radius;for (y=0;y<h;y++){pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];rsum-=routsum;gsum-=goutsum;bsum-=boutsum;stackstart=stackpointer-radius+div;sir=stack[stackstart%div];routsum-=sir[0];goutsum-=sir[1];boutsum-=sir[2];if(x==0){vmin[y]=min(y+r1,hm)*w;}p=x+vmin[y];sir[0]=r[p];sir[1]=g[p];sir[2]=b[p];rinsum+=sir[0];ginsum+=sir[1];binsum+=sir[2];rsum+=rinsum;gsum+=ginsum;bsum+=binsum;stackpointer=(stackpointer+1)%div;sir=stack[stackpointer];routsum+=sir[0];goutsum+=sir[1];boutsum+=sir[2];rinsum-=sir[0];ginsum-=sir[1];binsum-=sir[2];yi+=w;}}img.updatePixels();
}

StackBoxBlur.js

/*StackBoxBlur - a fast almost Box Blur For CanvasVersion:   0.3
Author:     Mario Klingemann
Contact:    mario@quasimondo.com
Website:    http://www.quasimondo.com/
Twitter:    @quasimondoIn 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.deCopyright (c) 2010 Mario KlingemannPermission 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:The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.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.
*/
/*
var mul_table = [ 1,57,41,21,203,34,97,73,227,91,149,62,105,45,39,137,241,107,3,173,39,71,65,238,219,101,187,87,81,151,141,133,249,117,221,209,197,187,177,169,5,153,73,139,133,127,243,233,223,107,103,99,191,23,177,171,165,159,77,149,9,139,135,131,253,245,119,231,224,109,211,103,25,195,189,23,45,175,171,83,81,79,155,151,147,9,141,137,67,131,129,251,123,30,235,115,113,221,217,53,13,51,50,49,193,189,185,91,179,175,43,169,83,163,5,79,155,19,75,147,145,143,35,69,17,67,33,65,255,251,247,243,239,59,29,229,113,111,219,27,213,105,207,51,201,199,49,193,191,47,93,183,181,179,11,87,43,85,167,165,163,161,159,157,155,77,19,75,37,73,145,143,141,35,138,137,135,67,33,131,129,255,63,250,247,61,121,239,237,117,29,229,227,225,111,55,109,216,213,211,209,207,205,203,201,199,197,195,193,48,190,47,93,185,183,181,179,178,176,175,173,171,85,21,167,165,41,163,161,5,79,157,78,154,153,19,75,149,74,147,73,144,143,71,141,140,139,137,17,135,134,133,66,131,65,129,1];var shg_table = [0,9,10,10,14,12,14,14,16,15,16,15,16,15,15,17,18,17,12,18,16,17,17,19,19,18,19,18,18,19,19,19,20,19,20,20,20,20,20,20,15,20,19,20,20,20,21,21,21,20,20,20,21,18,21,21,21,21,20,21,17,21,21,21,22,22,21,22,22,21,22,21,19,22,22,19,20,22,22,21,21,21,22,22,22,18,22,22,21,22,22,23,22,20,23,22,22,23,23,21,19,21,21,21,23,23,23,22,23,23,21,23,22,23,18,22,23,20,22,23,23,23,21,22,20,22,21,22,24,24,24,24,24,22,21,24,23,23,24,21,24,23,24,22,24,24,22,24,24,22,23,24,24,24,20,23,22,23,24,24,24,24,24,24,24,23,21,23,22,23,24,24,24,22,24,24,24,23,22,24,24,25,23,25,25,23,24,25,25,24,22,25,25,25,24,23,24,25,25,25,25,25,25,25,25,25,25,25,25,23,25,23,24,25,25,25,25,25,25,25,25,25,24,22,25,25,23,25,25,20,24,25,24,25,25,22,24,25,24,25,24,25,25,24,25,25,25,25,22,25,25,25,24,25,24,25,18];
*/var mul_table = [ 1,171,205,293,57,373,79,137,241,27,391,357,41,19,283,265,497,469,443,421,25,191,365,349,335,161,155,149,9,278,269,261,505,245,475,231,449,437,213,415,405,395,193,377,369,361,353,345,169,331,325,319,313,307,301,37,145,285,281,69,271,267,263,259,509,501,493,243,479,118,465,459,113,446,55,435,429,423,209,413,51,403,199,393,97,3,379,375,371,367,363,359,355,351,347,43,85,337,333,165,327,323,5,317,157,311,77,305,303,75,297,294,73,289,287,71,141,279,277,275,68,135,67,133,33,262,260,129,511,507,503,499,495,491,61,121,481,477,237,235,467,232,115,457,227,451,7,445,221,439,218,433,215,427,425,211,419,417,207,411,409,203,202,401,399,396,197,49,389,387,385,383,95,189,47,187,93,185,23,183,91,181,45,179,89,177,11,175,87,173,345,343,341,339,337,21,167,83,331,329,327,163,81,323,321,319,159,79,315,313,39,155,309,307,153,305,303,151,75,299,149,37,295,147,73,291,145,289,287,143,285,71,141,281,35,279,139,69,275,137,273,17,271,135,269,267,133,265,33,263,131,261,130,259,129,257,1];var shg_table = [0,9,10,11,9,12,10,11,12,9,13,13,10,9,13,13,14,14,14,14,10,13,14,14,14,13,13,13,9,14,14,14,15,14,15,14,15,15,14,15,15,15,14,15,15,15,15,15,14,15,15,15,15,15,15,12,14,15,15,13,15,15,15,15,16,16,16,15,16,14,16,16,14,16,13,16,16,16,15,16,13,16,15,16,14,9,16,16,16,16,16,16,16,16,16,13,14,16,16,15,16,16,10,16,15,16,14,16,16,14,16,16,14,16,16,14,15,16,16,16,14,15,14,15,13,16,16,15,17,17,17,17,17,17,14,15,17,17,16,16,17,16,15,17,16,17,11,17,16,17,16,17,16,17,17,16,17,17,16,17,17,16,16,17,17,17,16,14,17,17,17,17,15,16,14,16,15,16,13,16,15,16,14,16,15,16,12,16,15,16,17,17,17,17,17,13,16,15,17,17,17,16,15,17,17,17,16,15,17,17,14,16,17,17,16,17,17,16,15,17,16,14,17,16,15,17,16,17,17,16,17,15,16,17,14,17,16,15,17,16,17,13,17,16,17,17,16,17,14,17,16,17,16,17,16,17,9
];function stackBoxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations )
{var img = document.getElementById( imageID );var w = img.naturalWidth;var h = img.naturalHeight;var canvas = document.getElementById( canvasID );canvas.style.width  = w + "px";canvas.style.height = h + "px";canvas.width = w;canvas.height = h;var context = canvas.getContext("2d");context.clearRect( 0, 0, w, h );context.drawImage( img, 0, 0 );if ( isNaN(radius) || radius < 1 ) return;if ( blurAlphaChannel )stackBoxBlurCanvasRGBA( canvasID, 0, 0, w, h, radius, iterations );else stackBoxBlurCanvasRGB( canvasID, 0, 0, w, h, radius, iterations );
}function stackBoxBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations )
{if ( isNaN(radius) || radius < 1 ) return;radius |= 0;if ( isNaN(iterations) ) iterations = 1;iterations |= 0;if ( iterations > 3 ) iterations = 3;if ( iterations < 1 ) iterations = 1;var canvas  = document.getElementById( id );var context = canvas.getContext("2d");var imageData;try {try {imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {// NOTE: this part is supposedly only needed if you want to work with local files// so it might be okay to remove the whole try/catch block and just use// imageData = context.getImageData( top_x, top_y, width, height );try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {alert("Cannot access local image");throw new Error("unable to access local image data: " + e);return;}}} catch(e) {alert("Cannot access image");throw new Error("unable to access image data: " + e);}var pixels = imageData.data;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;var div = radius + radius + 1;var w4 = width << 2;var widthMinus1  = width - 1;var heightMinus1 = height - 1;var radiusPlus1  = radius + 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 mul_sum = mul_table[radius];var shg_sum = shg_table[radius];while ( iterations-- > 0 ) {yw = yi = 0;for ( y = height; --y > -1; ){r_sum = radiusPlus1 * ( pr = pixels[yi] );g_sum = radiusPlus1 * ( pg = pixels[yi+1] );b_sum = radiusPlus1 * ( pb = pixels[yi+2] );a_sum = radiusPlus1 * ( pa = pixels[yi+3] );stack = stackStart;for( i = radiusPlus1; --i > -1; ){stack.r = pr;stack.g = pg;stack.b = pb;stack.a = pa;stack = stack.next;}for( i = 1; i < radiusPlus1; i++ ){p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 );r_sum += ( stack.r = pixels[p]);g_sum += ( stack.g = pixels[p+1]);b_sum += ( stack.b = pixels[p+2]);a_sum += ( stack.a = pixels[p+3]);stack = stack.next;}stackIn = stackStart;for ( x = 0; x < width; x++ ){pixels[yi++] = (r_sum * mul_sum) >>> shg_sum;pixels[yi++] = (g_sum * mul_sum) >>> shg_sum;pixels[yi++] = (b_sum * mul_sum) >>> shg_sum;pixels[yi++] = (a_sum * mul_sum) >>> shg_sum;p =  ( yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2;r_sum -= stackIn.r - ( stackIn.r = pixels[p]);g_sum -= stackIn.g - ( stackIn.g = pixels[p+1]);b_sum -= stackIn.b - ( stackIn.b = pixels[p+2]);a_sum -= stackIn.a - ( stackIn.a = pixels[p+3]);stackIn = stackIn.next;}yw += width;}for ( x = 0; x < width; x++ ){yi = x << 2;r_sum = radiusPlus1 * ( pr = pixels[yi]);g_sum = radiusPlus1 * ( pg = pixels[yi+1]);b_sum = radiusPlus1 * ( pb = pixels[yi+2]);a_sum = radiusPlus1 * ( pa = pixels[yi+3]);stack = stackStart;for( i = 0; i < radiusPlus1; i++ ){stack.r = pr;stack.g = pg;stack.b = pb;stack.a = pa;stack = stack.next;}yp = width;for( i = 1; i <= radius; i++ ){yi = ( yp + x ) << 2;r_sum += ( stack.r = pixels[yi]);g_sum += ( stack.g = pixels[yi+1]);b_sum += ( stack.b = pixels[yi+2]);a_sum += ( stack.a = pixels[yi+3]);stack = stack.next;if( i < heightMinus1 ){yp += width;}}yi = x;stackIn = stackStart;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}p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2;r_sum -= stackIn.r - ( stackIn.r = pixels[p]);g_sum -= stackIn.g - ( stackIn.g = pixels[p+1]);b_sum -= stackIn.b - ( stackIn.b = pixels[p+2]);a_sum -= stackIn.a - ( stackIn.a = pixels[p+3]);stackIn = stackIn.next;yi += width;}}}context.putImageData( imageData, top_x, top_y );}function stackBoxBlurCanvasRGB( id, top_x, top_y, width, height, radius, iterations )
{if ( isNaN(radius) || radius < 1 ) return;radius |= 0;if ( isNaN(iterations) ) iterations = 1;iterations |= 0;if ( iterations > 3 ) iterations = 3;if ( iterations < 1 ) iterations = 1;var canvas  = document.getElementById( id );var context = canvas.getContext("2d");var imageData;try {try {imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {// NOTE: this part is supposedly only needed if you want to work with local files// so it might be okay to remove the whole try/catch block and just use// imageData = context.getImageData( top_x, top_y, width, height );try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");imageData = context.getImageData( top_x, top_y, width, height );} catch(e) {alert("Cannot access local image");throw new Error("unable to access local image data: " + e);return;}}} catch(e) {alert("Cannot access image");throw new Error("unable to access image data: " + e);}var pixels = imageData.data;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;var div = radius + radius + 1;var w4 = width << 2;var widthMinus1  = width - 1;var heightMinus1 = height - 1;var radiusPlus1  = radius + 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 mul_sum = mul_table[radius];var shg_sum = shg_table[radius];while ( iterations-- > 0 ) {yw = yi = 0;for ( y = height; --y >-1; ){r_sum = radiusPlus1 * ( pr = pixels[yi] );g_sum = radiusPlus1 * ( pg = pixels[yi+1] );b_sum = radiusPlus1 * ( pb = pixels[yi+2] );stack = stackStart;for( i = radiusPlus1; --i > -1; ){stack.r = pr;stack.g = pg;stack.b = pb;stack = stack.next;}for( i = 1; i < radiusPlus1; i++ ){p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 );r_sum += ( stack.r = pixels[p++]);g_sum += ( stack.g = pixels[p++]);b_sum += ( stack.b = pixels[p]);stack = stack.next;}stackIn = stackStart;for ( x = 0; x < width; x++ ){pixels[yi++] = (r_sum * mul_sum) >>> shg_sum;pixels[yi++] = (g_sum * mul_sum) >>> shg_sum;pixels[yi++] = (b_sum * mul_sum) >>> shg_sum;yi++;p =  ( yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2;r_sum -= stackIn.r - ( stackIn.r = pixels[p++]);g_sum -= stackIn.g - ( stackIn.g = pixels[p++]);b_sum -= stackIn.b - ( stackIn.b = pixels[p]);stackIn = stackIn.next;}yw += width;}for ( x = 0; x < width; x++ ){yi = x << 2;r_sum = radiusPlus1 * ( pr = pixels[yi++]);g_sum = radiusPlus1 * ( pg = pixels[yi++]);b_sum = radiusPlus1 * ( pb = pixels[yi]);stack = stackStart;for( i = 0; i < radiusPlus1; i++ ){stack.r = pr;stack.g = pg;stack.b = pb;stack = stack.next;}yp = width;for( i = 1; i <= radius; i++ ){yi = ( yp + x ) << 2;r_sum += ( stack.r = pixels[yi++]);g_sum += ( stack.g = pixels[yi++]);b_sum += ( stack.b = pixels[yi]);stack = stack.next;if ( i < heightMinus1 ) yp += width;}yi = x;stackIn = stackStart;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;p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2;r_sum -= stackIn.r - ( stackIn.r = pixels[p]);g_sum -= stackIn.g - ( stackIn.g = pixels[p+1]);b_sum -= stackIn.b - ( stackIn.b = pixels[p+2]);stackIn = stackIn.next;yi += width;}}}context.putImageData( imageData, top_x, top_y );}function BlurStack()
{this.r = 0;this.g = 0;this.b = 0;this.a = 0;this.next = null;
}

相关博客

[Android] 图片JNI(C++\Java)高斯模糊 多线程

[Android]-图片JNI(C++\Java)高斯模糊的实现与比较

========================================================
作者: qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41781073
========================================================

[Code] 收集各种语言对图片的处理算法实现 图片模糊相关推荐

  1. VS Code配置Go语言开发环境

    VS Code配置Go语言开发环境 Go语言是采用UTF8编码的,理论上使用任何文本编辑器都能做Go语言开发.大家可以根据自己的喜好自行选择.编辑器/IDE没有最好只有最适合 1.安装中文简体插件 点 ...

  2. Golang VS Code 配置 Go 语言开发环境

    前言 前面我已经讲过 GoLand 的安装,当然,你也可以使用 VS Code 来进行开发. VS Code 是微软开源的一款编辑器, 本文主要介绍如何使用VS Code搭建Go语言的开发环境. 下载 ...

  3. GO语言教程2:使用VS code进行go语言的编写和运行

    文章目录 Go语言系列教程:https://blog.csdn.net/zhangpeterx/article/details/89040274 1.安装vs code和go语言插件 2.解决方案: ...

  4. Algorithm:C++语言实现之链表相关算法(单链公共结点问题、一般LCA、括号匹配、最长括号匹配、逆波兰表达式Reverse Polish Notation、直方图矩形面积、收集雨水问题)

    Algorithm:C++语言实现之链表相关算法(单链公共结点问题.一般LCA.括号匹配.最长括号匹配.逆波兰表达式Reverse Polish Notation.直方图矩形面积.收集雨水问题) 目录 ...

  5. Visual Studio Code下c语言环境的安装与运行

    Visual Studio Code下c语言环境的安装与运行 在我们以往的c语言的学习中,c语言的编写代码用的最多的是c free5.0或者vc++6.0,这种软件的学习是我们最初使用的,也是经典的. ...

  6. VS Code写C语言输出long double类型数据不正确的问题

    VS Code写C语言输出long double类型数据不正确的问题 在学习<C Primer Plus>一书时遇到一个例题 #include <stdio.h>int mai ...

  7. vs code 运行C语言并调试

    vs code 运行C语言 2022.03.19 mingw64下载地址更新(window) task.json文件修改 launch.json文件修改 更新版(window) 1.下载MinGW编译 ...

  8. macbook如何使用visual studio code进行c语言编程

    macbook如何使用visual studio code进行c语言编程 Mac用Visual Studio Code编写C/C++ 苹果电脑VS Code快速编写C/C++教程 最近打算重新学习c语 ...

  9. Windows10下利用Visual Studio Code搭建C语言开发环境

    Windows10下利用Visual Studio Code搭建C语言开发环境 1. 前言 2. 下载安装VSCode以及MinGW 2.1 下载安装VSCode 2.2 下载安装MinGW-w64 ...

  10. 如何安装配置VS Code|配置C语言编译环境|彻底卸载VS Code

    相信看到这里的小伙伴已经经历了安装配置VS Code的重重困难,不要灰心,学习编程语言的第一道考验就是安装配置编译环境,UP主这里帮你一站式解决问题,助你快速入门!进入正题. 分割线--------- ...

最新文章

  1. 华人科学家,Yang-Kieffer算法之父杨恩辉斩获Eric E.Summer奖
  2. 组合模式源码解析(jdk+mybatis)
  3. AGAGA XOOORRR CodeForces - 1516B
  4. linux实验总结及心得_安全实验室 | 内网渗透—Linux权限维持技巧总结
  5. Windows下用tree命令生成目录树
  6. Dubbo面试 - Dubbo通信协议
  7. 《电路分析导论(原书第12版)》一3.14 压控电阻
  8. 基于TortoiseGit完成本地代码上传Git远程仓库中
  9. 网站被黑了不要慌,4招教你如何破解!网站被黑的10大原因
  10. 对话机器学习大神Yoshua Bengio(下)
  11. LM393实现简易PWM调压电路
  12. quicktime不能成功安装
  13. 网络技术——网络管理技术
  14. 并发编程之CompletableFuture全网最细最全用法(一)
  15. 【数学建模】主成因分析
  16. SSM酒店预订客房管理系统(包含数据库及项目说明)
  17. 中央大学计算机学什么,中央大学讲解
  18. 名编辑电子杂志大师教程 | 添加页码
  19. 随机过程(2)__马尔可夫链的主要性质__查普曼-科莫高洛夫方程
  20. Xilinx Zynq mpsoc 的 pcie Tandem 配置

热门文章

  1. xshell与虚拟机VMware中centos6.7系统突然连不上
  2. 【UVALive - 7344】Numbered Cards【数位DP+状压DP】
  3. 【0x50 动态规划】传纸条【线性DP】
  4. 【2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) E】Cops And Roobers【最小割】
  5. 线性代数中一些有关秩的不等式
  6. php mysql多条件查询界面_PHP组合查询多条件查询实例代码
  7. 【转】Intellij Idea识别Java Web项目
  8. linux双显卡配置_Kali Linux 2.0 安装 NVIDIA显卡驱动实现双显卡(联想笔记本)
  9. 什么是安全查找Bean,什么是非安全查找Bean?如何安全地查找Bean?
  10. Tomcat,servlet以及netty之间的简单区别