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

前几天一直在弄android上的图片模糊效果的实现!

一直找不到方法,看别人说都是调用JNI,但是JNI这个东西我还真不熟悉啊!

只好从零开始了!这里不讲JNI的平台搭建,只讲JNI的关键代码,具体的项目我会共享出来给大家!

对于JNI下使用C++来模糊图片这个我真的没找到,只好自己写C++的来实现了。

在国外的一个项目中找到了一个”堆栈模糊效果“,原型如下:

[javascript]  view plain copy
  1. // Stack Blur v1.0  
  2. //  
  3. // Author: Mario Klingemann <mario@quasimondo.com>  
  4. // http://incubator.quasimondo.com  
  5. // created Feburary 29, 2004  
  6.   
  7.   
  8. // This is a compromise between Gaussian Blur and Box blur  
  9. // It creates much better looking blurs than Box Blur, but is  
  10. // 7x faster than my Gaussian Blur implementation.  
  11. //  
  12. // I called it Stack Blur because this describes best how this  
  13. // filter works internally: it creates a kind of moving stack  
  14. // of colors whilst scanning through the image. Thereby it  
  15. // just has to add one new block of color to the right side  
  16. // of the stack and remove the leftmost color. The remaining  
  17. // colors on the topmost layer of the stack are either added on  
  18. // or reduced by one, depending on if they are on the right or  
  19. // on the left side of the stack.   
  20. //  
  21. // If you are using this algorithm in your code please add  
  22. // the following line:  
  23. //   
  24. // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>  
  25.   
  26. PImage a;  
  27. PImage b;  
  28.   
  29. void setup()  
  30. {  
  31.   a=loadImage("dog.jpg");  
  32.   size(a.width, a.height);  
  33.   b=new PImage(a.width, a.height);  
  34.   fill(255);  
  35.   noStroke();  
  36.   frameRate(25);  
  37. }  
  38.   
  39. void draw()  
  40. {  
  41.   System.arraycopy(a.pixels,0,b.pixels,0,a.pixels.length);  
  42.   fastblur(b,mouseY/4);  
  43.   image(b, 0, 0);  
  44. }  
  45.   
  46. void fastblur(PImage img,int radius){  
  47.   
  48.   if (radius<1){  
  49.     return;  
  50.   }  
  51.   int[] pix=img.pixels;  
  52.   int w=img.width;  
  53.   int h=img.height;  
  54.   int wm=w-1;  
  55.   int hm=h-1;  
  56.   int wh=w*h;  
  57.   int div=radius+radius+1;  
  58.   
  59.   int r[]=new int[wh];  
  60.   int g[]=new int[wh];  
  61.   int b[]=new int[wh];  
  62.   int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;  
  63.   int vmin[] = new int[max(w,h)];  
  64.   
  65.   int divsum=(div+1)>>1;  
  66.   divsum*=divsum;  
  67.   int dv[]=new int[256*divsum];  
  68.   for (i=0;i<256*divsum;i++){  
  69.     dv[i]=(i/divsum);  
  70.   }  
  71.   
  72.   yw=yi=0;  
  73.   
  74.   int[][] stack=new int[div][3];  
  75.   int stackpointer;  
  76.   int stackstart;  
  77.   int[] sir;  
  78.   int rbs;  
  79.   int r1=radius+1;  
  80.   int routsum,goutsum,boutsum;  
  81.   int rinsum,ginsum,binsum;  
  82.   
  83.   for (y=0;y<h;y++){  
  84.     rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;  
  85.     for(i=-radius;i<=radius;i++){  
  86.       p=pix[yi+min(wm,max(i,0))];  
  87.       sir=stack[i+radius];  
  88.       sir[0]=(p & 0xff0000)>>16;  
  89.       sir[1]=(p & 0x00ff00)>>8;  
  90.       sir[2]=(p & 0x0000ff);  
  91.       rbs=r1-abs(i);  
  92.       rsum+=sir[0]*rbs;  
  93.       gsum+=sir[1]*rbs;  
  94.       bsum+=sir[2]*rbs;  
  95.       if (i>0){  
  96.         rinsum+=sir[0];  
  97.         ginsum+=sir[1];  
  98.         binsum+=sir[2];  
  99.       } else {  
  100.         routsum+=sir[0];  
  101.         goutsum+=sir[1];  
  102.         boutsum+=sir[2];  
  103.       }  
  104.     }  
  105.     stackpointer=radius;  
  106.   
  107.     for (x=0;x<w;x++){  
  108.   
  109.       r[yi]=dv[rsum];  
  110.       g[yi]=dv[gsum];  
  111.       b[yi]=dv[bsum];  
  112.         
  113.       rsum-=routsum;  
  114.       gsum-=goutsum;  
  115.       bsum-=boutsum;  
  116.   
  117.       stackstart=stackpointer-radius+div;  
  118.       sir=stack[stackstart%div];  
  119.         
  120.       routsum-=sir[0];  
  121.       goutsum-=sir[1];  
  122.       boutsum-=sir[2];  
  123.         
  124.       if(y==0){  
  125.         vmin[x]=min(x+radius+1,wm);  
  126.       }  
  127.       p=pix[yw+vmin[x]];  
  128.         
  129.       sir[0]=(p & 0xff0000)>>16;  
  130.       sir[1]=(p & 0x00ff00)>>8;  
  131.       sir[2]=(p & 0x0000ff);  
  132.   
  133.       rinsum+=sir[0];  
  134.       ginsum+=sir[1];  
  135.       binsum+=sir[2];  
  136.   
  137.       rsum+=rinsum;  
  138.       gsum+=ginsum;  
  139.       bsum+=binsum;  
  140.         
  141.       stackpointer=(stackpointer+1)%div;  
  142.       sir=stack[(stackpointer)%div];  
  143.        
  144.       routsum+=sir[0];  
  145.       goutsum+=sir[1];  
  146.       boutsum+=sir[2];  
  147.        
  148.        rinsum-=sir[0];  
  149.       ginsum-=sir[1];  
  150.       binsum-=sir[2];  
  151.        
  152.        yi++;  
  153.     }  
  154.     yw+=w;  
  155.   }  
  156.   for (x=0;x<w;x++){  
  157.     rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;  
  158.     yp=-radius*w;  
  159.     for(i=-radius;i<=radius;i++){  
  160.       yi=max(0,yp)+x;  
  161.        
  162.        sir=stack[i+radius];  
  163.         
  164.       sir[0]=r[yi];  
  165.       sir[1]=g[yi];  
  166.       sir[2]=b[yi];  
  167.        
  168.       rbs=r1-abs(i);  
  169.         
  170.       rsum+=r[yi]*rbs;  
  171.       gsum+=g[yi]*rbs;  
  172.       bsum+=b[yi]*rbs;  
  173.        
  174.       if (i>0){  
  175.         rinsum+=sir[0];  
  176.         ginsum+=sir[1];  
  177.         binsum+=sir[2];  
  178.       } else {  
  179.         routsum+=sir[0];  
  180.         goutsum+=sir[1];  
  181.         boutsum+=sir[2];  
  182.       }  
  183.         
  184.       if(i<hm){  
  185.         yp+=w;  
  186.       }  
  187.     }  
  188.     yi=x;  
  189.     stackpointer=radius;  
  190.     for (y=0;y<h;y++){  
  191.       pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];  
  192.   
  193.       rsum-=routsum;  
  194.       gsum-=goutsum;  
  195.       bsum-=boutsum;  
  196.   
  197.       stackstart=stackpointer-radius+div;  
  198.       sir=stack[stackstart%div];  
  199.        
  200.       routsum-=sir[0];  
  201.       goutsum-=sir[1];  
  202.       boutsum-=sir[2];  
  203.        
  204.        if(x==0){  
  205.         vmin[y]=min(y+r1,hm)*w;  
  206.       }  
  207.       p=x+vmin[y];  
  208.         
  209.       sir[0]=r[p];  
  210.       sir[1]=g[p];  
  211.       sir[2]=b[p];  
  212.         
  213.       rinsum+=sir[0];  
  214.       ginsum+=sir[1];  
  215.       binsum+=sir[2];  
  216.   
  217.       rsum+=rinsum;  
  218.       gsum+=ginsum;  
  219.       bsum+=binsum;  
  220.   
  221.       stackpointer=(stackpointer+1)%div;  
  222.       sir=stack[stackpointer];  
  223.        
  224.       routsum+=sir[0];  
  225.       goutsum+=sir[1];  
  226.       boutsum+=sir[2];  
  227.         
  228.       rinsum-=sir[0];  
  229.       ginsum-=sir[1];  
  230.       binsum-=sir[2];  
  231.   
  232.       yi+=w;  
  233.     }  
  234.   }  
  235.     
  236.   img.updatePixels();  
  237. }  

同时找到一个借鉴这个所改进后成为Java的代码,具体如下:

[java]  view plain copy
  1. public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {  
  2.     // Stack Blur v1.0 from  
  3.     // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html  
  4.     //  
  5.     // Java Author: Mario Klingemann <mario at quasimondo.com>  
  6.     // http://incubator.quasimondo.com  
  7.     // created Feburary 29, 2004  
  8.     // Android port : Yahel Bouaziz <yahel at kayenko.com>  
  9.     // http://www.kayenko.com  
  10.     // ported april 5th, 2012  
  11.   
  12.     // This is a compromise between Gaussian Blur and Box blur  
  13.     // It creates much better looking blurs than Box Blur, but is  
  14.     // 7x faster than my Gaussian Blur implementation.  
  15.     //  
  16.     // I called it Stack Blur because this describes best how this  
  17.     // filter works internally: it creates a kind of moving stack  
  18.     // of colors whilst scanning through the image. Thereby it  
  19.     // just has to add one new block of color to the right side  
  20.     // of the stack and remove the leftmost color. The remaining  
  21.     // colors on the topmost layer of the stack are either added on  
  22.     // or reduced by one, depending on if they are on the right or  
  23.     // on the left side of the stack.  
  24.     //  
  25.     // If you are using this algorithm in your code please add  
  26.     // the following line:  
  27.     //  
  28.     // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>  
  29.   
  30.     Bitmap bitmap;  
  31.     if (canReuseInBitmap) {  
  32.         bitmap = sentBitmap;  
  33.     } else {  
  34.         bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);  
  35.     }  
  36.   
  37.     if (radius < 1) {  
  38.         return (null);  
  39.     }  
  40.   
  41.     int w = bitmap.getWidth();  
  42.     int h = bitmap.getHeight();  
  43.   
  44.     int[] pix = new int[w * h];  
  45.     bitmap.getPixels(pix, 0, w, 00, w, h);  
  46.   
  47.     int wm = w - 1;  
  48.     int hm = h - 1;  
  49.     int wh = w * h;  
  50.     int div = radius + radius + 1;  
  51.   
  52.     int r[] = new int[wh];  
  53.     int g[] = new int[wh];  
  54.     int b[] = new int[wh];  
  55.     int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;  
  56.     int vmin[] = new int[Math.max(w, h)];  
  57.   
  58.     int divsum = (div + 1) >> 1;  
  59.     divsum *= divsum;  
  60.     int dv[] = new int[256 * divsum];  
  61.     for (i = 0; i < 256 * divsum; i++) {  
  62.         dv[i] = (i / divsum);  
  63.     }  
  64.   
  65.     yw = yi = 0;  
  66.   
  67.     int[][] stack = new int[div][3];  
  68.     int stackpointer;  
  69.     int stackstart;  
  70.     int[] sir;  
  71.     int rbs;  
  72.     int r1 = radius + 1;  
  73.     int routsum, goutsum, boutsum;  
  74.     int rinsum, ginsum, binsum;  
  75.   
  76.     for (y = 0; y < h; y++) {  
  77.         rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  78.         for (i = -radius; i <= radius; i++) {  
  79.             p = pix[yi + Math.min(wm, Math.max(i, 0))];  
  80.             sir = stack[i + radius];  
  81.             sir[0] = (p & 0xff0000) >> 16;  
  82.             sir[1] = (p & 0x00ff00) >> 8;  
  83.             sir[2] = (p & 0x0000ff);  
  84.             rbs = r1 - Math.abs(i);  
  85.             rsum += sir[0] * rbs;  
  86.             gsum += sir[1] * rbs;  
  87.             bsum += sir[2] * rbs;  
  88.             if (i > 0) {  
  89.                 rinsum += sir[0];  
  90.                 ginsum += sir[1];  
  91.                 binsum += sir[2];  
  92.             } else {  
  93.                 routsum += sir[0];  
  94.                 goutsum += sir[1];  
  95.                 boutsum += sir[2];  
  96.             }  
  97.         }  
  98.         stackpointer = radius;  
  99.   
  100.         for (x = 0; x < w; x++) {  
  101.   
  102.             r[yi] = dv[rsum];  
  103.             g[yi] = dv[gsum];  
  104.             b[yi] = dv[bsum];  
  105.   
  106.             rsum -= routsum;  
  107.             gsum -= goutsum;  
  108.             bsum -= boutsum;  
  109.   
  110.             stackstart = stackpointer - radius + div;  
  111.             sir = stack[stackstart % div];  
  112.   
  113.             routsum -= sir[0];  
  114.             goutsum -= sir[1];  
  115.             boutsum -= sir[2];  
  116.   
  117.             if (y == 0) {  
  118.                 vmin[x] = Math.min(x + radius + 1, wm);  
  119.             }  
  120.             p = pix[yw + vmin[x]];  
  121.   
  122.             sir[0] = (p & 0xff0000) >> 16;  
  123.             sir[1] = (p & 0x00ff00) >> 8;  
  124.             sir[2] = (p & 0x0000ff);  
  125.   
  126.             rinsum += sir[0];  
  127.             ginsum += sir[1];  
  128.             binsum += sir[2];  
  129.   
  130.             rsum += rinsum;  
  131.             gsum += ginsum;  
  132.             bsum += binsum;  
  133.   
  134.             stackpointer = (stackpointer + 1) % div;  
  135.             sir = stack[(stackpointer) % div];  
  136.   
  137.             routsum += sir[0];  
  138.             goutsum += sir[1];  
  139.             boutsum += sir[2];  
  140.   
  141.             rinsum -= sir[0];  
  142.             ginsum -= sir[1];  
  143.             binsum -= sir[2];  
  144.   
  145.             yi++;  
  146.         }  
  147.         yw += w;  
  148.     }  
  149.     for (x = 0; x < w; x++) {  
  150.         rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  151.         yp = -radius * w;  
  152.         for (i = -radius; i <= radius; i++) {  
  153.             yi = Math.max(0, yp) + x;  
  154.   
  155.             sir = stack[i + radius];  
  156.   
  157.             sir[0] = r[yi];  
  158.             sir[1] = g[yi];  
  159.             sir[2] = b[yi];  
  160.   
  161.             rbs = r1 - Math.abs(i);  
  162.   
  163.             rsum += r[yi] * rbs;  
  164.             gsum += g[yi] * rbs;  
  165.             bsum += b[yi] * rbs;  
  166.   
  167.             if (i > 0) {  
  168.                 rinsum += sir[0];  
  169.                 ginsum += sir[1];  
  170.                 binsum += sir[2];  
  171.             } else {  
  172.                 routsum += sir[0];  
  173.                 goutsum += sir[1];  
  174.                 boutsum += sir[2];  
  175.             }  
  176.   
  177.             if (i < hm) {  
  178.                 yp += w;  
  179.             }  
  180.         }  
  181.         yi = x;  
  182.         stackpointer = radius;  
  183.         for (y = 0; y < h; y++) {  
  184.             // Preserve alpha channel: ( 0xff000000 & pix[yi] )  
  185.             pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];  
  186.   
  187.             rsum -= routsum;  
  188.             gsum -= goutsum;  
  189.             bsum -= boutsum;  
  190.   
  191.             stackstart = stackpointer - radius + div;  
  192.             sir = stack[stackstart % div];  
  193.   
  194.             routsum -= sir[0];  
  195.             goutsum -= sir[1];  
  196.             boutsum -= sir[2];  
  197.   
  198.             if (x == 0) {  
  199.                 vmin[y] = Math.min(y + r1, hm) * w;  
  200.             }  
  201.             p = x + vmin[y];  
  202.   
  203.             sir[0] = r[p];  
  204.             sir[1] = g[p];  
  205.             sir[2] = b[p];  
  206.   
  207.             rinsum += sir[0];  
  208.             ginsum += sir[1];  
  209.             binsum += sir[2];  
  210.   
  211.             rsum += rinsum;  
  212.             gsum += ginsum;  
  213.             bsum += binsum;  
  214.   
  215.             stackpointer = (stackpointer + 1) % div;  
  216.             sir = stack[stackpointer];  
  217.   
  218.             routsum += sir[0];  
  219.             goutsum += sir[1];  
  220.             boutsum += sir[2];  
  221.   
  222.             rinsum -= sir[0];  
  223.             ginsum -= sir[1];  
  224.             binsum -= sir[2];  
  225.   
  226.             yi += w;  
  227.         }  
  228.     }  
  229.   
  230.     bitmap.setPixels(pix, 0, w, 00, w, h);  
  231.     return (bitmap);  
  232. }  

借鉴于此我弄了一个C的代码,基本上的整体过程都没有变化,只是改变成了C(C++也可已)的而已:

文件名:ImageBlur.c

[cpp]  view plain copy
  1. /************************************************* 
  2. Copyright:  Copyright QIUJUER 2013. 
  3. Author:     Qiujuer 
  4. Date:       2014-04-18 
  5. Description:实现图片模糊处理 
  6. **************************************************/  
  7. #include<malloc.h>  
  8.   
  9. #define ABS(a) ((a)<(0)?(-a):(a))  
  10. #define MAX(a,b) ((a)>(b)?(a):(b))  
  11. #define MIN(a,b) ((a)<(b)?(a):(b))  
  12.   
  13. /************************************************* 
  14. Function:       StackBlur(堆栈模糊) 
  15. Description:    使用堆栈方式进行图片像素模糊处理 
  16. Calls:          malloc 
  17. Table Accessed: NULL 
  18. Table Updated:  NULL 
  19. Input:          像素点集合,图片宽,图片高,模糊半径 
  20. Output:         返回模糊后的像素点集合 
  21. Return:         返回模糊后的像素点集合 
  22. Others:         NULL 
  23. *************************************************/  
  24. static int* StackBlur(int* pix, int w, int h, int radius) {  
  25.     int wm = w - 1;  
  26.     int hm = h - 1;  
  27.     int wh = w * h;  
  28.     int div = radius + radius + 1;  
  29.   
  30.     int *r = (int *)malloc(wh * sizeof(int));  
  31.     int *g = (int *)malloc(wh * sizeof(int));  
  32.     int *b = (int *)malloc(wh * sizeof(int));  
  33.     int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;  
  34.   
  35.     int *vmin = (int *)malloc(MAX(w,h) * sizeof(int));  
  36.   
  37.     int divsum = (div + 1) >> 1;  
  38.     divsum *= divsum;  
  39.     int *dv = (int *)malloc(256 * divsum * sizeof(int));  
  40.     for (i = 0; i < 256 * divsum; i++) {  
  41.         dv[i] = (i / divsum);  
  42.     }  
  43.   
  44.     yw = yi = 0;  
  45.   
  46.     int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int));  
  47.     int stackpointer;  
  48.     int stackstart;  
  49.     int *sir;  
  50.     int rbs;  
  51.     int r1 = radius + 1;  
  52.     int routsum, goutsum, boutsum;  
  53.     int rinsum, ginsum, binsum;  
  54.   
  55.     for (y = 0; y < h; y++) {  
  56.         rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  57.         for (i = -radius; i <= radius; i++) {  
  58.             p = pix[yi + (MIN(wm, MAX(i, 0)))];  
  59.             sir = stack[i + radius];  
  60.             sir[0] = (p & 0xff0000) >> 16;  
  61.             sir[1] = (p & 0x00ff00) >> 8;  
  62.             sir[2] = (p & 0x0000ff);  
  63.   
  64.             rbs = r1 - ABS(i);  
  65.             rsum += sir[0] * rbs;  
  66.             gsum += sir[1] * rbs;  
  67.             bsum += sir[2] * rbs;  
  68.             if (i > 0) {  
  69.                 rinsum += sir[0];  
  70.                 ginsum += sir[1];  
  71.                 binsum += sir[2];  
  72.             }  
  73.             else {  
  74.                 routsum += sir[0];  
  75.                 goutsum += sir[1];  
  76.                 boutsum += sir[2];  
  77.             }  
  78.         }  
  79.         stackpointer = radius;  
  80.   
  81.         for (x = 0; x < w; x++) {  
  82.   
  83.             r[yi] = dv[rsum];  
  84.             g[yi] = dv[gsum];  
  85.             b[yi] = dv[bsum];  
  86.   
  87.             rsum -= routsum;  
  88.             gsum -= goutsum;  
  89.             bsum -= boutsum;  
  90.   
  91.             stackstart = stackpointer - radius + div;  
  92.             sir = stack[stackstart % div];  
  93.   
  94.             routsum -= sir[0];  
  95.             goutsum -= sir[1];  
  96.             boutsum -= sir[2];  
  97.   
  98.             if (y == 0) {  
  99.                 vmin[x] = MIN(x + radius + 1, wm);  
  100.             }  
  101.             p = pix[yw + vmin[x]];  
  102.   
  103.             sir[0] = (p & 0xff0000) >> 16;  
  104.             sir[1] = (p & 0x00ff00) >> 8;  
  105.             sir[2] = (p & 0x0000ff);  
  106.   
  107.             rinsum += sir[0];  
  108.             ginsum += sir[1];  
  109.             binsum += sir[2];  
  110.   
  111.             rsum += rinsum;  
  112.             gsum += ginsum;  
  113.             bsum += binsum;  
  114.   
  115.             stackpointer = (stackpointer + 1) % div;  
  116.             sir = stack[(stackpointer) % div];  
  117.   
  118.             routsum += sir[0];  
  119.             goutsum += sir[1];  
  120.             boutsum += sir[2];  
  121.   
  122.             rinsum -= sir[0];  
  123.             ginsum -= sir[1];  
  124.             binsum -= sir[2];  
  125.   
  126.             yi++;  
  127.         }  
  128.         yw += w;  
  129.     }  
  130.     for (x = 0; x < w; x++) {  
  131.         rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  132.         yp = -radius * w;  
  133.         for (i = -radius; i <= radius; i++) {  
  134.             yi = MAX(0, yp) + x;  
  135.   
  136.             sir = stack[i + radius];  
  137.   
  138.             sir[0] = r[yi];  
  139.             sir[1] = g[yi];  
  140.             sir[2] = b[yi];  
  141.   
  142.             rbs = r1 - ABS(i);  
  143.   
  144.             rsum += r[yi] * rbs;  
  145.             gsum += g[yi] * rbs;  
  146.             bsum += b[yi] * rbs;  
  147.   
  148.             if (i > 0) {  
  149.                 rinsum += sir[0];  
  150.                 ginsum += sir[1];  
  151.                 binsum += sir[2];  
  152.             }  
  153.             else {  
  154.                 routsum += sir[0];  
  155.                 goutsum += sir[1];  
  156.                 boutsum += sir[2];  
  157.             }  
  158.   
  159.             if (i < hm) {  
  160.                 yp += w;  
  161.             }  
  162.         }  
  163.         yi = x;  
  164.         stackpointer = radius;  
  165.         for (y = 0; y < h; y++) {  
  166.             // Preserve alpha channel: ( 0xff000000 & pix[yi] )  
  167.             pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];  
  168.   
  169.             rsum -= routsum;  
  170.             gsum -= goutsum;  
  171.             bsum -= boutsum;  
  172.   
  173.             stackstart = stackpointer - radius + div;  
  174.             sir = stack[stackstart % div];  
  175.   
  176.             routsum -= sir[0];  
  177.             goutsum -= sir[1];  
  178.             boutsum -= sir[2];  
  179.   
  180.             if (x == 0) {  
  181.                 vmin[y] = MIN(y + r1, hm) * w;  
  182.             }  
  183.             p = x + vmin[y];  
  184.   
  185.             sir[0] = r[p];  
  186.             sir[1] = g[p];  
  187.             sir[2] = b[p];  
  188.   
  189.             rinsum += sir[0];  
  190.             ginsum += sir[1];  
  191.             binsum += sir[2];  
  192.   
  193.             rsum += rinsum;  
  194.             gsum += ginsum;  
  195.             bsum += binsum;  
  196.   
  197.             stackpointer = (stackpointer + 1) % div;  
  198.             sir = stack[stackpointer];  
  199.   
  200.             routsum += sir[0];  
  201.             goutsum += sir[1];  
  202.             boutsum += sir[2];  
  203.   
  204.             rinsum -= sir[0];  
  205.             ginsum -= sir[1];  
  206.             binsum -= sir[2];  
  207.   
  208.             yi += w;  
  209.         }  
  210.     }  
  211.   
  212.     free(r);  
  213.     free(g);  
  214.     free(b);  
  215.     free(vmin);  
  216.     free(dv);  
  217.     free(stack);  
  218.     return(pix);  
  219. }  
在改为这个的过程中还遇到 了一个很喜剧的问题,我发现我使用这个来进行调用后结果程序内存一直增大,直到500多M,直接卡死。我知道是我写的有内存泄漏了!

然后找了一下,发现果然是。只好进行free了。然后一下就好了,发现内存占用的确比Java的要少,速度也是要快一些!

在JNI中的实现我使用了两种方案,一种是直接传递文件,一直是传递像素点集合进行模糊!分别如下:

[cpp]  view plain copy
  1. /* 
  2.  * Class:     com_accumulation_imageblurring_app_jni_ImageBlur 
  3.  * Method:    blurIntArray 
  4.  * Signature: ([IIII)V 
  5.  */  
  6. JNIEXPORT void JNICALL Java_com_accumulation_imageblurring_app_jni_ImageBlur_blurIntArray  
  7.   (JNIEnv *, jclass, jintArray, jint, jint, jint);  
  8.   
  9. /* 
  10.  * Class:     com_accumulation_imageblurring_app_jni_ImageBlur 
  11.  * Method:    blurBitMap 
  12.  * Signature: (Landroid/graphics/Bitmap;I)V 
  13.  */  
  14. JNIEXPORT void JNICALL Java_com_accumulation_imageblurring_app_jni_ImageBlur_blurBitMap  
  15.   (JNIEnv *, jclass, jobject, jint);  

对应的Java调用:

[java]  view plain copy
  1. public class ImageBlur {  
  2.     public static native void blurIntArray(int[] pImg, int w, int h, int r);  
  3.   
  4.     public static native void blurBitMap(Bitmap bitmap, int r);  
  5.   
  6.     static {  
  7.         System.loadLibrary("JNI_ImageBlur");  
  8.     }  
  9. }  

///

此时我做了3种测试,一种是直接在Java层实现,一种是传递像素点集合模糊,还有就是直接传递图片进行模糊,结果如下:




通过上面的比较我们可以得出这样的结论:

1.Java的确最慢,但是其实也慢不了多少,虚拟机优化好了一样猛。

2.C中直接传递像素集合的速度最快(第一次启动)

3.在我多次切换界面后发现,直接传递像素点集合的耗时会增加,从60多到120多。

4.多次切换后发现,其实直接传递像素点的速度与传递图片过去的速度几乎一样。

5.多次操作后发现传递文件的波动较小,在100~138之间,其次是传递像素点集合的波动较大,java的波动最大!

以上就是我的结论,可能有些不正确,但是在我的机器上的确是这样!

注:勾选选择框“Downscale before blur”会先压缩图片后模糊然后放大图片,这样的情况下,模糊效果会稍微损失一些效果,但是其速度确实无法比拟的。

其耗时在:1~10ms内可运算完成。当然与你要模糊的大小有关系!


最后:项目地址:GitHub

原创作品,转载请注明出处!

    QIUJUER(qiujuer@live.cn)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值