Android實現(xiàn)圖片高斯模糊
更新時間:2022年02月16日 10:55:12 投稿:lijiao
這篇文章主要為大家詳細介紹了Android實現(xiàn)圖片高斯模糊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Android實現(xiàn)圖片高斯模糊的具體代碼,供大家參考,具體內(nèi)容如下
原圖:

高斯模糊后:

FastBlur.java
import android.graphics.Bitmap;
/**
?* Description:
?* User: chenzheng
?* Date: 2017/2/22 0022
?* Time: 12:22
?*/
public class FastBlur {
? ? public static Bitmap doBlur(Bitmap sentBitmap, int radius,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? boolean canReuseInBitmap) {
? ? ? ? Bitmap bitmap;
? ? ? ? if (canReuseInBitmap) {
? ? ? ? ? ? bitmap = sentBitmap;
? ? ? ? } else {
? ? ? ? ? ? bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
? ? ? ? }
? ? ? ? if (radius < 1) {
? ? ? ? ? ? return (null);
? ? ? ? }
? ? ? ? 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++) {
? ? ? ? ? ? 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 + Math.min(wm, Math.max(i, 0))];
? ? ? ? ? ? ? ? sir = stack[i + radius];
? ? ? ? ? ? ? ? sir[0] = (p & 0xff0000) >> 16;
? ? ? ? ? ? ? ? sir[1] = (p & 0x00ff00) >> 8;
? ? ? ? ? ? ? ? sir[2] = (p & 0x0000ff);
? ? ? ? ? ? ? ? rbs = r1 - Math.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] = Math.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 = Math.max(0, yp) + x;
? ? ? ? ? ? ? ? sir = stack[i + radius];
? ? ? ? ? ? ? ? sir[0] = r[yi];
? ? ? ? ? ? ? ? sir[1] = g[yi];
? ? ? ? ? ? ? ? sir[2] = b[yi];
? ? ? ? ? ? ? ? rbs = r1 - Math.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++) {
? ? ? ? ? ? ? ? // Preserve alpha channel: ( 0xff000000 & pix[yi] )
? ? ? ? ? ? ? ? pix[yi] = (0xff000000 & pix[yi]) | (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] = Math.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;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? bitmap.setPixels(pix, 0, w, 0, 0, w, h);
? ? ? ? return (bitmap);
? ? }
}調(diào)用方法:
private void applyBlur(String filePath) {
? ? ? ? int radius = 1;//模糊程度
? ? ? ? int scaleRatio = 5;
? ? ? ? Bitmap originBitmap = BitmapFactory.decodeFile(filePath, getBitmapOption(2)); //將圖片的長和寬縮小味原來的1/2
? ? ? ? Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
? ? ? ? ? ? ? ? originBitmap.getWidth() / scaleRatio,
? ? ? ? ? ? ? ? originBitmap.getHeight() / scaleRatio,
? ? ? ? ? ? ? ? false);
? ? ? ? Bitmap blurBitmap = FastBlur.doBlur(scaledBitmap, radius, true);
? ? ? ? navLayout.setBackgroundDrawable(new BitmapDrawable(blurBitmap));
? ? }private BitmapFactory.Options getBitmapOption(int inSampleSize){
? ? ? ? System.gc();
? ? ? ? BitmapFactory.Options options = new BitmapFactory.Options();
? ? ? ? options.inPurgeable = true;
? ? ? ? options.inSampleSize = inSampleSize;
? ? ? ? return options;
?}以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android編程使用加速度傳感器實現(xiàn)搖一搖功能及優(yōu)化的方法詳解
這篇文章主要介紹了Android編程使用加速度傳感器實現(xiàn)搖一搖功能及優(yōu)化的方法,結合實例形式分析了Android傳感器的調(diào)用方法、參數(shù)含義及具體使用技巧,需要的朋友可以參考下2017-08-08
Android SQLite數(shù)據(jù)庫連接實現(xiàn)登錄功能
這篇文章主要為大家詳細介紹了Android SQLite數(shù)據(jù)庫連接實現(xiàn)登錄功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-10-10
Android編程使用內(nèi)容提供者方式(ContentProvider)進行存儲的方法
這篇文章主要介紹了Android編程使用內(nèi)容提供者方式進行存儲的方法,涉及Android內(nèi)容提供者的創(chuàng)建,配置及針對數(shù)據(jù)的增刪改查等操作技巧,需要的朋友可以參考下2016-01-01
淺談Android中適配器的notifyDataSetChanged()為何有時不刷新
這篇文章主要介紹了淺談Android中適配器的notifyDataSetChanged()為何有時不刷新,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
Android ConstraintLayout約束布局使用實例介紹
ConstraintLayout是Google在Google I/O 2016大會上發(fā)布的一種新的布局容器(ViewGroup),它支持以靈活的方式來放置子控件和調(diào)整子控件的大小,下面這篇文章主要給大家介紹了關于Android中ConstraintLayout約束布局詳細解析的相關資料,需要的朋友可以參考下2022-10-10

