android高斯模糊

2021-07-12 07:15:11 字數 4130 閱讀 5976

高斯模糊演算法介紹

高斯模糊就是將指定畫素變換為其與周邊畫素加權平均後的值,權重就是高斯分布函式計算出來的值。演算法介紹

一、通過自身的寫演算法

public static void gaussblur(int data, int width, int height, int radius, float sigma) 

for (int i = 0, length = gaussmatrix.length; i < length; ++i)

// x direction

for (int y = 0; y < height; ++y)

}int index = y * width + x;

int cr = (int) (r / gausssum);

int cg = (int) (g / gausssum);

int cb = (int) (b / gausssum);

data[index] = cr << 16 | cg << 8 | cb | 0xff000000;}}

// y direction

for (int x = 0; x < width; ++x)

}int index = y * width + x;

int cr = (int) (r / gausssum);

int cg = (int) (g / gausssum);

int cb = (int) (b / gausssum);

data[index] = cr << 16 | cg << 8 | cb | 0xff000000;}}

}

實際測試會發現這種計算方式是很耗時間的,而且模糊半徑越大,從原理也可以看到計算量是平方增長的,所以計算時間也越長。

二、通過android自帶的影象處理工具類

public static bitmap blurbitmap(bitmap bitmap, float radius, context context)
renderscript是android在api 11之後加入的,用於高效的處理,包括模糊、混合、矩陣卷積計算等,renderscript的使用介紹鏈結。使用這種方式明顯處理起來更快很多,但是使用renderscript做高斯模糊,模糊半徑只能小於25

三、採用另一種特殊的演算法,比第一種要快,但是比renderscript還是要慢

public static bitmap doblur(bitmap sentbitmap, int radius, boolean canreuseinbitmap)  else 

if (radius < 1)

int w = bitmap.getwidth();

int h = bitmap.getheight();

int pix = new int[w * h];

bitmap.getpixels(pix, 0, w, 0, 0, w, h);

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[math.max(w, h)];

int divsum = (div + 1) >> 1;

divsum *= divsum;

int dv = new int[256 * divsum];

for (i = 0; i < 256 * divsum; i++)

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++) else

}stackpointer = radius;

for (x = 0; x < w; x++)

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++) else

if (i < hm)

}yi = x;

stackpointer = radius;

for (y = 0; y < h; y++)

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;}}

bitmap.setpixels(pix, 0, w, 0, 0, w, h);

return (bitmap);

}

隨著手勢的滑動,越來越模糊

背景會隨著手指上滑模糊程度加深,實際使用中發現怎麼都達不到那樣流暢的效果,因為手勢重新整理的速度很快,每一幀都去重新模糊計算一遍,還是會有延遲,造成頁面卡頓。後來在一次偶然的開發中發現其實不需要每一幀都重新去模糊一遍,而是將最大程度模糊一次,之後和原圖疊加,通過改變疊加的模糊的alpha值來達到不同程度的模糊效。

mblurimage.setontouchlistener(new ontouchlistener()  else

if (alpha < 0.0)

mtextview.settext(string.valueof(alpha));

mblurimage.setalpha(alpha);

break;

case motionevent.action_up:

break;

} return

true;

} });

還有一種挺有意思的模糊實現:

classview蓋一層模糊層

Android設定高斯模糊

分享自己寫的乙個高斯模糊的工具類,可以根據bitmap,imageviw,drawable或者資源檔案設定 public class blurimageview blurfractional inpixels,outpixels,width,height,hradius blurfractional...

android 高斯模糊處理的簡單使用

android 高斯模糊處理的簡單使用 先是按比例壓縮,然後質量壓縮 然後模糊處理,然後非空判斷一直用 activity結束的時候recycle一下 測試機,三星note3,新鮮出爐,還沒測試低端機 override protected void onscrollchanged int l,int ...

Android進行高斯模糊的簡單實現

因為專案上有需求,將客人態的背景設定成使用者頭像的毛玻璃的效果 這句話怎麼這麼繞口,還是直接看吧 背景就是使用者的頭像 以前沒做過這種功能,所以上網查了一下,大牛們調研了很多種實現方法,因為需求比較簡單,對效能的要求沒有那麼苛刻,所以下面我將用最簡單的發來實現。思路是利用現有 android 提供的...