Android dynamic Gaussian blur effect tutorial _android

Source: Internet
Author: User
Tags abs documentation gety throw exception

It's written in front.

Recently has been doing the preparation of the project, considering the possible use of a fuzzy effect, so I learned some Gauss fuzzy effect of the implementation. More famous is the Fastblur and its derivative of some of the optimization scheme, there is today to say renderscript.

Because this thing is now need to learn, so about some image processing and rendering problems do not mention. However, in the use of the process can really feel, although different schemes can achieve the same fuzzy effect, but the efficiency difference is really big.

This article is the realization of the Gaussian Blur is based on the following article to learn, first recommended. This article is about the same as its content, just a little more detail, and modifies some of the implementation logic and details in the code. But the main content is unchanged, so choose which article to learn is the same.

Here is a look at how to achieve such a Gaussian blur effect.

Simple Talk Renderscript

Because the implementation of the effect is based on renderscript, so it is necessary to understand first.

Judging from its official documents, it is iffy. We just need to know a little bit better:

Renderscript is a framework for running computationally intensive tasks in high performance on Android.
Renderscript is the framework for High-performance computing on the Android platform.
Since it is high-performance computing, it shows that renderscript image processing is very powerful, so use it to achieve Gaussian blur is a better choice.

So how do you use it? As you can see from the official documentation, if you need to use Renderscript in Java code, you must rely on the APIs in Android.renderscript or Android.support.v8.renderscript. Now that there is an API that's a lot better.

Here's a brief description of the steps to use, which is also stated in the official documentation:

    1. First you need to create a renderscript through the context;
    2. Second, create a script (Scriptintrinsic) that you need by creating a renderscript, such as the need for ambiguity here, which is scriptintrinsicblur;
    3. Then create at least one allocation class to create, allocate memory space;
    4. Then it is to do some processing of the image, such as fuzzy processing;
    5. After processing, the allocation class is needed to fill the allocated memory space;
    6. Finally, some resources can be recycled selectively.

The interpretation of the document is always very regular, more difficult to understand, we combine the original Bo main water long days of code to look at the steps:

/** * @author Qiushui * @description blur Picture Tool class * @revision Xiarui 16.09.05 */public class Blurbitmaputil {//Picture scaling

  Private static final float Bitmap_scale = 0.4f; /** * Fuzzy picture of the specific method * * @param context Object * @param image needs to blur the picture * @return the image after the blur/public static B Itmap Blurbitmap (context, Bitmap image,float Blurradius) {//calculate the long width int width = Math.Round (image.getw
    Idth () * Bitmap_scale);

    int height = Math.Round (image.getheight () * Bitmap_scale);
    The reduced picture as a pre-rendered picture Bitmap Inputbitmap = Bitmap.createscaledbitmap (image, width, height, false);

    Create a rendered output picture Bitmap Outputbitmap = Bitmap.createbitmap (Inputbitmap);
    Create Renderscript Kernel object Renderscript rs = renderscript.create (context);

    Create a fuzzy effect of the Renderscript tool object Scriptintrinsicblur Blurscript = Scriptintrinsicblur.create (RS, Element.u8_4 (RS)); Since Renderscript does not use a VM to allocate memory, it is necessary to use the allocation class to create and allocate memory space//When the allocation object is created, the memory is empty, and the need to use CopyTo () will countAccording to fill in allocation Tmpin = Allocation.createfrombitmap (RS, inputbitmap);

    Allocation Tmpout = Allocation.createfrombitmap (RS, outputbitmap);
    Setting the blur degree of the rendering, 25f is the maximum ambiguity Blurscript.setradius (Blurradius);
    Sets the input memory Blurscript.setinput (Tmpin) of the Blurscript object;

    Saves the output data to the output memory Blurscript.foreach (tmpout);

    Fill the data into the allocation Tmpout.copyto (OUTPUTBITMAP);
  return outputbitmap;

 }
}

Above is the processing of Gaussian blur code, where comments are written in great detail, and the picture has been scaled. In combination with the steps just said, we should be able to have a general impression, really do not understand it does not matter, this is a tool class, direct Copy come over.

Of course, the original Bo will be packaged into the code of the wheel, can also be directly referenced in the project Gradle is also possible, but I think the source is still to see.

Simple blur.

Well, with a general impression, take a look at how to achieve the Gaussian blur effect bar!

First you can refer directly to the Yumbo main package's wheels in your project:

Compile ' com.qiushui:blurredview:0.8.1 '

If you do not want to refer to it, you must add the following code to the Build.gradle of the current Module:

defaultconfig {
  Renderscripttargetapi
  renderscriptsupportmodeenabled True
}

Can be used when the construction is good. If the build fails, just set the minsdkversion to 19, for the time being, I don't know why. But it's a bug to learn from the StackOverflow, so don't delve into it.

Now see code implementation, first layout file in a imageview, nothing to say, from the above fuzzy picture tool class can be seen, to get a Gaussian blur effect of the picture, need three things:

Context: Contextual objects
Bitmap: Need to blur the picture
Blurradius: Fuzzy degree

Here you need to note:

At present, this scheme only applies to images in PNG format, and the picture size is best smaller, although the code has scaled the picture, but still may appear cotton situation.

Now just set the picture and the degree of ambiguity is good:

/**
 * Initialize view *
 /
@SuppressWarnings ("deprecation")
private void Initview () {
  basicimage = ( ImageView) Findviewbyid (r.id.iv_basic_pic);
  Get the initial figure
  Bitmap Initbitmap = Bitmaputil.drawabletobitmap (Getresources (). getdrawable (R.raw.pic));
  Deal with the fuzzy effect of the figure
  Bitmap Blurbitmap = Blurbitmaputil.blurbitmap (this, Initbitmap, 20f);
  Basicimage.setimagebitmap (Blurbitmap);
}

Take a look at the run diagram:

As you can see, the picture has achieved a blur effect, and the speed is quite fast, generally through BLURBITMAPUTIL.BLURBITMAP () can get a picture of the blur effect.

customizing fuzzy controls

The original blogger's wheel encapsulates a custom Blurredview, and at first I didn't think it was necessary to customize it. It was later found that the reason for customization was the need to implement dynamic blur effects.

So why not manually set the level of ambiguity? The explanation he gave was:

"If you use the above code to render it in real time, it will cause a severe interface," he said. ”

I tried it myself, and I did have a bit of a card. His solution for dynamic obfuscation is this:

"First, the image to the maximum degree of obfuscation, and then put the original image on the blurred picture above, by constantly changing the original transparency (alpha value) to achieve dynamic blur effect." ”

This is a clever way to implement dynamic effects, but note that if you want to use this method, you must have two identical pictures. If you write directly in your code, you need two controls, which are obviously undesirable if you have more pictures. So there's a custom Blurredview in the wheel.

But this Blurredview package is not too good, I cut a part of the content, the reason later. Let's take a look at the core code.

The first is the custom Blurredview inherited from Relativelayout, which is seen in the layout file, which has two imageview and is stacked together.

<framelayout xmlns:android= "http://schemas.android.com/apk/res/android"
       android:layout_width= "Match_ Parent "
       android:layout_height=" match_parent ">

  <imageview
    android:id=" @+id/blurredview_ Blurred_img "
    .../>

  <imageview
    android:id=" @+id/blurredview_origin_img ".../>"

</FrameLayout>

Some attributes are also defined:

<resources>
  <declare-styleable name= "Blurredview" >
    <attr name= "src" format= "reference"/ >
    <attr name= "disableblurred" format= "boolean"/>
  </declare-styleable>
</resources >

One is to set the picture, one is to set whether the blur is disabled. Finally is the Blurredview class, the code is as follows, has the massive deletion, only pastes the core code:

/** * @author Qiushui * @description custom Blur view class * @revision Xiarui 16.09.05/public class Blurredview extends Relat ivelayout {/*========== Global related ==========*/Private context mcontext;//Contextual object private static final int Alpha_max_valu E = 255;//Transparent maximum private static final float Blur_radius = 25f;//maximum ambiguity (between 0.0 and 25.0)/*========== picture related ==========*/PR Ivate ImageView moriginimg;//The original ImageView private ImageView mblurredimg;//the fuzzy imageview private Bitmap /Fuzzy Bitmap private Bitmap moriginbitmap;//original Bitmap/*========== properties related ==========*/private Boolean isdisableblurred //Whether to disable blur effects .../** * Add a picture to be blurred in code (* * * @param blurredbitmap the picture to be blurred/public void setblurredimg (BITM
      AP Blurredbitmap {if (null!= blurredbitmap) {moriginbitmap = Blurredbitmap;
      Mblurredbitmap = Blurbitmaputil.blurbitmap (Mcontext, Blurredbitmap, Blur_radius);
    Setimageview (); } .../** * fill ImageView/private void SetimagEview () {mblurredimg.setimagebitmap (MBLURREDBITMAP);
  Moriginimg.setimagebitmap (MORIGINBITMAP);
   /** * Sets the blur degree * * @param level blur degree, the value is between 0~100.  * * * @SuppressWarnings ("deprecation") public void Setblurredlevel (int level) {//////////////(+) Direct throw exception if (Levels < 0) ||
    Level >} {throw new IllegalStateException ("No validate level, the value must to be 0~100");
    }//disable Blur direct return if (isdisableblurred) {returns;
  //Set Transparency Moriginimg.setalpha ((int) (Alpha_max_value-level * 2.55));

 }

  ...
}

As you can see from the code, the core is the following three methods:

Setblurredimg (Bitmap blurredbitmap): Set the picture and copy two copies;
Setimageview (): Give two imageview set the corresponding picture, internal call;
Setblurredlevel (int level): Setting the degree of transparency;

The idea is to first select a picture, one as the original image, a picture as a fuzzy processing. The two graphs are then set to the two ImageView in the custom Blurredview, and finally the transparency of the blurred graph is processed.
OK, now to write a custom blur effect diagram, first is the layout, very simple:

 <com.blurdemo.view.blurredview
    android:id= "@+id/bv_custom_blur"
    android:layout_width= "Match_parent"
    android:layout_height= "match_parent"
    app:src= "@raw/pic"
    app:disableblurred= "false"/>

You can see, set the picture, set the open blur, then we can only set the level of transparency in the activity:

private void Initview () {
    Custombview = (blurredview) Findviewbyid (R.id.bv_custom_blur);
    Set the blur degree
    custombview.setblurredlevel (m);
  

The effect picture is the same as the above picture, and there is no repetition here. As you can see, the code is a lot simpler, but simply because it's convenient and simple is not a custom View, it's about the implementation of the dynamic blur effect that follows.

Dynamic Blur

Let's take a look at what's called Dynamic Blur effect:

As you can see from the diagram, the blur of the background changes as we touch the screen. If you want to set its fuzzy degree directly and its cotton, so as the original blogger said, you can use two pictures to achieve.

The general idea is that the image above blurred processing, the image below does not deal with, and then through gestures to change the transparency of the above blurred picture.

So, almost as in the previous code, you just need to rewrite the Ontouchevent method:

/** * Initialize view */private void Initview () {Custombview = (Blurredview) Findviewbyid (R.id.bv_dynamic_blur);
  Set initial ambiguity initlevel = 100;
Custombview.setblurredlevel (Initlevel); /** * Touch Event/@Override public boolean ontouchevent (motionevent ev) {switch (ev.getaction ()) {case Motioneven
      T.action_down:downy = Ev.gety ();

    Break
      Case MotionEvent.ACTION_MOVE:float Movey = Ev.gety ();
      Finger sliding distance float OffsetY = movey-downy;
      The screen height is 10 times times to see the display effect int screenY = Getwindowmanager (). Getdefaultdisplay (). GetHeight () * 10;
      Finger sliding distance to the percentage of the screen movepercent = Offsety/screeny;
      CurrentLevel = initlevel + (int) (movepercent * 100);
      if (CurrentLevel < 0) {currentlevel = 0;
      if (CurrentLevel > MB) {currentlevel = 100;
      //Set the fuzzy degree Custombview.setblurredlevel (currentlevel);
      Change the initial blur level initlevel = CurrentLevel;
    Break
    Case MOTIONEVENT.ACTION_UP:  Break
return super.ontouchevent (EV);

 }

As you can see from the code, it is easy to understand that the code is not difficult to calculate after changing the transparency level by the percentage of the finger sliding distance to the screen. Of course, the original Blogger blog is through the progress bar to change, it is also possible, not to repeat.

Combined with Recylcerview

First look at an effect chart, which is modeled on the original blogger to achieve, but there is a slight difference.

There are several pieces of code in the original custom Blurredview to change the position of the background image, because you want to pull down when the background image can also be moved, but from the experience to see the effect is not too good, pull the process will appear in the white problem.

Although the original blogger gave the solution: Manually add a height to the background image, but this is not the best solution, so I have to delete the function, and so on to find a better way to add to the implementation.

Now let's see how it's implemented? The first layout is the bottom layer of the custom Blurredview, above a recylcerview,recylcerview has two Type, one is the head layout, one is the bottom list, very simple, does not elaborate.

The focus is still on the implementation of the dynamic blur, in the dynamic blur above, we have adopted the rewrite Ontouchevent method, but here is just the recylcerview, we can according to its rolling monitoring, that is, Onscrolllistener to complete the dynamic change of transparency, The core approach is as follows:

 Recyclerview scrolling Monitor
  mainrview.setonscrolllistener (new Recyclerview.onscrolllistener () {
    @Override
    public void onscrollstatechanged (Recyclerview recyclerview, int newstate) {
      super.onscrollstatechanged ( Recyclerview, newstate);

    @Override public
    void onscrolled (recyclerview recyclerview, int dx, int dy) {
      super.onscrolled (recyclerview, DX , DY);
      Rolling distance
      mscrollery + dy;
      According to the rolling distance control the fuzzy degree of the rolling distance is 10 times times the degree of ambiguity
      if (Math.Abs (mscrollery) > 1000) {
        Malpha = =;
      } else {
        Malpha = Mat H.abs (mscrollery)/
      Set transparency level
      recyclerbview.setblurredlevel (Malpha);
    }
  );

The code is very simple, that is, in the Onscrolled method to calculate and dynamically change the transparency, as long as mastered the principle, it is easy to achieve.

Summarize

As you can see from all of the previous dynamic diagrams, it's faster to run, but I see from the Android Monitor that the GPU renders for a long time at the beginning of the blur, so it might be a bit poor in performance.

Of course, it may be related to the simulator, the test on the real machine is very fast. And it seems to be faster than Fastblur, and so on. Test the performance of several Gauss fuzzy implementation methods to compare.

To this end, this method of realizing Gauss ambiguity has been all finished, thanks to the Yumbo Lord so excellent article, again attached links:

Jiu Shui days-teach you a minute to implement dynamic blur effect

Other references

Renderscript–android Developers

Introduction to Android Renderscript (1)

The realization scheme of Gaussian blur effect and its performance comparison –lcyfox

Project Source

Blurdemo–iamxiarui–github

The above is the Android dynamic Gaussian blur effect of the tutorial example, thank you for your support for this site!

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.