In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail how to realize the picture JNI C++\ Java Gaussian blur. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
Let's get to work
Description: most of the code comes from the network, but it is open source.
The original code:
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] = {512512456512328456335512405328271456388335292512 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, 385381377374370367363360357354350347344341338335 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, 289287285282280278275273271269267265263261259} Static unsigned char const stackblur_shr [255] = {9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 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, 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 bodyvoid stackblurJob (unsigned char* src, / /
< input image data unsigned int w, ///< image width unsigned int h, ///< image height unsigned int radius, ///< blur intensity (should be in 2..254 range) int cores, ///< total number of working threads int core, ///< current thread number int 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 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 2 if (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,0 for(i = 0; i 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 colorvoid stackblur (unsigned char* src, / /
< input image data unsigned int w, ///< image width unsigned int h, ///< image height unsigned 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 multithreading stackblurJob(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;}
This is the code of C++.
An example of an open source Android vagueness was found online, with a Java version of the code.
JavaBlurProcess.javaimport android.graphics.Bitmap;import java.util.ArrayList;import java.util.concurrent.Callable Class JavaBlurProcess implements BlurProcess {private static final short [] stackblur_mul = {512,512,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} Private static final byte [] stackblur_shr = {9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 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} @ Override public Bitmap blur (Bitmap original, float radius) {int w = original.getWidth (); int h = original.getHeight (); int [] currentPixels = new int [w * h]; original.getPixels (currentPixels, 0, w, 0, w, h); int cores = StackBlurManager.EXECUTOR_THREADS ArrayList horizontal = new ArrayList (cores); ArrayList vertical = new ArrayList (cores); for (int I = 0; I
< cores; i++) { horizontal.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 1)); vertical.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 2)); } try { StackBlurManager.EXECUTOR.invokeAll(horizontal); } catch (InterruptedException e) { return null; } try { StackBlurManager.EXECUTOR.invokeAll(vertical); } catch (InterruptedException e) { return null; } return Bitmap.createBitmap(currentPixels, w, h, Bitmap.Config.ARGB_8888); } private static void blurIteration(int[] src, int w, int h, int radius, int cores, int core, int step) { int x, y, xp, yp, i; int sp; int stack_start; int stack_i; int src_i; int dst_i; long sum_r, sum_g, sum_b, sum_in_r, sum_in_g, sum_in_b, sum_out_r, sum_out_g, sum_out_b; int wm = w - 1; int hm = h - 1; int div = (radius * 2) + 1; int mul_sum = stackblur_mul[radius]; byte shr_sum = stackblur_shr[radius]; int[] stack = new int[div]; 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_in_r = sum_in_g = sum_in_b = sum_out_r = sum_out_g = sum_out_b = 0; src_i = w * y; // start of line (0,y) for(i = 0; i >> 16) & 0xff) * (I + 1); sum_g + = ((SRC [SRC _ I] > > 8) & 0xff) * (I + 1); sum_b + = (SRC [SRC _ I] & 0xff) * (I + 1) Sum_out_r + = (src [src] > > 16) & 0xff); sum_out_g + = ((src [src] > > 8) & 0xff); sum_out_b + = (src [src] & 0xff) } for (I = 1; I > 16) & 0xff) * (radius + 1-I); sum_g + = ((src [src _ I] > > 8) & 0xff) * (radius + 1-I) Sum_b + = (src [src] & 0xff) * (radius + 1-I); sum_in_r + = ((src [src] > 16) & 0xff); sum_in_g + = ((src [src] > 8) & 0xff) Sum_in_b + = (SRC [src _ I] & 0xff);} sp = radius; xp = radius; if (xp > wm) xp = wm Src_i = xp + y * w; / / img.pix_ptr (xp, y); dst_i = y * w; / / img.pix_ptr (0, y); for (x = 0; x
< w; x++) { src[dst_i] = (int) ((src[dst_i] & 0xff000000) | ((((sum_r * mul_sum) >> > shr_sum) & 0xff) > > shr_sum) & 0xff) > > shr_sum) & 0xff); dst_i + = 1; sum_r-= sum_out_r; sum_g-= sum_out_g Sum_b-= sum_out_b; stack_start = sp + div-radius; if (stack_start > = div) stack_start-= div; stack_i = stack_start Sum_out_r-= (stack [stack _ I] > > 16) & 0xff); sum_out_g-= ((stack [stack _ I] > > 8) & 0xff); sum_out_b-= (stack [stack _ I] & 0xff) If (xp
< wm) { src_i += 1; ++xp; } stack[stack_i] = src[src_i]; sum_in_r += ((src[src_i] >> 16) & 0xff); sum_in_g + = (src [src _ I] > 8) & 0xff); sum_in_b + = (src [src _ I] & 0xff); sum_r + = sum_in_r Sum_g + = sum_in_g; sum_b + = sum_in_b; + + sp; if (sp > = div) sp = 0 Stack_i = sp; sum_out_r + = (Stack [stack _ I] > > 16) & 0xff); sum_out_g + = ((Stack [stack _ I] > > 8) & 0xff) Sum_out_b + = (stack [stack _ I] & 0xff); sum_in_r-= ((stack [stack _ I] > 16) & 0xff); sum_in_g-= ((stack [stack _ I] > > 8) & 0xff) Sum_in_b-= (Stack [stack _ I] & 0xff) }} / / step 2 else if (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_in_r = sum_in_g = sum_in_b = sum_out_r = sum_out_g = sum_out_b = 0; src_i = x; // x,0 for(i = 0; i >> 16) & 0xff) * (I + 1); sum_g + = ((SRC [SRC _ I] > > 8) & 0xff) * (I + 1); sum_b + = (SRC [SRC _ I] & 0xff) * (I + 1) Sum_out_r + = (src [src] > > 16) & 0xff); sum_out_g + = ((src [src] > > 8) & 0xff); sum_out_b + = (src [src] & 0xff) } for (I = 1; I > 16) & 0xff) * (radius + 1-I); sum_g + = ((src [src _ I] > > 8) & 0xff) * (radius + 1-I) Sum_b + = (src [src] & 0xff) * (radius + 1-I); sum_in_r + = ((src [src] > 16) & 0xff); sum_in_g + = ((src [src] > 8) & 0xff) Sum_in_b + = (SRC [src _ I] & 0xff);} sp = radius; yp = radius; if (yp > hm) yp = hm Src_i = x + yp * w; / / img.pix_ptr (x, yp); dst_i = x; / / img.pix_ptr (x, 0); for (y = 0; y
< h; y++) { src[dst_i] = (int) ((src[dst_i] & 0xff000000) | ((((sum_r * mul_sum) >> > shr_sum) & 0xff) > > shr_sum) & 0xff) > > shr_sum) & 0xff); dst_i + = w; sum_r-= sum_out_r; sum_g-= sum_out_g Sum_b-= sum_out_b; stack_start = sp + div-radius; if (stack_start > = div) stack_start-= div; stack_i = stack_start Sum_out_r-= (stack [stack _ I] > > 16) & 0xff); sum_out_g-= ((stack [stack _ I] > > 8) & 0xff); sum_out_b-= (stack [stack _ I] & 0xff) If (yp
< hm) { src_i += w; // stride ++yp; } stack[stack_i] = src[src_i]; sum_in_r += ((src[src_i] >> 16) & 0xff); sum_in_g + = (src [src _ I] > 8) & 0xff); sum_in_b + = (src [src _ I] & 0xff); sum_r + = sum_in_r Sum_g + = sum_in_g; sum_b + = sum_in_b; + + sp; if (sp > = div) sp = 0 Stack_i = sp; sum_out_r + = (Stack [stack _ I] > > 16) & 0xff); sum_out_g + = ((Stack [stack _ I] > > 8) & 0xff) Sum_out_b + = (stack [stack _ I] & 0xff); sum_in_r-= ((stack [stack _ I] > 16) & 0xff); sum_in_g-= ((stack [stack _ I] > > 8) & 0xff) Sum_in_b-= (Stack [stack _ I] & 0xff);}} private static class BlurTask implements Callable {private final int [] _ src; private final int _ w Private final int _ h; private final int _ radius; private final int _ totalCores; private final int _ coreIndex; private final int _ round; public BlurTask (int [] src, int w, int h, int radius, int totalCores, int coreIndex, int round) {_ src = src _ w = w; _ h = h; _ radius = radius; _ totalCores = totalCores; _ coreIndex = coreIndex; _ round = round @ Override public Void call () throws Exception {blurIteration (_ src, _ w, _ h, _ radius, _ totalCores, _ coreIndex, _ round); return null;}
This code has the same source as the code of C++. Let's make a brief analysis.
Analysis entry: public Bitmap blur (Bitmap original, float radius) {int w = original.getWidth (); int h = original.getHeight (); int [] currentPixels = new int [w * h]; original.getPixels (currentPixels, 0, w, 0, w, h); int cores = StackBlurManager.EXECUTOR_THREADS ArrayList horizontal = new ArrayList (cores); ArrayList vertical = new ArrayList (cores); for (int I = 0; I < cores; iTunes +) {horizontal.add (new BlurTask (currentPixels, w, h, (int) radius, cores, I, 1)) Vertical.add (new BlurTask (currentPixels, w, h, (int) radius, cores, I, 2);} try {StackBlurManager.EXECUTOR.invokeAll (horizontal);} catch (InterruptedException e) {return null } try {StackBlurManager.EXECUTOR.invokeAll (vertical);} catch (InterruptedException e) {return null;} return Bitmap.createBitmap (currentPixels, w, h, Bitmap.Config.ARGB_8888);}
After entering the method, we first get the pixel set of the picture, and then New two List to store the BlurTask respectively.
Look at BlurTask: private static class BlurTask implements Callable {private final int [] _ src; private final int _ w; private final int _ h; private final int _ radius; private final int _ totalCores; private final int _ coreIndex; private final int _ round Public BlurTask (int [] src, int w, int h, int radius, int totalCores, int coreIndex, int round) {_ src = src; _ w = w; _ h = h; _ radius = radius; _ totalCores = totalCores _ coreIndex = coreIndex; _ round = round;} @ Override public Void call () throws Exception {blurIteration (_ src, _ w, _ h, _ radius, _ totalCores, _ coreIndex, _ round); return null;}}
You can see that BlurTask is a callback class for thread pooling; it mainly calls the method blurIteration to obfuscate.
At the same time, the parameters passed in to the method are:
Pixel set
Width
High
Blur radius
Maximum kernel number
Current kernel
Steps
Then go back to the first step:
Int cores = StackBlurManager.EXECUTOR_THREADS
It is actually called:
Runtime.getRuntime () .availableProcessors ()
This method is used to return the number of cores of the current virtual machine; this method can be used to allocate multi-threads with the greatest efficiency.
Then:
For (int I = 0; I < cores; ionization +) {horizontal.add (new BlurTask (currentPixels, w, h, (int) radius, cores, I, 1)); vertical.add (new BlurTask (currentPixels (currentPixels, w, h, (int) radius, cores, I, 2));}
You can see that the corresponding thread callback operations are added to the list; they are steps 1 and 2, respectively.
Then:
Try {StackBlurManager.EXECUTOR.invokeAll (horizontal);} catch (InterruptedException e) {return null;} try {StackBlurManager.EXECUTOR.invokeAll (vertical);} catch (InterruptedException e) {return null }
In this method: StackBlurManager.EXECUTOR is actually:
Executors.newFixedThreadPool (Runtime.getRuntime () .availableProcessors ())
You can see that a thread pool is actually established, and the number of running threads in the thread pool is the number of cores of the current virtual machine.
Then throw the collection of step 1 into the thread pool and wait for the execution to complete; then throw it into step 2.
In fact, you can see from its name:
Step 1 is actually blurring the horizontal direction
Step 2 is actually blurring the vertical direction
Specifically, you can take a look at the blurIteration method.
The method is simplified because it is too long:
Private static void blurIteration (int [] src, int w, int h, int radius, int cores, int core, int step) {. If (step = = 1) {int minY = core * h / cores; int maxY = (core + 1) * h / cores; for (y = minY; y < maxY Yearly +) {...}} / / step 2 else if (step = = 2) {int minX = core * w / cores Int maxX = (core + 1) * w / cores; for (x = minX; x < maxX; x +) {...}
It can be seen that the blurring is horizontal and vertical respectively.
At the same time, when blurred, it is divided into many parts, depending on the virtual core number.
It is necessary to make it clear here that when blurring, you can only blur the first step before blurring the second part.
It means that the first step and the second step cannot be carried out at the same time; if you don't agree, you can change the above two lists to be multithreaded at the same time.
test
There is no screenshot here, but according to my test, this fuzzy method has obvious advantages in multithreading; that is to say, the higher the number of cores, the faster the blur speed.
If the method executes sequentially and does not use multithreading, then its obfuscation takes about 1 and 4 more time than the method I introduced in the previous chapter.
On how to carry out the picture JNI C++\ Java Gaussian blur implementation is shared here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.