The Fastblur of Android blur effect

Source: Internet
Author: User
Tags vmin

Blur

Since the iOS system introduced the Blur effect, that is, the so-called frosted glass, blur effect, matte effect, the big system began to race to imitate, this is a kind of effect, we now look at some diagram:



These are typical blur effects, and there are many more in iOS and MIUI, which are no longer mapped.


Realize

There are two main ways to achieve blur effect, one is to do it through Renderscript, and the other is to process the algorithm directly on the pixel point.

Renderscript is API11 after the introduction, so there is a limitation on the version, and Renderscript is indeed quite complicated, although the use of his blur function is very simple, but to really understand, not two days a day.

This paper mainly introduces another algorithm to achieve blur, this algorithm is currently available on the market for blur effect of a better algorithm, the forefront of the research site please poke me is blur.

Classic graphs:


Interested friends can go and have a look.


Use

Let's take a look at how to use Blur in Android, and of course we need to use the Fastblur mentioned above

Package Com.xys.blur;import android.graphics.bitmap;/** * Created is Paveld on 3/6/14.        */public class Fastblur {public static Bitmap Doblur (Bitmap sentbitmap, int radius, Boolean canreuseinbitmap) { Stack Blur v1.0 from//http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html/////Jav A Author:mario Klingemann <mario at quasimondo.com>//http://incubator.quasimondo.com//created Feb        Urary, 2004//Android Port:yahel Bouaziz <yahel at kayenko.com>//http://www.kayenko.com Ported April 5th,//This is a compromise between Gaussian Blur and Box Blur//It creates much bet        ter 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 K IND of moving stack//of colors whilst scanning through the image. THereby IT//just have to add one new block of color to the right side//the stack and remove the Leftmos T color. The remaining//colors on the topmost layer of the stack is either added on//or reduced by one, Dependin        G on if they is on the right or//on the left side of the stack. If you is using this algorithm in your code "ADD///The following line:////Sta        CK Blur Algorithm by Mario Klingemann <[email protected]> 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 < * 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; + +) {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; + +) {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 &Amp 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); }}

The algorithm is like this, do not ask me to understand, you understand.

Use

How to use it in a program is also simple:

Package Com.xys.blur;import Android.app.activity;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.paint;import Android.graphics.drawable.bitmapdrawable;import Android.os.bundle;import Android.view.view;import Android.view.viewtreeobserver.onpredrawlistener;import Android.widget.imageview;public class Test extends Activity { @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.main); final ImageView ImageView = (ImageView) Findviewbyid (r.id.image1); final Bitmap Bitmap = Bitmapfactory.decoderesource (Getresources (), R.drawable.blur); Imageview.getviewtreeobserver (). Addonpredrawlistener (New Onpredrawlistener () {@Overridepublic Boolean onpredraw () {blur (bitmap, ImageView); return true;});} private void Blur (Bitmap bkg, view view) {Long Startms = System.currenttimemillis (); Float Scalefactor = 8;float radius = 2 ; Bitmap overlay = Bitmap.createbitmap ((int) (viEw.getmeasuredwidth ()/Scalefactor), (int) (View.getmeasuredheight ()/scalefactor), Bitmap.Config.ARGB_8888); Canvas canvas = new canvas (overlay), Canvas.translate (-view.getleft ()/Scalefactor,-view.gettop ()/scalefactor); Canvas.scale (1/scalefactor, 1/scalefactor); Paint paint = new paint ();p aint.setflags (Paint.filter_bitmap_flag), Canvas.drawbitmap (bkg, 0, 0, paint); overlay = Fastblur.doblur (overlay, (int) radius, true), View.setbackground (New Bitmapdrawable (Getresources (), overlay)); System.out.println (System.currenttimemillis ()-Startms + "MS");}}

Why do we call the Blur method in Addonpredrawlistener, the friends who look at my previous article should know that this is to be able to get control dimensions in OnCreate, through scalefactor and radius two parameters, We're here to control the blur level.

There are a few more things to explain in the code:

1, why we want to narrow the picture through Scalefactor: Because in doing blur, the picture accuracy would have to be lowered, then why don't we first reduce the accuracy to deal with it, this effect is a huge reduction of the generation time

2, we give paint to provide filter_bitmap_flag marking, so that in the processing of BITMAP scaling, you can achieve double buffering effect, the process of fuzzy processing is more smooth

3, if we want to do a part of the blur effect, it is generally to cut down this part of the picture, and then blur to set the background of a control

The final effect is as follows:


The effect has come out, the demo is simple, just to demonstrate how to use it.

Above.


The Fastblur of Android blur effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.