├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── 1.png ├── BlurBehindView.gif ├── BlurBehindView1.gif ├── BlurDrawable.gif ├── LICENSE ├── README.md ├── app-debug.apk ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── robinx │ │ └── blur │ │ └── view │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── robinx │ │ └── blur │ │ └── view │ │ ├── BlurActivity.java │ │ ├── BlurBehindViewActivity.java │ │ ├── BlurBehindViewActivity2.java │ │ ├── BlurDrawableActivity.java │ │ ├── BlurUtils.java │ │ ├── MainActivity.java │ │ └── MainApplication.java │ └── res │ ├── layout │ ├── activity_blur.xml │ ├── activity_blur_behind_view.xml │ ├── activity_blur_behind_view2.xml │ ├── activity_blur_drawable.xml │ ├── activity_main.xml │ └── item_spinner.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── bg_1.jpg │ ├── bg_2.jpg │ ├── bg_3.jpg │ ├── bg_4.jpg │ ├── bg_5.jpg │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lib.blurview ├── .gitignore ├── build.gradle ├── libs │ ├── armeabi-v7a │ │ └── libblur.so │ ├── armeabi │ │ └── libblur.so │ ├── mips │ │ └── libblur.so │ └── x86 │ │ └── libblur.so ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── robinx │ │ └── lib │ │ └── blurview │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── robinx │ │ └── lib │ │ └── blurview │ │ ├── BlurBehindView.java │ │ ├── BlurDrawable.java │ │ ├── algorithm │ │ ├── BlurKernels.java │ │ ├── IBlur.java │ │ ├── IgnoreBlur.java │ │ ├── java │ │ │ ├── BoxBlur.java │ │ │ ├── GaussianFastBlur.java │ │ │ ├── StackBlur.java │ │ │ └── SuperFastBlur.java │ │ ├── ndk │ │ │ └── NdkStackBlur.java │ │ └── rs │ │ │ ├── RSBox3x3Blur.java │ │ │ ├── RSBox5x5Blur.java │ │ │ ├── RSGaussian5x5Blur.java │ │ │ ├── RSGaussianBlur.java │ │ │ └── RSStackBlur.java │ │ └── processor │ │ ├── BlurProcessor.java │ │ ├── BlurProcessorProxy.java │ │ ├── IgnoreBlurProcessor.java │ │ ├── JavaBoxBlurProcessor.java │ │ ├── JavaGaussianFastBlurProcessor.java │ │ ├── JavaStackBlurProcessor.java │ │ ├── JavaSuperFastBlurProcessor.java │ │ ├── NdkStackBlurProcessor.java │ │ ├── RSBox3x3BlurProcessor.java │ │ ├── RSBox5x5BlurProcessor.java │ │ ├── RSGaussian5x5BlurProcessor.java │ │ ├── RSGaussianBlurProcessor.java │ │ └── RSStackBlurProcessor.java │ ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── blur.c │ ├── hold.cpp │ └── hold.h │ ├── res │ └── values │ │ └── strings.xml │ └── rs │ ├── contrast.rs │ ├── ip.rsh │ └── stackblur.rs └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | BlurView -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/1.png -------------------------------------------------------------------------------- /BlurBehindView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/BlurBehindView.gif -------------------------------------------------------------------------------- /BlurBehindView1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/BlurBehindView1.gif -------------------------------------------------------------------------------- /BlurDrawable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/BlurDrawable.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "{}" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright 2016 Robin 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## BlurView ## 2 | 3 | ### Support ### 4 | 5 | 1 BlurBehindView 三种更新方式:只模糊一次(Never); 滚动时实时更新(scroll); 无条件实时更新(Continuously); 6 | 2 BlurDrawable 实时模糊Drawable 7 | 3 多种Blur方式,核心算法源自 https://github.com/patrickfav/Dali 8 | 9 | 10 | ### Example ### 11 | 12 | [Download demo.apk](https://github.com/robinxdroid/BlurView/blob/master/app-debug.apk?raw=true) 13 | 14 | ### Screenshot ### 15 | 16 | ![](https://github.com/robinxdroid/BlurView/blob/master/1.png?raw=true) 17 | ![](https://github.com/robinxdroid/BlurView/blob/master/BlurBehindView.gif?raw=true) ![](https://github.com/robinxdroid/BlurView/blob/master/BlurBehindView1.gif?raw=true) 18 | ![](https://github.com/robinxdroid/BlurView/blob/master/BlurDrawable.gif?raw=true) 19 | 20 | ### Usage ### 21 | Gradle: 22 | ```java 23 | compile 'net.robinx:lib.blurview:1.0.2' 24 | ``` 25 | ```java 26 | defaultConfig { 27 | .... 28 | 29 | renderscriptTargetApi 19 30 | renderscriptSupportModeEnabled true 31 | } 32 | ``` 33 | **Blur:** 34 | 35 | ```java 36 | blurBitmap = RSGaussianBlurProcessor.getInstance(context).process(originalBitmap, blurRadius); //RenderScript其中一个方式(此方式在所有方式中速度最快) 37 | 38 | blurBitmap = NdkStackBlurProcessor.INSTANCE.process(originalBitmap, blurRadius); //NDK方式,速度比上面的方式略慢,相对稳定 39 | 40 | blurBitmap = BlurProcessorProxy.INSTANCE //代理 41 | .processor(processor) //传入Processor对象,eg:NdkStackBlurProcessor.INSTANCE 42 | .copy(true) //为true时,将copy一份,不影响原图 43 | .process(originalBitmap, blurRadius); 44 | 45 | ``` 46 | 更多请见[BlurActivity.java](https://github.com/robinxdroid/BlurView/blob/master/app/src/main/java/net/robinx/blur/view/BlurActivity.java) 47 | 48 | **BlurDrawable** 49 | 50 | 扩展Drawable可设置为任何View背景 51 | 52 | ```java 53 | BlurDrawable blurDrawable = new BlurDrawable(bluredview); 54 | blurDrawable.drawableContainerId(R.id.blur_drawable_container) //此方法用于bluredview内部包含了将要设置blurDrawable的View的时候 55 | .cornerRadius(10) //圆角 56 | .blurRadius(10) //Blur程度 <= 25 57 | .overlayColor(Color.parseColor("#64ffffff")) //覆盖颜色 58 | .offset(mBlurDrawableRelativeLayout.getLeft(), mBlurDrawableRelativeLayout.getTop() ); //画布偏移 59 | ``` 60 | 61 | **BlurBehindView**: 62 | 63 | 1.XML: 64 | 65 | ```java 66 | 70 | 71 | ``` 72 | 2.代码中使用: 73 | ```java 74 | BlurBehindView blurBehindView = (BlurBehindView) findViewById(R.id.blur_behind_view); 75 | blurBehindView.updateMode(BlurBehindView.UPDATE_CONTINOUSLY) //更新方式,3种,见demo 76 | .blurRadius(8) //模糊程度,RenderScript方式时,<= 25 77 | .sizeDivider(10) //对原图的缩放程度,此值越大,缩放程度越大,Blur时间越短 78 | .clipPath(path) //裁剪路径,传入不同的path可裁成不同的形状 79 | .clipCircleOutline(true) //是否裁成圆形 80 | .clipCircleRadius(1.0f) //圆形半径系数 <= 1.0 81 | .cornerRadius(10) //圆角 82 | .processor(NdkStackBlurProcessor.INSTANCE); //BlurProcessor,内置了很多不同的Processor,可自己定义,默认RenderScript进行处理 83 | ``` 84 | **自定义Processor**: 85 | 86 | 实现BlurProcessor接口,实现process(Bitmap original, int radius)函数即可 87 | 88 | 89 | **Thanks**: 90 | 91 | [https://github.com/patrickfav/Dali](https://github.com/patrickfav/Dali)
92 | [https://github.com/kikoso/android-stackblur](https://github.com/kikoso/android-stackblur) 93 | 94 | # About me 95 | Email:735506404@robinx.net
96 | Blog:[www.robinx.net](http://www.robinx.net) 97 | 98 | -------------------------------------------------------------------------------- /app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app-debug.apk -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion ANDROID_BUILD_SDK_VERSION as int 5 | buildToolsVersion ANDROID_BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | applicationId "net.robinx.blur.view" 9 | minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION as int 10 | targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION as int 11 | versionCode VERSION_CODE as int 12 | versionName VERSION_NAME 13 | 14 | renderscriptTargetApi 19 15 | renderscriptSupportModeEnabled true 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | compile 'com.android.support:appcompat-v7:23.0.0' 28 | compile 'jp.wasabeef:takt:1.0.2' 29 | 30 | compile project(':lib.blurview') 31 | //compile 'net.robinx:lib.blurview:1.0.0' 32 | } 33 | 34 | //-----------------javadoc编码------------------------ 35 | allprojects { 36 | tasks.withType(Javadoc) { 37 | options{ 38 | encoding "UTF-8" 39 | charSet 'UTF-8' 40 | links "http://docs.oracle.com/javase/7/docs/api" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Administrator\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/net/robinx/blur/view/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/BlurActivity.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.app.Activity; 5 | import android.app.ProgressDialog; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.database.Cursor; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.net.Uri; 12 | import android.os.AsyncTask; 13 | import android.os.Bundle; 14 | import android.provider.MediaStore; 15 | import android.support.v7.app.AppCompatActivity; 16 | import android.util.Log; 17 | import android.view.View; 18 | import android.view.ViewGroup; 19 | import android.widget.AdapterView; 20 | import android.widget.BaseAdapter; 21 | import android.widget.CheckBox; 22 | import android.widget.CompoundButton; 23 | import android.widget.ImageView; 24 | import android.widget.SeekBar; 25 | import android.widget.Spinner; 26 | import android.widget.TextView; 27 | 28 | import net.robinx.lib.blurview.algorithm.rs.RSGaussianBlur; 29 | import net.robinx.lib.blurview.processor.BlurProcessor; 30 | import net.robinx.lib.blurview.processor.BlurProcessorProxy; 31 | import net.robinx.lib.blurview.processor.IgnoreBlurProcessor; 32 | import net.robinx.lib.blurview.processor.JavaBoxBlurProcessor; 33 | import net.robinx.lib.blurview.processor.JavaGaussianFastBlurProcessor; 34 | import net.robinx.lib.blurview.processor.JavaStackBlurProcessor; 35 | import net.robinx.lib.blurview.processor.JavaSuperFastBlurProcessor; 36 | import net.robinx.lib.blurview.processor.NdkStackBlurProcessor; 37 | import net.robinx.lib.blurview.processor.RSBox3x3BlurProcessor; 38 | import net.robinx.lib.blurview.processor.RSBox5x5BlurProcessor; 39 | import net.robinx.lib.blurview.processor.RSGaussian5x5BlurProcessor; 40 | import net.robinx.lib.blurview.processor.RSGaussianBlurProcessor; 41 | import net.robinx.lib.blurview.processor.RSStackBlurProcessor; 42 | 43 | import java.util.ArrayList; 44 | import java.util.List; 45 | 46 | public class BlurActivity extends AppCompatActivity { 47 | 48 | private static final int REQUEST_CODE_CHOOSE_GALLERY_IMAGE = 0x01; 49 | private ImageView mRootImageView; 50 | private ImageView mOriginalImageView; 51 | private ImageView mBlurImageView; 52 | private CheckBox mCompressCheckBox; 53 | private TextView mBlurTimeTextView; 54 | 55 | private Bitmap mOriginalBitmap; 56 | private Bitmap mCompressedBitmap; 57 | 58 | private int blurRadius = 5; 59 | 60 | private static final int RS_GAUSS = 0, 61 | RS_BOX_3x3 = 1, 62 | RS_BOX_5x5 = 2, 63 | RS_GAUSS_5x5 = 3, 64 | RS_STACK = 4, 65 | NDK_STACK = 5, 66 | JAVA_GAUSS_FAST = 6, 67 | JAVA_BOX = 7, 68 | JAVA_SUPER_FAST = 8, 69 | JAVA_STACK = 9, 70 | NONE = 10; 71 | 72 | private int BlurMode = RS_GAUSS; 73 | 74 | @Override 75 | protected void onCreate(Bundle savedInstanceState) { 76 | super.onCreate(savedInstanceState); 77 | setContentView(R.layout.activity_blur); 78 | 79 | init(); 80 | } 81 | 82 | private void init() { 83 | mRootImageView = (ImageView) this.findViewById(R.id.img_root_bg); 84 | mBlurTimeTextView = (TextView) this.findViewById(R.id.tv_blur_time); 85 | mOriginalImageView = (ImageView) this.findViewById(R.id.img_origin); 86 | mBlurImageView = (ImageView) this.findViewById(R.id.img_blur); 87 | this.findViewById(R.id.tv_choose).setOnClickListener(getOnClickListener()); 88 | this.findViewById(R.id.tv_blur).setOnClickListener(getOnClickListener()); 89 | Spinner spinner = (Spinner) this.findViewById(R.id.sp); 90 | mCompressCheckBox = (CheckBox) this.findViewById(R.id.cb_compress); 91 | final TextView radiusTextView = (TextView) this.findViewById(R.id.tv_radius); 92 | SeekBar radiusSeekBar = (SeekBar) this.findViewById(R.id.sb_radius); 93 | 94 | //background 95 | Bitmap bgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.bg_2); 96 | Bitmap compressedBgBitmap = BlurUtils.compressBitmap(bgBitmap, 8); 97 | Bitmap blurBgBitmap = NdkStackBlurProcessor.INSTANCE.process(compressedBgBitmap, 25); 98 | mRootImageView.setImageBitmap(blurBgBitmap); 99 | ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(mRootImageView, View.ALPHA, 0, 1f); 100 | alphaAnimator.setDuration(2000); 101 | alphaAnimator.start(); 102 | 103 | List strings = new ArrayList<>(); 104 | strings.add("RSGaussianBlurProcessor"); 105 | strings.add("RSBox3x3BlurProcessor"); 106 | strings.add("RSBox5x5BlurProcessor"); 107 | strings.add("RSGaussian5x5BlurProcessor"); 108 | strings.add("RSStackBlurProcessor"); 109 | strings.add("NdkStackBlurProcessor"); 110 | strings.add("JavaGaussianFastBlurProcessor"); 111 | strings.add("JavaBoxBlurProcessor"); 112 | strings.add("JavaSuperFastBlurProcessor"); 113 | strings.add("JavaStackBlurProcessor"); 114 | strings.add("IgnoreBlurProcessor"); 115 | 116 | 117 | spinner.setAdapter(new SpinnerAdapter(strings)); 118 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 119 | @Override 120 | public void onItemSelected(AdapterView adapterView, View view, int i, long l) { 121 | BlurMode = i; 122 | blur(); 123 | } 124 | 125 | @Override 126 | public void onNothingSelected(AdapterView adapterView) { 127 | 128 | } 129 | }); 130 | 131 | mCompressCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 132 | @Override 133 | public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 134 | blur(); 135 | } 136 | }); 137 | 138 | radiusSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 139 | @Override 140 | public void onProgressChanged(SeekBar seekBar, int i, boolean b) { 141 | blurRadius = i; 142 | radiusTextView.setText("blur radius:" + i); 143 | } 144 | 145 | @Override 146 | public void onStartTrackingTouch(SeekBar seekBar) { 147 | 148 | } 149 | 150 | @Override 151 | public void onStopTrackingTouch(SeekBar seekBar) { 152 | blur(); 153 | } 154 | }); 155 | } 156 | 157 | private View.OnClickListener mOnClickListener; 158 | 159 | private View.OnClickListener getOnClickListener() { 160 | if (mOnClickListener == null) { 161 | mOnClickListener = new View.OnClickListener() { 162 | @Override 163 | public void onClick(View view) { 164 | switch (view.getId()) { 165 | case R.id.tv_choose: 166 | chooseGalleryImage(BlurActivity.this, REQUEST_CODE_CHOOSE_GALLERY_IMAGE); 167 | break; 168 | case R.id.tv_blur: 169 | 170 | blur(); 171 | break; 172 | } 173 | } 174 | }; 175 | } 176 | return mOnClickListener; 177 | } 178 | 179 | private void blur() { 180 | 181 | if (mOriginalBitmap == null) { 182 | return; 183 | } 184 | 185 | final Bitmap willBlurBitmap; 186 | if (mCompressCheckBox.isChecked()) { 187 | willBlurBitmap = mCompressedBitmap; 188 | } else { 189 | willBlurBitmap = mOriginalBitmap; 190 | } 191 | 192 | final ProgressDialog progressDialog = new ProgressDialog(this); 193 | progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 194 | progressDialog.setCanceledOnTouchOutside(false); 195 | progressDialog.setCancelable(true); 196 | 197 | new AsyncTask() { 198 | 199 | @Override 200 | protected void onPreExecute() { 201 | progressDialog.show(); 202 | } 203 | 204 | @Override 205 | protected Bitmap doInBackground(Void... voids) { 206 | long blurStartTime = System.currentTimeMillis(); 207 | Bitmap blurBitmap = null; 208 | BlurProcessor processor = null; 209 | switch (BlurMode) { 210 | case RS_GAUSS: 211 | Log.i("robin", "BlurMode:RS_GAUSS"); 212 | //blurBitmap = RSGaussianBlurProcessor.getInstance(BlurActivity.this).process(willBlurBitmap, blurRadius); 213 | processor = RSGaussianBlurProcessor.getInstance(BlurActivity.this); 214 | break; 215 | case RS_BOX_3x3: 216 | Log.i("robin", "BlurMode:RS_BOX_3x3"); 217 | //blurBitmap = RSBox3x3BlurProcessor.getInstance(BlurActivity.this).process(willBlurBitmap, blurRadius); 218 | processor = RSBox3x3BlurProcessor.getInstance(BlurActivity.this); 219 | break; 220 | case RS_BOX_5x5: 221 | Log.i("robin", "BlurMode:RS_BOX_5x5"); 222 | //blurBitmap = RSBox5x5BlurProcessor.getInstance(BlurActivity.this).process(willBlurBitmap, blurRadius); 223 | processor = RSBox5x5BlurProcessor.getInstance(BlurActivity.this); 224 | break; 225 | case RS_GAUSS_5x5: 226 | Log.i("robin", "BlurMode:RS_GAUSS_5x5"); 227 | //blurBitmap = RSGaussian5x5BlurProcessor.getInstance(BlurActivity.this).process(willBlurBitmap, blurRadius); 228 | processor = RSGaussian5x5BlurProcessor.getInstance(BlurActivity.this); 229 | break; 230 | case RS_STACK: 231 | Log.i("robin", "BlurMode:RS_STACK"); 232 | //blurBitmap = RSStackBlurProcessor.getInstance(BlurActivity.this).process(willBlurBitmap, blurRadius); 233 | processor = RSStackBlurProcessor.getInstance(BlurActivity.this); 234 | break; 235 | case NDK_STACK: 236 | Log.i("robin", "BlurMode:NDK_STACK"); 237 | //blurBitmap = NdkStackBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 238 | processor = NdkStackBlurProcessor.INSTANCE; 239 | break; 240 | case JAVA_GAUSS_FAST: 241 | Log.i("robin", "BlurMode:JAVA_GAUSS_FAST"); 242 | //blurBitmap = JavaGaussianFastBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 243 | processor = JavaGaussianFastBlurProcessor.INSTANCE; 244 | break; 245 | case JAVA_BOX: 246 | Log.i("robin", "BlurMode:JAVA_BOX"); 247 | //blurBitmap = JavaBoxBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 248 | processor = JavaBoxBlurProcessor.INSTANCE; 249 | break; 250 | case JAVA_SUPER_FAST: 251 | Log.i("robin", "BlurMode:JAVA_SUPER_FAST"); 252 | //blurBitmap = JavaSuperFastBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 253 | processor = JavaSuperFastBlurProcessor.INSTANCE; 254 | break; 255 | case JAVA_STACK: 256 | Log.i("robin", "BlurMode:JAVA_STACK"); 257 | //blurBitmap = JavaStackBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 258 | processor = JavaStackBlurProcessor.INSTANCE; 259 | break; 260 | case NONE: 261 | Log.i("robin", "BlurMode:NONE"); 262 | //blurBitmap = IgnoreBlurProcessor.INSTANCE.process(willBlurBitmap, blurRadius); 263 | processor = IgnoreBlurProcessor.INSTANCE; 264 | break; 265 | } 266 | 267 | blurBitmap = BlurProcessorProxy.INSTANCE 268 | .processor(processor) 269 | .copy(true) 270 | .process(willBlurBitmap, blurRadius); 271 | 272 | final long blurTime = System.currentTimeMillis() - blurStartTime; 273 | runOnUiThread(new Runnable() { 274 | @Override 275 | public void run() { 276 | mBlurTimeTextView.setText("blur time: " + blurTime + " ms"); 277 | } 278 | }); 279 | return blurBitmap; 280 | } 281 | 282 | @Override 283 | protected void onPostExecute(Bitmap bitmap) { 284 | progressDialog.dismiss(); 285 | mBlurImageView.setImageBitmap(bitmap); 286 | } 287 | }.execute(); 288 | 289 | 290 | } 291 | 292 | @Override 293 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 294 | super.onActivityResult(requestCode, resultCode, data); 295 | switch (requestCode) { 296 | case REQUEST_CODE_CHOOSE_GALLERY_IMAGE: 297 | if (data == null) { 298 | return; 299 | } 300 | clearImageView(); 301 | 302 | String picPath = chooseGalleryImageHandler(BlurActivity.this, data); 303 | Log.i("robin", "PicPath:" + picPath); 304 | 305 | // Original 306 | mOriginalBitmap = BitmapFactory.decodeFile(picPath); 307 | // Compress 308 | /*Matrix matrix = new Matrix(); 309 | matrix.postScale(1.0f / 6, 1.0f / 6); 310 | mCompressedBitmap = Bitmap.createBitmap(mOriginalBitmap, 0, 0, 311 | mOriginalBitmap.getWidth(), mOriginalBitmap.getHeight(), matrix, true);*/ 312 | mCompressedBitmap = BlurUtils.compressBitmap(mOriginalBitmap, 6); 313 | 314 | mOriginalImageView.setImageBitmap(mOriginalBitmap); 315 | break; 316 | } 317 | } 318 | 319 | public void clearImageView() { 320 | mOriginalImageView.setImageBitmap(null); 321 | mBlurImageView.setImageBitmap(null); 322 | } 323 | 324 | public static void chooseGalleryImage(Activity activity, int requestCode) { 325 | Intent intent = new Intent(Intent.ACTION_PICK, null); 326 | intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 327 | "image/*"); 328 | activity.startActivityForResult(intent, requestCode); 329 | } 330 | 331 | public static String chooseGalleryImageHandler( 332 | Context context, Intent data) { 333 | if (data == null) { 334 | return null; 335 | } 336 | Uri uri = data.getData(); 337 | String filePath; 338 | if (uri.toString().substring(0, 4).equals("file")) { 339 | filePath = uri.getPath(); 340 | } else { 341 | String[] proj = {MediaStore.Images.Media.DATA}; 342 | Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); 343 | int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 344 | cursor.moveToFirst(); 345 | filePath = cursor.getString(columnIndex); 346 | } 347 | return filePath; 348 | } 349 | 350 | public static class SpinnerAdapter extends BaseAdapter { 351 | 352 | private List mStrings; 353 | 354 | public SpinnerAdapter(List strings) { 355 | mStrings = strings; 356 | } 357 | 358 | @Override 359 | public int getCount() { 360 | return mStrings.size(); 361 | } 362 | 363 | @Override 364 | public Object getItem(int i) { 365 | return mStrings.get(i); 366 | } 367 | 368 | @Override 369 | public long getItemId(int i) { 370 | return i; 371 | } 372 | 373 | @Override 374 | public View getView(int i, View view, ViewGroup viewGroup) { 375 | ViewHolder viewHolder; 376 | if (view == null) { 377 | viewHolder = new ViewHolder(); 378 | view = View.inflate(viewGroup.getContext(), R.layout.item_spinner, null); 379 | viewHolder.mTextView = (TextView) view.findViewById(R.id.tv); 380 | view.setTag(viewHolder); 381 | } else { 382 | viewHolder = (ViewHolder) view.getTag(); 383 | } 384 | 385 | viewHolder.mTextView.setText(mStrings.get(i)); 386 | 387 | return view; 388 | } 389 | 390 | class ViewHolder { 391 | TextView mTextView; 392 | } 393 | } 394 | 395 | 396 | } 397 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/BlurBehindViewActivity.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.graphics.Path; 4 | import android.graphics.RectF; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.view.ViewTreeObserver; 10 | import android.widget.AdapterView; 11 | import android.widget.BaseAdapter; 12 | import android.widget.ScrollView; 13 | import android.widget.Spinner; 14 | import android.widget.TextView; 15 | 16 | import net.robinx.lib.blurview.BlurBehindView; 17 | import net.robinx.lib.blurview.processor.NdkStackBlurProcessor; 18 | import net.robinx.lib.blurview.processor.RSGaussianBlurProcessor; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | 24 | public class BlurBehindViewActivity extends AppCompatActivity { 25 | 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_blur_behind_view); 31 | 32 | init(); 33 | } 34 | 35 | private void init() { 36 | 37 | int diameter = 400; 38 | Path path = new Path(); 39 | path.moveTo(0, 0); 40 | path.lineTo(diameter / 2, diameter); 41 | path.lineTo(diameter, 0); 42 | path.close(); 43 | 44 | //Blur view 45 | final BlurBehindView blurBehindView = (BlurBehindView) findViewById(R.id.blur_behind_view); 46 | blurBehindView.updateMode(BlurBehindView.UPDATE_CONTINOUSLY) 47 | .blurRadius(8) 48 | .sizeDivider(10) 49 | .clipPath(path); 50 | 51 | final BlurBehindView blurBehindView2 = (BlurBehindView) findViewById(R.id.blur_behind_view2); 52 | blurBehindView2.updateMode(BlurBehindView.UPDATE_CONTINOUSLY) 53 | .blurRadius(8) 54 | .sizeDivider(10) 55 | .clipCircleOutline(true) 56 | .clipCircleRadius(1.0f); 57 | 58 | //Spinner 59 | Spinner spinner = (Spinner) this.findViewById(R.id.sp); 60 | List strings = new ArrayList<>(); 61 | strings.add("Scroll"); 62 | strings.add("Continuously"); 63 | strings.add("Never"); 64 | spinner.setAdapter(new SpinnerAdapter(strings)); 65 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 66 | @Override 67 | public void onItemSelected(AdapterView adapterView, View view, int i, long l) { 68 | switch (i) { 69 | case 0: 70 | blurBehindView.updateMode(BlurBehindView.UPDATE_SCROLL_CHANGED); 71 | blurBehindView2.updateMode(BlurBehindView.UPDATE_SCROLL_CHANGED); 72 | break; 73 | case 1: 74 | blurBehindView.updateMode(BlurBehindView.UPDATE_CONTINOUSLY); 75 | blurBehindView2.updateMode(BlurBehindView.UPDATE_CONTINOUSLY); 76 | break; 77 | case 2: 78 | blurBehindView.updateMode(BlurBehindView.UPDATE_NEVER); 79 | blurBehindView2.updateMode(BlurBehindView.UPDATE_NEVER); 80 | break; 81 | } 82 | } 83 | 84 | @Override 85 | public void onNothingSelected(AdapterView adapterView) { 86 | 87 | } 88 | }); 89 | } 90 | 91 | 92 | public static class SpinnerAdapter extends BaseAdapter { 93 | 94 | private List mStrings; 95 | 96 | public SpinnerAdapter(List strings) { 97 | mStrings = strings; 98 | } 99 | 100 | @Override 101 | public int getCount() { 102 | return mStrings.size(); 103 | } 104 | 105 | @Override 106 | public Object getItem(int i) { 107 | return mStrings.get(i); 108 | } 109 | 110 | @Override 111 | public long getItemId(int i) { 112 | return i; 113 | } 114 | 115 | @Override 116 | public View getView(int i, View view, ViewGroup viewGroup) { 117 | ViewHolder viewHolder; 118 | if (view == null) { 119 | viewHolder = new ViewHolder(); 120 | view = View.inflate(viewGroup.getContext(), R.layout.item_spinner, null); 121 | viewHolder.mTextView = (TextView) view.findViewById(R.id.tv); 122 | view.setTag(viewHolder); 123 | } else { 124 | viewHolder = (ViewHolder) view.getTag(); 125 | } 126 | 127 | viewHolder.mTextView.setText(mStrings.get(i)); 128 | 129 | return view; 130 | } 131 | 132 | class ViewHolder { 133 | TextView mTextView; 134 | } 135 | } 136 | 137 | 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/BlurBehindViewActivity2.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.ViewTreeObserver; 6 | import android.widget.ScrollView; 7 | 8 | import net.robinx.lib.blurview.BlurBehindView; 9 | import net.robinx.lib.blurview.processor.NdkStackBlurProcessor; 10 | 11 | 12 | public class BlurBehindViewActivity2 extends AppCompatActivity { 13 | 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_blur_behind_view2); 19 | 20 | init(); 21 | } 22 | 23 | private void init() { 24 | 25 | BlurBehindView blurBehindView2 = (BlurBehindView) findViewById(R.id.blur_behind_view); 26 | blurBehindView2.updateMode(BlurBehindView.UPDATE_SCROLL_CHANGED) 27 | .cornerRadius(10) 28 | .processor(NdkStackBlurProcessor.INSTANCE); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/BlurDrawableActivity.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v4.view.ViewCompat; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.ViewTreeObserver; 8 | import android.widget.RelativeLayout; 9 | import android.widget.ScrollView; 10 | 11 | import net.robinx.lib.blurview.BlurDrawable; 12 | 13 | 14 | public class BlurDrawableActivity extends AppCompatActivity { 15 | 16 | private ScrollView mScrollView; 17 | private RelativeLayout mBlurDrawableRelativeLayout; 18 | 19 | private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener; 20 | 21 | private BlurDrawable mBlurDrawable; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_blur_drawable); 27 | 28 | init(); 29 | } 30 | 31 | private void init() { 32 | mBlurDrawableRelativeLayout = (RelativeLayout) this.findViewById(R.id.blur_drawable_container); 33 | mBlurDrawableRelativeLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 34 | @Override 35 | public void onGlobalLayout() { 36 | mBlurDrawableRelativeLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); 37 | mBlurDrawable = new BlurDrawable(BlurDrawableActivity.this); 38 | mBlurDrawable.drawableContainerId(R.id.blur_drawable_container) 39 | .cornerRadius(10) 40 | .blurRadius(10) 41 | .overlayColor(Color.parseColor("#64ffffff")) 42 | .offset(mBlurDrawableRelativeLayout.getLeft(), mBlurDrawableRelativeLayout.getTop() ); 43 | mBlurDrawableRelativeLayout.setBackgroundDrawable(mBlurDrawable); 44 | } 45 | }); 46 | 47 | mScrollView = (ScrollView) this.findViewById(R.id.sv); 48 | mScrollView.getViewTreeObserver().addOnScrollChangedListener(getOnScrollChangedListener()); 49 | } 50 | 51 | public ViewTreeObserver.OnScrollChangedListener getOnScrollChangedListener() { 52 | if (mOnScrollChangedListener == null) { 53 | mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { 54 | @Override 55 | public void onScrollChanged() { 56 | //BlurDrawable 57 | ViewCompat.postInvalidateOnAnimation(mBlurDrawableRelativeLayout); 58 | 59 | } 60 | }; 61 | } 62 | return mOnScrollChangedListener; 63 | } 64 | 65 | @Override 66 | protected void onDestroy() { 67 | super.onDestroy(); 68 | if (mOnScrollChangedListener != null) { 69 | mScrollView.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener); 70 | mOnScrollChangedListener = null; 71 | } 72 | 73 | mBlurDrawable.onDestroy(); 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/BlurUtils.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Matrix; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | /** 10 | * Created by Robin on 2016/7/25 12:12. 11 | */ 12 | public class BlurUtils { 13 | 14 | public static Bitmap compressBitmap(Bitmap bitmap,int compressFactor){ 15 | Matrix matrix = new Matrix(); 16 | matrix.postScale(1.0f / compressFactor, 1.0f / compressFactor); 17 | bitmap = Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true); 18 | return bitmap; 19 | } 20 | 21 | public static int getStatusBarHeight(Context context) { 22 | Class c = null; 23 | Object obj = null; 24 | Field field = null; 25 | int x = 0; 26 | try { 27 | c = Class.forName("com.android.internal.R$dimen"); 28 | obj = c.newInstance(); 29 | field = c.getField("status_bar_height"); 30 | x = Integer.parseInt(field.get(obj).toString()); 31 | return context.getResources().getDimensionPixelSize(x); 32 | } catch (Exception e1) { 33 | e1.printStackTrace(); 34 | return 75; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/MainActivity.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | init(); 16 | } 17 | 18 | private void init() { 19 | this.findViewById(R.id.tv_blur).setOnClickListener(getOnClickListener()); 20 | this.findViewById(R.id.tv_blur_drawable).setOnClickListener(getOnClickListener()); 21 | this.findViewById(R.id.tv_blur_behind_view).setOnClickListener(getOnClickListener()); 22 | this.findViewById(R.id.tv_blur_behind_view2).setOnClickListener(getOnClickListener()); 23 | } 24 | 25 | private View.OnClickListener mOnClickListener; 26 | private View.OnClickListener getOnClickListener() { 27 | if (mOnClickListener == null) { 28 | mOnClickListener = new View.OnClickListener() { 29 | @Override 30 | public void onClick(View view) { 31 | switch (view.getId()) { 32 | case R.id.tv_blur: 33 | startActivity(new Intent(MainActivity.this,BlurActivity.class)); 34 | break; 35 | case R.id.tv_blur_drawable: 36 | startActivity(new Intent(MainActivity.this,BlurDrawableActivity.class)); 37 | break; 38 | case R.id.tv_blur_behind_view: 39 | startActivity(new Intent(MainActivity.this,BlurBehindViewActivity.class)); 40 | break; 41 | case R.id.tv_blur_behind_view2: 42 | startActivity(new Intent(MainActivity.this,BlurBehindViewActivity2.class)); 43 | break; 44 | } 45 | } 46 | }; 47 | } 48 | return mOnClickListener; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/net/robinx/blur/view/MainApplication.java: -------------------------------------------------------------------------------- 1 | package net.robinx.blur.view; 2 | 3 | import android.app.Application; 4 | 5 | import jp.wasabeef.takt.Takt; 6 | 7 | /** 8 | * Created by Robin on 2016/8/23 12:02. 9 | */ 10 | public class MainApplication extends Application { 11 | 12 | public void onCreate() { 13 | super.onCreate(); 14 | Takt.stock(this).size(20f).play(); 15 | } 16 | 17 | @Override public void onTerminate() { 18 | Takt.finish(); 19 | super.onTerminate(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_blur.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 20 | 26 | 27 | 33 | 34 | 38 | 39 | 45 | 46 | 53 | 54 | 55 | 59 | 60 | 76 | 77 | 94 | 95 | 96 | 101 | 102 | 107 | 108 | 115 | 116 | 123 | 124 | 125 | 130 | 131 | 137 | 138 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_blur_behind_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 24 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 48 | 49 | 53 | 54 | 58 | 59 | 65 | 72 | 80 | 81 | 82 | 89 | 97 | 98 | 99 | 100 | 104 | 105 | 109 | 110 | 111 | 118 | 119 | 126 | 127 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_blur_behind_view2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 12 | 13 | 17 | 18 | 22 | 23 | 28 | 29 | 34 | 39 | 44 | 45 | 50 | 51 | 52 | 53 | 54 | 55 | 60 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_blur_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 22 | 23 | 28 | 29 | 34 | 35 | 40 | 41 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 12 | 18 | 19 | 33 | 34 | 49 | 64 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_spinner.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/bg_1.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/bg_2.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/bg_3.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/bg_4.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/bg_5.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | BlurView 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.1.0' 9 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' 10 | classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0" 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | jcenter() 21 | } 22 | } 23 | 24 | task clean(type: Delete) { 25 | delete rootProject.buildDir 26 | } 27 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | ANDROID_BUILD_SDK_VERSION=23 20 | ANDROID_BUILD_TARGET_SDK_VERSION=23 21 | VERSION_NAME=1.0 22 | VERSION_CODE=1 23 | ANDROID_BUILD_TOOLS_VERSION=23.0.3 24 | ANDROID_BUILD_MIN_SDK_VERSION=16 25 | android.useDeprecatedNdk=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /lib.blurview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /lib.blurview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion ANDROID_BUILD_SDK_VERSION as int 5 | buildToolsVersion ANDROID_BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION as int 9 | targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION as int 10 | versionCode VERSION_CODE as int 11 | versionName VERSION_NAME 12 | 13 | ndk { 14 | moduleName "blur" 15 | cFlags "-DANDROID_NDK -D_RELEASE" 16 | ldLibs "m", "log", "jnigraphics" 17 | abiFilters "all" 18 | } 19 | 20 | renderscriptTargetApi 19 21 | renderscriptSupportModeEnabled true 22 | } 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | sourceSets { 30 | main { 31 | jniLibs.srcDirs = ['libs'] 32 | } 33 | } 34 | 35 | } 36 | 37 | dependencies { 38 | compile fileTree(dir: 'libs', include: ['*.jar']) 39 | } 40 | 41 | //-----------------javadoc编码------------------------ 42 | allprojects { 43 | tasks.withType(Javadoc) { 44 | options{ 45 | encoding "UTF-8" 46 | charSet 'UTF-8' 47 | links "http://docs.oracle.com/javase/7/docs/api" 48 | } 49 | } 50 | } 51 | 52 | //-----------------jCenter 配置 begin------------------------ 53 | ext { 54 | bintrayRepo = 'RobinMaven' 55 | bintrayName = 'BlurViewLibrary' 56 | 57 | publishedGroupId = 'net.robinx' 58 | libraryName = 'lib.blurview' 59 | artifact = 'lib.blurview' 60 | 61 | libraryDescription = 'Android blur view library' 62 | 63 | siteUrl = 'http://git.oschina.net/robinxdroid/BlurView' 64 | gitUrl = 'https://git.oschina.net/robinxdroid/BlurView.git' 65 | 66 | libraryVersion = '1.0.0' 67 | 68 | developerId = 'robinx' 69 | developerName = 'robin' 70 | developerEmail = 'robinxdroid@gmail.com' 71 | 72 | licenseName = 'The Apache Software License, Version 2.0' 73 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 74 | allLicenses = ["Apache-2.0"] 75 | 76 | } 77 | 78 | apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle' 79 | apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle' 80 | -------------------------------------------------------------------------------- /lib.blurview/libs/armeabi-v7a/libblur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/lib.blurview/libs/armeabi-v7a/libblur.so -------------------------------------------------------------------------------- /lib.blurview/libs/armeabi/libblur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/lib.blurview/libs/armeabi/libblur.so -------------------------------------------------------------------------------- /lib.blurview/libs/mips/libblur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/lib.blurview/libs/mips/libblur.so -------------------------------------------------------------------------------- /lib.blurview/libs/x86/libblur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robinxdroid/BlurView/0ccce8d197c8ff6ac7848d1ef44d57a9371b2908/lib.blurview/libs/x86/libblur.so -------------------------------------------------------------------------------- /lib.blurview/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Administrator\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /lib.blurview/src/androidTest/java/net/robinx/lib/blurview/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /lib.blurview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/BlurBehindView.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Bitmap; 6 | import android.graphics.Bitmap.Config; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.Paint; 10 | import android.graphics.Path; 11 | import android.graphics.Path.Direction; 12 | import android.graphics.PorterDuff.Mode; 13 | import android.graphics.Rect; 14 | import android.graphics.RectF; 15 | import android.support.v8.renderscript.Allocation; 16 | import android.support.v8.renderscript.Element; 17 | import android.support.v8.renderscript.RenderScript; 18 | import android.support.v8.renderscript.ScriptIntrinsicBlur; 19 | import android.util.AttributeSet; 20 | import android.util.Log; 21 | import android.view.View; 22 | import android.view.ViewGroup; 23 | import android.view.ViewTreeObserver.OnScrollChangedListener; 24 | import android.widget.RelativeLayout; 25 | 26 | import net.robinx.lib.blurview.processor.BlurProcessor; 27 | 28 | import java.io.FileOutputStream; 29 | 30 | public class BlurBehindView extends RelativeLayout { 31 | public static final int UPDATE_CONTINOUSLY = 2; 32 | public static final int UPDATE_NEVER = 0; 33 | public static final int UPDATE_SCROLL_CHANGED = 1; 34 | private int blurRadius = 8; 35 | private BlurRender mBlurRender; 36 | private boolean clipCircleOutline = false; 37 | private float clipCircleRadius = 1.0F; 38 | private float cornerRadius = 0; 39 | private float sizeDivider = 12.0F; 40 | //private int overlayColor = Color.TRANSPARENT; 41 | private int updateMode = UPDATE_NEVER; 42 | private BlurProcessor mProcessor; 43 | 44 | private static final int TAG_VIEW = 10000; 45 | 46 | public BlurBehindView(Context context) { 47 | super(context); 48 | this.init(); 49 | } 50 | 51 | public BlurBehindView(Context context, AttributeSet attrs) { 52 | super(context, attrs); 53 | this.init(); 54 | } 55 | 56 | public BlurBehindView(Context context, AttributeSet attrs, int defStyleAttr) { 57 | super(context, attrs, defStyleAttr); 58 | this.init(); 59 | } 60 | 61 | private void init() { 62 | this.mBlurRender = new BlurRender(this.getContext()); 63 | this.addView(this.mBlurRender, 0, new LayoutParams(-1, -1)); 64 | this.setTag(TAG_VIEW); 65 | } 66 | 67 | private boolean isSizeKnown() { 68 | if (this.mBlurRender.getWidth() != 0) { 69 | return true; 70 | } 71 | return false; 72 | } 73 | 74 | public float getSizeDivider() { 75 | return this.sizeDivider; 76 | } 77 | 78 | public BlurBehindView sizeDivider(float sizeDivider) { 79 | this.sizeDivider = sizeDivider; 80 | if (this.isSizeKnown()) { 81 | this.mBlurRender.initDrawingBitmap(); 82 | } 83 | return this; 84 | } 85 | 86 | public float getBlurRadius() { 87 | return this.blurRadius; 88 | } 89 | 90 | public BlurBehindView blurRadius(int blurRadius) { 91 | if (this.blurRadius != blurRadius) { 92 | this.blurRadius = blurRadius; 93 | this.mBlurRender.setRenderScriptBlurRadius(blurRadius); 94 | this.mBlurRender.drawToBitmap(); 95 | } 96 | return this; 97 | } 98 | 99 | /*public BlurBehindView overlayColor(int overlayColor) { 100 | this.overlayColor = overlayColor; 101 | this.mBlurRender.drawToBitmap(); 102 | return this; 103 | }*/ 104 | 105 | public boolean isClipCircleOutline() { 106 | return this.clipCircleOutline; 107 | } 108 | 109 | public BlurBehindView clipCircleOutline(boolean clipCircleOutline) { 110 | this.clipCircleOutline = clipCircleOutline; 111 | return this; 112 | } 113 | 114 | public BlurBehindView clipPath(Path clipPath) { 115 | this.mBlurRender.setClipPath(clipPath); 116 | this.mBlurRender.invalidate(); 117 | return this; 118 | } 119 | 120 | public float getClipCircleRadius() { 121 | return this.clipCircleRadius; 122 | } 123 | 124 | public BlurBehindView clipCircleRadius(float radius) { 125 | this.clipCircleRadius = Math.max(0.0F, Math.min(1.0F, radius)); 126 | this.mBlurRender.initCirclePath(); 127 | return this; 128 | } 129 | 130 | public float getCornerRadius() { 131 | return cornerRadius; 132 | } 133 | 134 | public BlurBehindView cornerRadius(float cornerRadius) { 135 | this.cornerRadius = Math.max(0.0F, cornerRadius); 136 | this.mBlurRender.initRoundRectPath(); 137 | return this; 138 | } 139 | 140 | public BlurBehindView updateMode(int updateMode) { 141 | this.updateMode = updateMode; 142 | this.mBlurRender.drawToBitmap(); 143 | return this; 144 | } 145 | 146 | public BlurRender getBlurRender() { 147 | return mBlurRender; 148 | } 149 | 150 | public BlurBehindView processor(BlurProcessor processor) { 151 | mProcessor = processor; 152 | mBlurRender.setProcessor(processor); 153 | this.mBlurRender.drawToBitmap(); 154 | return this; 155 | } 156 | 157 | public class BlurRender extends View { 158 | public static final int PADDING_SIDE_TO_AVOID_FLICKER = 15; 159 | private Bitmap blurBitmap; 160 | private Canvas blurCanvas; 161 | int[] childPositionInWindow = new int[2]; 162 | final Path circlePath = new Path(); 163 | private Path roundPath = new Path(); 164 | private Path clipPath; 165 | float extraPaddingOnSides; 166 | int halfPaddingOnSides; 167 | boolean isInDrawPassFromThisView = false; 168 | private Bitmap snapShotBitmap; 169 | int[] thisPositionInWindow = new int[2]; 170 | private BlurProcessor mProcessor; 171 | 172 | //RenderScript 173 | private RenderScript mRenderScript; 174 | private ScriptIntrinsicBlur mBlurScript; 175 | private Allocation mBlurInput, mBlurOutput; 176 | 177 | public OnScrollChangedListener onscrollChangedListener = new OnScrollChangedListener() { 178 | public void onScrollChanged() { 179 | if (BlurBehindView.this.updateMode == UPDATE_SCROLL_CHANGED && !BlurRender.this.isInDrawPassFromThisView) { 180 | BlurRender.this.isInDrawPassFromThisView = true; 181 | BlurRender.this.drawToBitmap(); 182 | } 183 | } 184 | }; 185 | 186 | public BlurRender(Context context) { 187 | super(context); 188 | this.setLayerType(LAYER_TYPE_HARDWARE, null); 189 | 190 | //RenderScript 191 | this.initRenderScript(getContext()); 192 | } 193 | 194 | private void printViewsBehind(ViewGroup rootView) { 195 | if (!this.isInEditMode() && !(rootView instanceof BlurBehindView) && rootView.getVisibility() == View.VISIBLE && rootView.getAlpha() != 0.0F) { 196 | if (rootView.getBackground() != null) { 197 | this.blurCanvas.save(); 198 | this.blurCanvas.translate((float) (this.childPositionInWindow[0] - this.thisPositionInWindow[0] + this.halfPaddingOnSides), (float) (this.halfPaddingOnSides + this.childPositionInWindow[1] - this.thisPositionInWindow[1])); 199 | rootView.getBackground().draw(this.blurCanvas); 200 | this.blurCanvas.restore(); 201 | } 202 | 203 | for (int i = 0; i < rootView.getChildCount(); ++i) { 204 | View childView = rootView.getChildAt(i); 205 | if (childView.findViewWithTag(TAG_VIEW) != null & rootView.getVisibility() == View.VISIBLE) { 206 | this.printViewsBehind((ViewGroup) childView); 207 | } else if (childView.getVisibility() == View.VISIBLE) { 208 | this.blurCanvas.save(); 209 | childView.getLocationOnScreen(this.childPositionInWindow); 210 | this.blurCanvas.translate((float) (this.halfPaddingOnSides + this.childPositionInWindow[0] - this.thisPositionInWindow[0]), (float) (this.halfPaddingOnSides + this.childPositionInWindow[1] - this.thisPositionInWindow[1])); 211 | this.blurCanvas.scale(childView.getScaleX(), childView.getScaleY()); 212 | childView.draw(this.blurCanvas); 213 | this.blurCanvas.restore(); 214 | } 215 | } 216 | } 217 | } 218 | 219 | @Override 220 | protected void onAttachedToWindow() { 221 | super.onAttachedToWindow(); 222 | if (!this.isInEditMode()) { 223 | ((Activity) this.getContext()).getWindow().getDecorView().getViewTreeObserver().addOnScrollChangedListener(this.onscrollChangedListener); 224 | } 225 | } 226 | 227 | @Override 228 | protected void onDetachedFromWindow() { 229 | super.onDetachedFromWindow(); 230 | if (blurBitmap != null) { 231 | this.blurBitmap.recycle(); 232 | this.blurBitmap = null; 233 | } 234 | 235 | if (snapShotBitmap != null) { 236 | this.snapShotBitmap.recycle(); 237 | this.snapShotBitmap = null; 238 | } 239 | 240 | //RenderScript 241 | if (mRenderScript != null) { 242 | mRenderScript.destroy(); 243 | } 244 | if (!this.isInEditMode()) { 245 | ((Activity) this.getContext()).getWindow().getDecorView().getViewTreeObserver().removeOnScrollChangedListener(this.onscrollChangedListener); 246 | } 247 | } 248 | 249 | @Override 250 | protected void onDraw(Canvas canvas) { 251 | super.onDraw(canvas); 252 | if (this.isInEditMode()) { 253 | canvas.drawColor(Color.TRANSPARENT); 254 | } else if (this.blurBitmap != null && BlurBehindView.this.blurRadius > 0.0F) { 255 | if (BlurBehindView.this.clipCircleOutline) { 256 | canvas.clipPath(this.circlePath); 257 | }else if (clipPath != null){ 258 | canvas.clipPath(this.clipPath); 259 | } else if (this.roundPath != null) { 260 | canvas.clipPath(this.roundPath); 261 | } 262 | 263 | canvas.drawBitmap(this.blurBitmap, null, new Rect(-this.halfPaddingOnSides, -this.halfPaddingOnSides, this.getWidth() + this.halfPaddingOnSides, this.getHeight() + this.halfPaddingOnSides), (Paint) null); 264 | if (BlurBehindView.this.getBackground() != null) { 265 | BlurBehindView.this.getBackground().draw(canvas); 266 | } 267 | 268 | this.isInDrawPassFromThisView = false; 269 | if (BlurBehindView.this.updateMode == UPDATE_CONTINOUSLY) { 270 | this.drawToBitmap(); 271 | } 272 | } 273 | } 274 | 275 | @Override 276 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 277 | super.onLayout(changed, left, top, right, bottom); 278 | if (this.snapShotBitmap == null) { 279 | this.initDrawingBitmap(); 280 | this.initCirclePath(); 281 | this.initRoundRectPath(); 282 | } 283 | } 284 | 285 | private void initRoundRectPath() { 286 | this.roundPath.reset(); 287 | RectF rectF = new RectF(); 288 | rectF.set(0, 0, this.getWidth(), this.getHeight()); 289 | roundPath.addRoundRect(rectF, BlurBehindView.this.cornerRadius, BlurBehindView.this.cornerRadius, Direction.CCW); 290 | } 291 | 292 | public void initCirclePath() { 293 | this.circlePath.reset(); 294 | this.circlePath.addCircle((float) (this.getWidth() / 2), (float) (this.getHeight() / 2), Math.min((float) this.getWidth(), (float) (this.getHeight() / 2) * BlurBehindView.this.clipCircleRadius), Direction.CCW); 295 | } 296 | 297 | public void initDrawingBitmap() { 298 | this.extraPaddingOnSides = PADDING_SIDE_TO_AVOID_FLICKER * this.getResources().getDisplayMetrics().density * BlurBehindView.this.sizeDivider; 299 | this.halfPaddingOnSides = (int) (this.extraPaddingOnSides / 2.0F); 300 | this.snapShotBitmap = Bitmap.createBitmap((int) ((float) this.getWidth() / BlurBehindView.this.sizeDivider + this.extraPaddingOnSides / BlurBehindView.this.sizeDivider), (int) ((float) this.getHeight() / BlurBehindView.this.sizeDivider + this.extraPaddingOnSides / BlurBehindView.this.sizeDivider), Config.ARGB_8888); 301 | this.blurCanvas = new Canvas(this.snapShotBitmap); 302 | 303 | //RenderScript 304 | mBlurInput = Allocation.createFromBitmap(mRenderScript, this.snapShotBitmap, 305 | Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 306 | mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); 307 | 308 | this.drawToBitmap(); 309 | 310 | } 311 | 312 | private void initRenderScript(Context context) { 313 | //RenderScript 314 | mRenderScript = RenderScript.create(context); 315 | mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); 316 | blurRadius(blurRadius); 317 | } 318 | 319 | private void drawToBitmap() { 320 | if (this.blurCanvas != null) { 321 | this.blurCanvas.save(); 322 | // this.blurCanvas.drawColor(0, Mode.CLEAR); 323 | this.blurCanvas.drawColor(Color.WHITE,Mode.SRC_OVER); 324 | this.blurCanvas.scale(1.0F / BlurBehindView.this.sizeDivider, 1.0F / BlurBehindView.this.sizeDivider); 325 | this.getLocationOnScreen(this.thisPositionInWindow); 326 | this.printViewsBehind((ViewGroup) this.getRootView()); 327 | if (!this.isInEditMode()) { 328 | 329 | //saveIntoFile("/sdcard/"+System.currentTimeMillis()+".png",snapShotBitmap); 330 | 331 | if (mProcessor != null) { 332 | this.blurBitmap = mProcessor.process(this.snapShotBitmap, BlurBehindView.this.blurRadius); 333 | Log.i("robin", "Do Blur Processor"); 334 | } else { 335 | //this.blurBitmap = NdkStackBlurProcessor.INSTANCE.process(this.snapShotBitmap, BlurBehindView.this.blurRadius); 336 | 337 | //RenderScript 338 | if (mBlurInput != null && mBlurScript != null && mBlurOutput != null && this.snapShotBitmap != null) { 339 | if (blurBitmap == null) { 340 | this.blurBitmap = Bitmap.createBitmap((int) ((float) this.getWidth() / BlurBehindView.this.sizeDivider + this.extraPaddingOnSides / BlurBehindView.this.sizeDivider), (int) ((float) this.getHeight() / BlurBehindView.this.sizeDivider + this.extraPaddingOnSides / BlurBehindView.this.sizeDivider), Config.ARGB_8888); 341 | } 342 | mBlurInput.copyFrom(this.snapShotBitmap); 343 | mBlurScript.setInput(mBlurInput); 344 | mBlurScript.forEach(mBlurOutput); 345 | mBlurOutput.copyTo(this.blurBitmap); 346 | Log.i("robin", "Do Blur RenderScript"); 347 | } 348 | 349 | } 350 | 351 | } 352 | 353 | this.invalidate(); 354 | this.blurCanvas.restore(); 355 | } 356 | 357 | } 358 | 359 | public BlurRender setClipPath(Path clipPath) { 360 | this.clipPath = clipPath; 361 | return this; 362 | } 363 | 364 | public void saveIntoFile (String path, Bitmap bitmap){ 365 | try { 366 | FileOutputStream out = new FileOutputStream(path); 367 | bitmap.compress(Bitmap.CompressFormat.PNG, 80, out); 368 | out.flush(); 369 | out.close(); 370 | } catch (Exception e) { 371 | e.printStackTrace(); 372 | } 373 | } 374 | 375 | public BlurRender setProcessor(BlurProcessor processor) { 376 | mProcessor = processor; 377 | return this; 378 | } 379 | 380 | public BlurRender setRenderScriptBlurRadius(int radius){ 381 | //RenderScript 382 | if (mBlurScript != null) { 383 | mBlurScript.setRadius(radius); 384 | } 385 | return this; 386 | } 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/BlurDrawable.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Bitmap; 6 | import android.graphics.Canvas; 7 | import android.graphics.Color; 8 | import android.graphics.Path; 9 | import android.graphics.RectF; 10 | import android.graphics.drawable.ColorDrawable; 11 | import android.support.v8.renderscript.Allocation; 12 | import android.support.v8.renderscript.Element; 13 | import android.support.v8.renderscript.RenderScript; 14 | import android.support.v8.renderscript.ScriptIntrinsicBlur; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.view.Window; 18 | 19 | import java.io.FileOutputStream; 20 | 21 | /** 22 | * Created by Robin on 2016/8/22 12:20. 23 | */ 24 | public class BlurDrawable extends ColorDrawable { 25 | 26 | private final View mBlurredView; 27 | private Bitmap mSnapShotBitmap, mBlurredBitmap; 28 | private int mBlurredViewWidth, mBlurredViewHeight; 29 | private boolean mSizeDividerChanged; 30 | private Canvas mBlurCanvas; 31 | 32 | private float mCornerRadius = 0; 33 | private final Path mRoundClipPath = new Path(); 34 | private final RectF mRoundRectF = new RectF(); 35 | 36 | private int mDrawableContainerId; 37 | private float mOffsetX; 38 | private float mOffsetY; 39 | private int mBlurRadius = 1; 40 | private int mSizeDivider; 41 | private int mOverlayColor = Color.TRANSPARENT; 42 | 43 | private static boolean sEnabled = true; 44 | 45 | //RenderScript 46 | private RenderScript mRenderScript; 47 | private ScriptIntrinsicBlur mBlurScript; 48 | private Allocation mBlurInput, mBlurOutput; 49 | 50 | public BlurDrawable(View blurredView) { 51 | this.mBlurredView = blurredView; 52 | if (sEnabled) { 53 | initRenderScript(blurredView.getContext()); 54 | initDrawingBitmap(); 55 | } 56 | overlayColor(mOverlayColor); 57 | } 58 | 59 | public BlurDrawable(Activity activity) { 60 | this(activity.getWindow().getDecorView()); 61 | } 62 | 63 | public BlurDrawable(Window blurredWindow) { 64 | this(blurredWindow.getDecorView()); 65 | } 66 | 67 | private void initRenderScript(Context context) { 68 | mRenderScript = RenderScript.create(context); 69 | mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); 70 | blurRadius(mBlurRadius); 71 | sizeDivider(8); 72 | } 73 | 74 | private boolean initDrawingBitmap() { 75 | final int width = mBlurredView.getWidth(); 76 | final int height = mBlurredView.getHeight(); 77 | if (mBlurCanvas == null 78 | || mSizeDividerChanged 79 | || mBlurredViewWidth != width 80 | || mBlurredViewHeight != height) { 81 | mSizeDividerChanged = false; 82 | 83 | mBlurredViewWidth = width; 84 | mBlurredViewHeight = height; 85 | 86 | int scaledWidth = width / mSizeDivider; 87 | int scaledHeight = height / mSizeDivider; 88 | 89 | scaledWidth = scaledWidth - scaledWidth % 4 + 4; 90 | scaledHeight = scaledHeight - scaledHeight % 4 + 4; 91 | 92 | if (mBlurredBitmap == null 93 | || mBlurredBitmap.getWidth() != scaledWidth 94 | || mBlurredBitmap.getHeight() != scaledHeight) { 95 | mSnapShotBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); 96 | if (mSnapShotBitmap == null) { 97 | return false; 98 | } 99 | 100 | mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); 101 | if (mBlurredBitmap == null) { 102 | return false; 103 | } 104 | } 105 | 106 | 107 | // mBlurredBitmap = Bitmap.createBitmap((int) ((float) mBlurredView.getWidth() / mSizeDivider), (int) ((float) mBlurredView.getHeight() / mSizeDivider), Bitmap.Config.ARGB_8888); 108 | // 109 | // this.mSnapShotBitmap = Bitmap.createBitmap((int) ((float) mBlurredView.getWidth() / mSizeDivider), (int) ((float) mBlurredView.getHeight() / mSizeDivider), Bitmap.Config.ARGB_8888); 110 | mBlurCanvas = new Canvas(mSnapShotBitmap); 111 | mBlurCanvas.scale(1.0F / mSizeDivider, 1.0F / mSizeDivider); 112 | 113 | mBlurInput = Allocation.createFromBitmap(mRenderScript, mSnapShotBitmap, 114 | Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 115 | mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); 116 | 117 | } 118 | return true; 119 | } 120 | 121 | @Override 122 | public void draw(Canvas canvas) { 123 | 124 | if (mCornerRadius != 0) { 125 | mRoundClipPath.reset(); 126 | mRoundRectF.set(0, 0, canvas.getWidth(), canvas.getHeight()); 127 | mRoundClipPath.addRoundRect(mRoundRectF, mCornerRadius, mCornerRadius, Path.Direction.CCW); 128 | canvas.clipPath(mRoundClipPath); 129 | } 130 | if (sEnabled) { 131 | drawBlur(canvas); 132 | } 133 | //draw overlayColor 134 | super.draw(canvas); 135 | 136 | } 137 | 138 | private void drawBlur(Canvas canvas) { 139 | if (initDrawingBitmap()) { 140 | 141 | printView(mBlurredView); 142 | blur(mSnapShotBitmap, mBlurredBitmap); 143 | 144 | canvas.save(); 145 | canvas.translate(mBlurredView.getX() - mOffsetX, mBlurredView.getY() - mOffsetY); 146 | canvas.scale(mSizeDivider, mSizeDivider); 147 | canvas.drawBitmap(mBlurredBitmap, 0, 0, null); 148 | canvas.restore(); 149 | } 150 | 151 | } 152 | 153 | private void printView(View bluredView) { 154 | if (!(bluredView instanceof ViewGroup)) { 155 | bluredView.draw(mBlurCanvas); 156 | return; 157 | } 158 | 159 | ViewGroup rootView = (ViewGroup) bluredView; 160 | 161 | if (rootView.getVisibility() == View.VISIBLE && rootView.getAlpha() != 0.0F) { 162 | if (rootView.findViewById(mDrawableContainerId) == null) { 163 | rootView.draw(mBlurCanvas); 164 | return; 165 | } 166 | 167 | for (int i = 0; i < rootView.getChildCount(); ++i) { 168 | View childView = rootView.getChildAt(i); 169 | 170 | if (childView.findViewById(mDrawableContainerId) != null & rootView.getVisibility() == View.VISIBLE) { 171 | this.printView(childView); 172 | } else if (childView.getVisibility() == View.VISIBLE) { 173 | childView.draw(mBlurCanvas); 174 | } 175 | } 176 | } 177 | } 178 | 179 | private void blur(Bitmap bitmapToBlur, Bitmap blurredBitmap) { 180 | if (!sEnabled) { 181 | return; 182 | } 183 | 184 | //just test 185 | //saveIntoFile("/sdcard/"+System.currentTimeMillis()+".png",mSnapShotBitmap); 186 | 187 | mBlurInput.copyFrom(bitmapToBlur); 188 | mBlurScript.setInput(mBlurInput); 189 | mBlurScript.forEach(mBlurOutput); 190 | mBlurOutput.copyTo(blurredBitmap); 191 | 192 | //mBlurredBitmap = NdkStackBlurProcessor.INSTANCE.process(bitmapToBlur,mBlurRadius); 193 | } 194 | 195 | /** 196 | * used for test 197 | * 198 | * @param path 199 | * @param bitmap 200 | */ 201 | public void saveIntoFile(String path, Bitmap bitmap) { 202 | try { 203 | FileOutputStream out = new FileOutputStream(path); 204 | bitmap.compress(Bitmap.CompressFormat.PNG, 80, out); 205 | out.flush(); 206 | out.close(); 207 | } catch (Exception e) { 208 | e.printStackTrace(); 209 | } 210 | } 211 | 212 | public BlurDrawable offset(float x, float y) { 213 | this.mOffsetX = x; 214 | this.mOffsetY = y; 215 | return this; 216 | } 217 | 218 | public BlurDrawable blurRadius(int radius) { 219 | if (!sEnabled) { 220 | return this; 221 | } 222 | this.mBlurRadius = radius; 223 | mBlurScript.setRadius(radius); 224 | 225 | return this; 226 | } 227 | 228 | public BlurDrawable sizeDivider(int sizeDivider) { 229 | if (!sEnabled) { 230 | return this; 231 | } 232 | if (mSizeDivider != sizeDivider) { 233 | mSizeDivider = sizeDivider; 234 | mSizeDividerChanged = true; 235 | } 236 | return this; 237 | } 238 | 239 | public BlurDrawable cornerRadius(float radius) { 240 | this.mCornerRadius = radius; 241 | return this; 242 | } 243 | 244 | public BlurDrawable overlayColor(int color) { 245 | mOverlayColor = color; 246 | setColor(color); 247 | return this; 248 | } 249 | 250 | public BlurDrawable drawableContainerId(int drawableContainerId) { 251 | mDrawableContainerId = drawableContainerId; 252 | return this; 253 | } 254 | 255 | public BlurDrawable enabled(boolean enabled) { 256 | BlurDrawable.sEnabled = enabled; 257 | return this; 258 | } 259 | 260 | public void onDestroy() { 261 | if (!sEnabled) { 262 | return; 263 | } 264 | if (mRenderScript != null) { 265 | mRenderScript.destroy(); 266 | } 267 | } 268 | 269 | } 270 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/BlurKernels.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm; 2 | 3 | /** 4 | * Blur kernels for convolve matrix algorithms 5 | */ 6 | public interface BlurKernels { 7 | public static float[] GAUSSIAN_5x5 = new float[] { 8 | 0.0030f, 0.0133f, 0.0219f, 0.0133f, 0.0030f, 9 | 0.0133f, 0.0596f, 0.0983f, 0.0596f, 0.0133f, 10 | 0.0219f, 0.0983f, 0.1621f, 0.0983f, 0.0219f, 11 | 0.0133f, 0.0596f, 0.0983f, 0.0596f, 0.0133f, 12 | 0.0030f, 0.0133f, 0.0219f, 0.0133f, 0.0030f 13 | }; 14 | 15 | public static float[] BOX_5x5 = new float[] { 16 | 0.04f,0.04f,0.04f,0.04f,0.04f, 17 | 0.04f,0.04f,0.04f,0.04f,0.04f, 18 | 0.04f,0.0425f,0.05f,0.0425f,0.04f, 19 | 0.04f,0.04f,0.04f,0.04f,0.04f, 20 | 0.04f,0.04f,0.04f,0.04f,0.04f 21 | }; 22 | 23 | public static float[] BOX_3x3 = new float[]{ 24 | 0.111111111111111111111111112f, 0.111111111111111111111111112f, 0.111111111111111111111111112f, 25 | 0.111111111111111111111111112f, 0.13f, 0.111111111111111111111111112f, 26 | 0.111111111111111111111111112f, 0.111111111111111111111111112f, 0.111111111111111111111111112f 27 | }; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/IBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | /** 6 | * Interface for a blur algorithm 7 | */ 8 | public interface IBlur { 9 | //threshold for live blurring 10 | public static final int MS_THRESHOLD_FOR_SMOOTH = 16; 11 | 12 | /** 13 | * Takes a bitmap and blurs it with the given blur radius. This will NOT copy the original 14 | * but reuses it, so if this instance will be used somewhere else, manual copying is needed. 15 | * 16 | * @param radius blurradius, keep in mind some algorithms don't take all values (e.g. ScriptIntrinsicBlur will only take 1-25) 17 | * @param original 18 | * @return blurred original bitmap 19 | */ 20 | public Bitmap blur(int radius, Bitmap original); 21 | } 22 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/IgnoreBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | /** 6 | * This is the default algorithm, that does nothing but returns 7 | * the original bitmap 8 | */ 9 | public class IgnoreBlur implements IBlur { 10 | @Override 11 | public Bitmap blur(int radius, Bitmap original) { 12 | return original; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/java/BoxBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.java; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | 9 | 10 | /** 11 | * http://stackoverflow.com/questions/8218438 12 | * by saarraz1 13 | */ 14 | public class BoxBlur implements IBlur { 15 | @Override 16 | public Bitmap blur(int radius, Bitmap bmp) { 17 | if((radius & 1) == 0 ) throw new IllegalArgumentException("Range must be odd."); 18 | 19 | Bitmap blurred = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), 20 | Bitmap.Config.ARGB_8888); 21 | Canvas c = new Canvas(blurred); 22 | 23 | int w = bmp.getWidth(); 24 | int h = bmp.getHeight(); 25 | 26 | int[] pixels = new int[bmp.getWidth() * bmp.getHeight()]; 27 | bmp.getPixels(pixels, 0, w, 0, 0, w, h); 28 | 29 | boxBlurHorizontal(pixels, w, h, radius / 2); 30 | boxBlurVertical(pixels, w, h, radius / 2); 31 | 32 | c.drawBitmap(pixels, 0, w, 0.0F, 0.0F, w, h, true, null); 33 | 34 | return blurred; 35 | } 36 | 37 | private static void boxBlurHorizontal(int[] pixels, int w, int h, 38 | int halfRange) { 39 | int index = 0; 40 | int[] newColors = new int[w]; 41 | 42 | for (int y = 0; y < h; y++) { 43 | int hits = 0; 44 | long r = 0; 45 | long g = 0; 46 | long b = 0; 47 | for (int x = -halfRange; x < w; x++) { 48 | int oldPixel = x - halfRange - 1; 49 | if (oldPixel >= 0) { 50 | int color = pixels[index + oldPixel]; 51 | if (color != 0) { 52 | r -= Color.red(color); 53 | g -= Color.green(color); 54 | b -= Color.blue(color); 55 | } 56 | hits--; 57 | } 58 | 59 | int newPixel = x + halfRange; 60 | if (newPixel < w) { 61 | int color = pixels[index + newPixel]; 62 | if (color != 0) { 63 | r += Color.red(color); 64 | g += Color.green(color); 65 | b += Color.blue(color); 66 | } 67 | hits++; 68 | } 69 | 70 | if (x >= 0) { 71 | newColors[x] = Color.argb(0xFF, (int) (r / hits), (int) (g / hits), (int) (b / hits)); 72 | } 73 | } 74 | 75 | System.arraycopy(newColors, 0, pixels, index + 0, w); 76 | 77 | index += w; 78 | } 79 | } 80 | 81 | private static void boxBlurVertical(int[] pixels, int w, int h, 82 | int halfRange) { 83 | 84 | int[] newColors = new int[h]; 85 | int oldPixelOffset = -(halfRange + 1) * w; 86 | int newPixelOffset = (halfRange) * w; 87 | 88 | for (int x = 0; x < w; x++) { 89 | int hits = 0; 90 | long r = 0; 91 | long g = 0; 92 | long b = 0; 93 | int index = -halfRange * w + x; 94 | for (int y = -halfRange; y < h; y++) { 95 | int oldPixel = y - halfRange - 1; 96 | if (oldPixel >= 0) { 97 | int color = pixels[index + oldPixelOffset]; 98 | if (color != 0) { 99 | r -= Color.red(color); 100 | g -= Color.green(color); 101 | b -= Color.blue(color); 102 | } 103 | hits--; 104 | } 105 | 106 | int newPixel = y + halfRange; 107 | if (newPixel < h) { 108 | int color = pixels[index + newPixelOffset]; 109 | if (color != 0) { 110 | r += Color.red(color); 111 | g += Color.green(color); 112 | b += Color.blue(color); 113 | } 114 | hits++; 115 | } 116 | 117 | if (y >= 0) { 118 | newColors[y] = Color.argb(0xFF, (int) (r / hits), (int) (g / hits), (int) (b / hits)); 119 | } 120 | 121 | index += w; 122 | } 123 | 124 | for (int y = 0; y < h; y++) { 125 | pixels[y * w + x] = newColors[y]; 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/java/GaussianFastBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.java; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | 7 | 8 | /** 9 | * http://stackoverflow.com/a/13436737/774398 10 | * by gordi 11 | */ 12 | public class GaussianFastBlur implements IBlur { 13 | @Override 14 | public Bitmap blur(int radius, Bitmap original) { 15 | int w = original.getWidth(); 16 | int h = original.getHeight(); 17 | int[] pix = new int[w * h]; 18 | original.getPixels(pix, 0, w, 0, 0, w, h); 19 | 20 | for(int r = radius; r >= 1; r /= 2) { 21 | for(int i = r; i < h - r; i++) { 22 | for(int j = r; j < w - r; j++) { 23 | int tl = pix[(i - r) * w + j - r]; 24 | int tr = pix[(i - r) * w + j + r]; 25 | int tc = pix[(i - r) * w + j]; 26 | int bl = pix[(i + r) * w + j - r]; 27 | int br = pix[(i + r) * w + j + r]; 28 | int bc = pix[(i + r) * w + j]; 29 | int cl = pix[i * w + j - r]; 30 | int cr = pix[i * w + j + r]; 31 | 32 | pix[(i * w) + j] = 0xFF000000 | 33 | (((tl & 0xFF) + (tr & 0xFF) + (tc & 0xFF) + (bl & 0xFF) + (br & 0xFF) + (bc & 0xFF) + (cl & 0xFF) + (cr & 0xFF)) >> 3) & 0xFF | 34 | (((tl & 0xFF00) + (tr & 0xFF00) + (tc & 0xFF00) + (bl & 0xFF00) + (br & 0xFF00) + (bc & 0xFF00) + (cl & 0xFF00) + (cr & 0xFF00)) >> 3) & 0xFF00 | 35 | (((tl & 0xFF0000) + (tr & 0xFF0000) + (tc & 0xFF0000) + (bl & 0xFF0000) + (br & 0xFF0000) + (bc & 0xFF0000) + (cl & 0xFF0000) + (cr & 0xFF0000)) >> 3) & 0xFF0000; 36 | } 37 | } 38 | } 39 | original.setPixels(pix, 0, w, 0, 0, w, h); 40 | return original; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/java/StackBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.java; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | 7 | 8 | /** 9 | * Stack BlurUtil v1.0 from 10 | http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html 11 | 12 | Java Author: Mario Klingemann (mario at quasimondo.com) 13 | http://incubator.quasimondo.com 14 | created Feburary 29, 2004 15 | Android port : Yahel Bouaziz (yahel at kayenko.com) 16 | http://www.kayenko.com 17 | ported april 5th, 2012 18 | 19 | This is a compromise between Gaussian BlurUtil and Box blur 20 | It creates much better looking blurs than Box BlurUtil, but is 21 | 7x faster than my Gaussian BlurUtil implementation. 22 | 23 | I called it Stack BlurUtil because this describes best how this 24 | filter works internally: it creates a kind of moving stack 25 | of colors whilst scanning through the image. Thereby it 26 | just has to add one new block of color to the right side 27 | of the stack and remove the leftmost color. The remaining 28 | colors on the topmost layer of the stack are either added on 29 | or reduced by one, depending on if they are on the right or 30 | on the left side of the stack. 31 | 32 | If you are using this algorithm in your code please add 33 | the following line: 34 | 35 | Stack BlurUtil Algorithm by Mario Klingemann (mario@quasimondo.com) 36 | */ 37 | 38 | public class StackBlur implements IBlur { 39 | @Override 40 | public Bitmap blur(int radius, Bitmap original) { 41 | if (radius < 1) { 42 | return (null); 43 | } 44 | 45 | int w = original.getWidth(); 46 | int h = original.getHeight(); 47 | 48 | int[] pix = new int[w * h]; 49 | original.getPixels(pix, 0, w, 0, 0, w, h); 50 | 51 | int wm = w - 1; 52 | int hm = h - 1; 53 | int wh = w * h; 54 | int div = radius + radius + 1; 55 | 56 | int r[] = new int[wh]; 57 | int g[] = new int[wh]; 58 | int b[] = new int[wh]; 59 | int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; 60 | int vmin[] = new int[Math.max(w, h)]; 61 | 62 | int divsum = (div + 1) >> 1; 63 | divsum *= divsum; 64 | int dv[] = new int[256 * divsum]; 65 | for (i = 0; i < 256 * divsum; i++) { 66 | dv[i] = (i / divsum); 67 | } 68 | 69 | yw = yi = 0; 70 | 71 | int[][] stack = new int[div][3]; 72 | int stackpointer; 73 | int stackstart; 74 | int[] sir; 75 | int rbs; 76 | int r1 = radius + 1; 77 | int routsum, goutsum, boutsum; 78 | int rinsum, ginsum, binsum; 79 | 80 | for (y = 0; y < h; y++) { 81 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 82 | for (i = -radius; i <= radius; i++) { 83 | p = pix[yi + Math.min(wm, Math.max(i, 0))]; 84 | sir = stack[i + radius]; 85 | sir[0] = (p & 0xff0000) >> 16; 86 | sir[1] = (p & 0x00ff00) >> 8; 87 | sir[2] = (p & 0x0000ff); 88 | rbs = r1 - Math.abs(i); 89 | rsum += sir[0] * rbs; 90 | gsum += sir[1] * rbs; 91 | bsum += sir[2] * rbs; 92 | if (i > 0) { 93 | rinsum += sir[0]; 94 | ginsum += sir[1]; 95 | binsum += sir[2]; 96 | } else { 97 | routsum += sir[0]; 98 | goutsum += sir[1]; 99 | boutsum += sir[2]; 100 | } 101 | } 102 | stackpointer = radius; 103 | 104 | for (x = 0; x < w; x++) { 105 | 106 | r[yi] = dv[rsum]; 107 | g[yi] = dv[gsum]; 108 | b[yi] = dv[bsum]; 109 | 110 | rsum -= routsum; 111 | gsum -= goutsum; 112 | bsum -= boutsum; 113 | 114 | stackstart = stackpointer - radius + div; 115 | sir = stack[stackstart % div]; 116 | 117 | routsum -= sir[0]; 118 | goutsum -= sir[1]; 119 | boutsum -= sir[2]; 120 | 121 | if (y == 0) { 122 | vmin[x] = Math.min(x + radius + 1, wm); 123 | } 124 | p = pix[yw + vmin[x]]; 125 | 126 | sir[0] = (p & 0xff0000) >> 16; 127 | sir[1] = (p & 0x00ff00) >> 8; 128 | sir[2] = (p & 0x0000ff); 129 | 130 | rinsum += sir[0]; 131 | ginsum += sir[1]; 132 | binsum += sir[2]; 133 | 134 | rsum += rinsum; 135 | gsum += ginsum; 136 | bsum += binsum; 137 | 138 | stackpointer = (stackpointer + 1) % div; 139 | sir = stack[(stackpointer) % div]; 140 | 141 | routsum += sir[0]; 142 | goutsum += sir[1]; 143 | boutsum += sir[2]; 144 | 145 | rinsum -= sir[0]; 146 | ginsum -= sir[1]; 147 | binsum -= sir[2]; 148 | 149 | yi++; 150 | } 151 | yw += w; 152 | } 153 | for (x = 0; x < w; x++) { 154 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 155 | yp = -radius * w; 156 | for (i = -radius; i <= radius; i++) { 157 | yi = Math.max(0, yp) + x; 158 | 159 | sir = stack[i + radius]; 160 | 161 | sir[0] = r[yi]; 162 | sir[1] = g[yi]; 163 | sir[2] = b[yi]; 164 | 165 | rbs = r1 - Math.abs(i); 166 | 167 | rsum += r[yi] * rbs; 168 | gsum += g[yi] * rbs; 169 | bsum += b[yi] * rbs; 170 | 171 | if (i > 0) { 172 | rinsum += sir[0]; 173 | ginsum += sir[1]; 174 | binsum += sir[2]; 175 | } else { 176 | routsum += sir[0]; 177 | goutsum += sir[1]; 178 | boutsum += sir[2]; 179 | } 180 | 181 | if (i < hm) { 182 | yp += w; 183 | } 184 | } 185 | yi = x; 186 | stackpointer = radius; 187 | for (y = 0; y < h; y++) { 188 | // Preserve alpha channel: ( 0xff000000 & pix[yi] ) 189 | pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; 190 | 191 | rsum -= routsum; 192 | gsum -= goutsum; 193 | bsum -= boutsum; 194 | 195 | stackstart = stackpointer - radius + div; 196 | sir = stack[stackstart % div]; 197 | 198 | routsum -= sir[0]; 199 | goutsum -= sir[1]; 200 | boutsum -= sir[2]; 201 | 202 | if (x == 0) { 203 | vmin[y] = Math.min(y + r1, hm) * w; 204 | } 205 | p = x + vmin[y]; 206 | 207 | sir[0] = r[p]; 208 | sir[1] = g[p]; 209 | sir[2] = b[p]; 210 | 211 | rinsum += sir[0]; 212 | ginsum += sir[1]; 213 | binsum += sir[2]; 214 | 215 | rsum += rinsum; 216 | gsum += ginsum; 217 | bsum += binsum; 218 | 219 | stackpointer = (stackpointer + 1) % div; 220 | sir = stack[stackpointer]; 221 | 222 | routsum += sir[0]; 223 | goutsum += sir[1]; 224 | boutsum += sir[2]; 225 | 226 | rinsum -= sir[0]; 227 | ginsum -= sir[1]; 228 | binsum -= sir[2]; 229 | 230 | yi += w; 231 | } 232 | } 233 | original.setPixels(pix, 0, w, 0, 0, w, h); 234 | return (original); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/java/SuperFastBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.java; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | /** 7 | * Super Fast Blur by Mario Klingemann
8 | * Resource: http://incubator.quasimondo.com/processing/superfast_blur.php
9 | * StackOverflow - Understanding super fast blur algorithm: http://stackoverflow.com/questions/21418892/understanding-super-fast-blur-algorithm
10 | */ 11 | public class SuperFastBlur implements IBlur { 12 | @Override 13 | public Bitmap blur(int radius, Bitmap original) { 14 | int w= original.getWidth(); 15 | int h=original.getHeight(); 16 | int wm=w-1; 17 | int hm=h-1; 18 | int wh=w*h; 19 | int div=radius+radius+1; 20 | int r[]=new int[wh]; 21 | int g[]=new int[wh]; 22 | int b[]=new int[wh]; 23 | int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw; 24 | int vmin[] = new int[Math.max(w,h)]; 25 | int vmax[] = new int[Math.max(w,h)]; 26 | int[] pix= new int[w*h]; 27 | 28 | original.getPixels(pix, 0, w, 0,0,w, h); 29 | 30 | int dv[]=new int[256*div]; 31 | for (i=0;i<256*div;i++){ 32 | dv[i]=(i/div); 33 | } 34 | 35 | yw=yi=0; 36 | 37 | for (y=0;y>16; 42 | gsum+=(p & 0x00ff00)>>8; 43 | bsum+= p & 0x0000ff; 44 | } 45 | for (x=0;x>16; 59 | gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; 60 | bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff); 61 | yi++; 62 | } 63 | yw+=w; 64 | } 65 | 66 | for (x=0;x horizontal = new ArrayList(cores); 55 | ArrayList vertical = new ArrayList(cores); 56 | for (int i = 0; i < cores; i++) { 57 | horizontal.add(new NativeTask(bitmap, radius, cores, i, 1)); 58 | vertical.add(new NativeTask(bitmap, radius, cores, i, 2)); 59 | } 60 | 61 | try { 62 | mExecutor.invokeAll(horizontal); 63 | } catch (InterruptedException e) { 64 | return bitmap; 65 | } 66 | 67 | try { 68 | mExecutor.invokeAll(vertical); 69 | } catch (InterruptedException e) { 70 | return bitmap; 71 | } 72 | } 73 | return bitmap; 74 | } 75 | 76 | private static class NativeTask implements Callable { 77 | private final Bitmap mBitmapOut; 78 | private final int mRadius; 79 | private final int mTotalCores; 80 | private final int mCoreIndex; 81 | private final int mRound; 82 | 83 | public NativeTask(Bitmap bitmapOut, int radius, int totalCores, int coreIndex, int round) { 84 | mBitmapOut = bitmapOut; 85 | mRadius = radius; 86 | mTotalCores = totalCores; 87 | mCoreIndex = coreIndex; 88 | mRound = round; 89 | } 90 | 91 | @Override 92 | public Void call() throws Exception { 93 | functionToBlur(mBitmapOut, mRadius, mTotalCores, mCoreIndex, mRound); 94 | return null; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/rs/RSBox3x3Blur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.rs; 2 | 3 | import android.graphics.Bitmap; 4 | import android.support.v8.renderscript.Allocation; 5 | import android.support.v8.renderscript.Element; 6 | import android.support.v8.renderscript.RenderScript; 7 | import android.support.v8.renderscript.ScriptIntrinsicConvolve3x3; 8 | 9 | import net.robinx.lib.blurview.algorithm.BlurKernels; 10 | import net.robinx.lib.blurview.algorithm.IBlur; 11 | 12 | 13 | /** 14 | * This is a convolve matrix based blur algorithms powered by Renderscript's ScriptIntrinsicConvolve class. This uses a box kernel. 15 | * Instead of radius it uses passes, so a radius parameter of 16 makes the convolve algorithm applied 16 times onto the image. 16 | */ 17 | public class RSBox3x3Blur implements IBlur { 18 | private RenderScript rs; 19 | 20 | public RSBox3x3Blur(RenderScript rs) { 21 | this.rs = rs; 22 | } 23 | 24 | @Override 25 | public Bitmap blur(int radius, Bitmap bitmapOriginal) { 26 | radius = Math.min(radius,25); 27 | 28 | Allocation input = Allocation.createFromBitmap(rs, bitmapOriginal); 29 | final Allocation output = Allocation.createTyped(rs, input.getType()); 30 | final ScriptIntrinsicConvolve3x3 script = ScriptIntrinsicConvolve3x3.create(rs, Element.U8_4(rs)); 31 | script.setCoefficients(BlurKernels.BOX_3x3); 32 | for (int i = 0; i < radius; i++) { 33 | script.setInput(input); 34 | script.forEach(output); 35 | input = output; 36 | } 37 | output.copyTo(bitmapOriginal); 38 | return bitmapOriginal; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/rs/RSBox5x5Blur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.rs; 2 | 3 | import android.graphics.Bitmap; 4 | import android.support.v8.renderscript.Allocation; 5 | import android.support.v8.renderscript.Element; 6 | import android.support.v8.renderscript.RenderScript; 7 | import android.support.v8.renderscript.ScriptIntrinsicConvolve5x5; 8 | 9 | import net.robinx.lib.blurview.algorithm.BlurKernels; 10 | import net.robinx.lib.blurview.algorithm.IBlur; 11 | 12 | 13 | /** 14 | * This is a convolve matrix based blur algorithms powered by Renderscript's ScriptIntrinsicConvolve class. This uses a box kernel. 15 | * Instead of radius it uses passes, so a radius parameter of 16 makes the convolve algorithm applied 16 times onto the image. 16 | */ 17 | public class RSBox5x5Blur implements IBlur { 18 | private RenderScript rs; 19 | 20 | public RSBox5x5Blur(RenderScript rs) { 21 | this.rs = rs; 22 | } 23 | 24 | @Override 25 | public Bitmap blur(int radius, Bitmap bitmapOriginal) { 26 | radius = Math.min(radius,25); 27 | 28 | Allocation input = Allocation.createFromBitmap(rs, bitmapOriginal); 29 | final Allocation output = Allocation.createTyped(rs, input.getType()); 30 | final ScriptIntrinsicConvolve5x5 script = ScriptIntrinsicConvolve5x5.create(rs, Element.U8_4(rs)); 31 | script.setCoefficients(BlurKernels.BOX_5x5); 32 | for (int i = 0; i < radius; i++) { 33 | script.setInput(input); 34 | script.forEach(output); 35 | input = output; 36 | } 37 | output.copyTo(bitmapOriginal); 38 | return bitmapOriginal; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/rs/RSGaussian5x5Blur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.rs; 2 | 3 | import android.graphics.Bitmap; 4 | import android.support.v8.renderscript.Allocation; 5 | import android.support.v8.renderscript.Element; 6 | import android.support.v8.renderscript.RenderScript; 7 | import android.support.v8.renderscript.ScriptIntrinsicConvolve5x5; 8 | 9 | import net.robinx.lib.blurview.algorithm.BlurKernels; 10 | import net.robinx.lib.blurview.algorithm.IBlur; 11 | 12 | 13 | /** 14 | * This is a convolve matrix based blur algorithms powered by Renderscript's ScriptIntrinsicConvolve class. This uses a gaussian kernel. 15 | * Instead of radius it uses passes, so a radius parameter of 16 makes the convolve algorithm applied 16 times onto the image. 16 | */ 17 | public class RSGaussian5x5Blur implements IBlur { 18 | private RenderScript rs; 19 | 20 | public RSGaussian5x5Blur(RenderScript rs) { 21 | this.rs = rs; 22 | } 23 | 24 | @Override 25 | public Bitmap blur(int radius, Bitmap bitmapOriginal) { 26 | radius = Math.min(radius,25); 27 | 28 | Allocation input = Allocation.createFromBitmap(rs, bitmapOriginal); 29 | final Allocation output = Allocation.createTyped(rs, input.getType()); 30 | final ScriptIntrinsicConvolve5x5 script = ScriptIntrinsicConvolve5x5.create(rs, Element.U8_4(rs)); 31 | script.setCoefficients(BlurKernels.GAUSSIAN_5x5); 32 | for (int i = 0; i < radius; i++) { 33 | script.setInput(input); 34 | script.forEach(output); 35 | input = output; 36 | } 37 | output.copyTo(bitmapOriginal); 38 | return bitmapOriginal; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/rs/RSGaussianBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.rs; 2 | 3 | import android.graphics.Bitmap; 4 | import android.support.v8.renderscript.Allocation; 5 | import android.support.v8.renderscript.Element; 6 | import android.support.v8.renderscript.RenderScript; 7 | import android.support.v8.renderscript.ScriptIntrinsicBlur; 8 | 9 | import net.robinx.lib.blurview.algorithm.IBlur; 10 | 11 | 12 | /** 13 | * Simple example of ScriptIntrinsicBlur Renderscript gaussion blur. 14 | * In production always use this algorithm as it is the fastest on Android. 15 | */ 16 | public class RSGaussianBlur implements IBlur { 17 | private RenderScript rs; 18 | 19 | public RSGaussianBlur(RenderScript rs) { 20 | this.rs = rs; 21 | } 22 | 23 | @Override 24 | public Bitmap blur(int radius, Bitmap bitmapOriginal) { 25 | radius = Math.min(radius,25); 26 | 27 | final Allocation input = Allocation.createFromBitmap(rs, bitmapOriginal); 28 | final Allocation output = Allocation.createTyped(rs, input.getType()); 29 | final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 30 | script.setRadius(radius); 31 | script.setInput(input); 32 | script.forEach(output); 33 | output.copyTo(bitmapOriginal); 34 | return bitmapOriginal; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/algorithm/rs/RSStackBlur.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.algorithm.rs; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.Allocation; 6 | import android.support.v8.renderscript.Element; 7 | import android.support.v8.renderscript.RenderScript; 8 | 9 | import net.robinx.lib.blurview.algorithm.IBlur; 10 | import net.robinx.lib.blurview.R; 11 | 12 | import at.favre.app.blurbenchmark.ScriptC_stackblur; 13 | 14 | 15 | /** 16 | * by kikoso 17 | * from https://github.com/kikoso/android-stackblur/blob/master/StackBlur/src/blur.rs 18 | */ 19 | public class RSStackBlur implements IBlur { 20 | private RenderScript _rs; 21 | private Context ctx; 22 | 23 | public RSStackBlur(RenderScript rs, Context ctx) { 24 | this.ctx = ctx; 25 | this._rs = rs; 26 | } 27 | 28 | @Override 29 | public Bitmap blur(int radius, Bitmap blurred) { 30 | radius = Math.min(radius,25); 31 | 32 | int width = blurred.getWidth(); 33 | int height = blurred.getHeight(); 34 | 35 | ScriptC_stackblur blurScript = new ScriptC_stackblur(_rs, ctx.getResources(), R.raw.stackblur); 36 | 37 | Allocation inAllocation = Allocation.createFromBitmap(_rs, blurred); 38 | 39 | blurScript.set_gIn(inAllocation); 40 | blurScript.set_width(width); 41 | blurScript.set_height(height); 42 | blurScript.set_radius(radius); 43 | 44 | int[] row_indices = new int[height]; 45 | for (int i = 0; i < height; i++) { 46 | row_indices[i] = i; 47 | } 48 | 49 | Allocation rows = Allocation.createSized(_rs, Element.U32(_rs), height, Allocation.USAGE_SCRIPT); 50 | rows.copyFrom(row_indices); 51 | 52 | row_indices = new int[width]; 53 | for (int i = 0; i < width; i++) { 54 | row_indices[i] = i; 55 | } 56 | 57 | Allocation columns = Allocation.createSized(_rs, Element.U32(_rs), width, Allocation.USAGE_SCRIPT); 58 | columns.copyFrom(row_indices); 59 | 60 | blurScript.forEach_blur_h(rows); 61 | blurScript.forEach_blur_v(columns); 62 | inAllocation.copyTo(blurred); 63 | 64 | return blurred; 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/BlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | 7 | /** 8 | * Created by Robin on 2016/8/20 15:18. 9 | */ 10 | public interface BlurProcessor { 11 | Bitmap process(Bitmap original,int radius); 12 | } 13 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/BlurProcessorProxy.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | /** 6 | * Created by Robin on 2016/8/22 10:12. 7 | */ 8 | public enum BlurProcessorProxy implements BlurProcessor { 9 | 10 | INSTANCE; 11 | 12 | private BlurProcessorProxy() { 13 | } 14 | 15 | private BlurProcessor mBlurProcessor; 16 | private boolean mCopy; 17 | 18 | @Override 19 | public Bitmap process(Bitmap original, int radius) { 20 | Bitmap bitmap = buildBitmap(original, mCopy); 21 | if (mBlurProcessor == null) { 22 | mBlurProcessor = NdkStackBlurProcessor.INSTANCE; 23 | } 24 | return mBlurProcessor.process(bitmap, radius); 25 | } 26 | 27 | private static Bitmap buildBitmap(Bitmap bitmap, boolean copy) { 28 | // If can copy return copy 29 | Bitmap rBitmap; 30 | if (copy) { 31 | rBitmap = bitmap.copy(bitmap.getConfig(), true); 32 | } else { 33 | rBitmap = bitmap; 34 | } 35 | return (rBitmap); 36 | } 37 | 38 | public BlurProcessorProxy processor(BlurProcessor processor) { 39 | mBlurProcessor = processor; 40 | return this; 41 | } 42 | 43 | public BlurProcessorProxy copy(boolean copy) { 44 | mCopy = copy; 45 | return this; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/IgnoreBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.IgnoreBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 16:16. 10 | */ 11 | public enum IgnoreBlurProcessor implements BlurProcessor { 12 | 13 | INSTANCE; 14 | 15 | private IgnoreBlurProcessor() { 16 | mIgnoreBlur = new IgnoreBlur(); 17 | } 18 | 19 | private IBlur mIgnoreBlur; 20 | 21 | @Override 22 | public Bitmap process(Bitmap original, int radius) { 23 | return mIgnoreBlur.blur(radius, original); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/JavaBoxBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.java.BoxBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 16:16. 10 | */ 11 | public enum JavaBoxBlurProcessor implements BlurProcessor { 12 | 13 | INSTANCE; 14 | 15 | private JavaBoxBlurProcessor() { 16 | mBoxBlur = new BoxBlur(); 17 | } 18 | 19 | private IBlur mBoxBlur; 20 | 21 | @Override 22 | public Bitmap process(Bitmap original, int radius) { 23 | return mBoxBlur.blur(radius, original); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/JavaGaussianFastBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.java.GaussianFastBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 16:16. 10 | */ 11 | public enum JavaGaussianFastBlurProcessor implements BlurProcessor { 12 | 13 | INSTANCE; 14 | 15 | private JavaGaussianFastBlurProcessor() { 16 | mGaussianFastBlur = new GaussianFastBlur(); 17 | } 18 | 19 | private IBlur mGaussianFastBlur; 20 | 21 | @Override 22 | public Bitmap process(Bitmap original, int radius) { 23 | return mGaussianFastBlur.blur(radius, original); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/JavaStackBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.java.StackBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 16:16. 10 | */ 11 | public enum JavaStackBlurProcessor implements BlurProcessor { 12 | 13 | INSTANCE; 14 | 15 | private JavaStackBlurProcessor() { 16 | mStackBlur = new StackBlur(); 17 | } 18 | 19 | private IBlur mStackBlur; 20 | 21 | @Override 22 | public Bitmap process(Bitmap original, int radius) { 23 | return mStackBlur.blur(radius, original); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/JavaSuperFastBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.java.SuperFastBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 16:16. 10 | */ 11 | public enum JavaSuperFastBlurProcessor implements BlurProcessor { 12 | 13 | INSTANCE; 14 | 15 | private JavaSuperFastBlurProcessor() { 16 | mSuperFastBlur = new SuperFastBlur(); 17 | } 18 | 19 | private IBlur mSuperFastBlur; 20 | 21 | @Override 22 | public Bitmap process(Bitmap original, int radius) { 23 | return mSuperFastBlur.blur(radius, original); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/NdkStackBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import net.robinx.lib.blurview.algorithm.IBlur; 6 | import net.robinx.lib.blurview.algorithm.ndk.NdkStackBlur; 7 | 8 | /** 9 | * Created by Robin on 2016/8/20 15:42. 10 | */ 11 | public enum NdkStackBlurProcessor implements BlurProcessor { 12 | INSTANCE; 13 | private NdkStackBlurProcessor(){ 14 | mNdkStackBlur = NdkStackBlur.createMultithreaded(); 15 | } 16 | 17 | private IBlur mNdkStackBlur; 18 | 19 | @Override 20 | public Bitmap process(Bitmap original, int radius) { 21 | return mNdkStackBlur.blur(radius, original); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/RSBox3x3BlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.RenderScript; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | import net.robinx.lib.blurview.algorithm.rs.RSBox3x3Blur; 9 | 10 | /** 11 | * Created by Robin on 2016/8/20 15:51. 12 | */ 13 | public class RSBox3x3BlurProcessor implements BlurProcessor { 14 | 15 | private volatile static RSBox3x3BlurProcessor INSTANCE; 16 | 17 | private RSBox3x3BlurProcessor(Context context) { 18 | mRSBox3x3Blur = new RSBox3x3Blur(RenderScript.create(context)); 19 | } 20 | 21 | public static RSBox3x3BlurProcessor getInstance(Context context) { 22 | if (INSTANCE == null) { 23 | synchronized (RSBox3x3BlurProcessor.class) { 24 | if (INSTANCE == null) { 25 | INSTANCE = new RSBox3x3BlurProcessor(context); 26 | } 27 | } 28 | } 29 | return INSTANCE; 30 | } 31 | 32 | 33 | private IBlur mRSBox3x3Blur; 34 | 35 | 36 | @Override 37 | public Bitmap process(Bitmap original, int radius) { 38 | return mRSBox3x3Blur.blur(radius, original); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/RSBox5x5BlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.RenderScript; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | import net.robinx.lib.blurview.algorithm.rs.RSBox5x5Blur; 9 | 10 | /** 11 | * Created by Robin on 2016/8/20 15:51. 12 | */ 13 | public class RSBox5x5BlurProcessor implements BlurProcessor { 14 | 15 | private volatile static RSBox5x5BlurProcessor INSTANCE; 16 | 17 | private RSBox5x5BlurProcessor(Context context) { 18 | mRSBox5x5Blur = new RSBox5x5Blur(RenderScript.create(context)); 19 | } 20 | 21 | public static RSBox5x5BlurProcessor getInstance(Context context) { 22 | if (INSTANCE == null) { 23 | synchronized (RSBox5x5BlurProcessor.class) { 24 | if (INSTANCE == null) { 25 | INSTANCE = new RSBox5x5BlurProcessor(context); 26 | } 27 | } 28 | } 29 | return INSTANCE; 30 | } 31 | 32 | 33 | private IBlur mRSBox5x5Blur; 34 | 35 | 36 | @Override 37 | public Bitmap process(Bitmap original, int radius) { 38 | return mRSBox5x5Blur.blur(radius, original); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/RSGaussian5x5BlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.RenderScript; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | import net.robinx.lib.blurview.algorithm.rs.RSGaussian5x5Blur; 9 | 10 | /** 11 | * Created by Robin on 2016/8/20 15:51. 12 | */ 13 | public class RSGaussian5x5BlurProcessor implements BlurProcessor { 14 | 15 | private volatile static RSGaussian5x5BlurProcessor INSTANCE; 16 | 17 | private RSGaussian5x5BlurProcessor(Context context) { 18 | mRSGaussian5x5Blur = new RSGaussian5x5Blur(RenderScript.create(context)); 19 | } 20 | 21 | public static RSGaussian5x5BlurProcessor getInstance(Context context) { 22 | if (INSTANCE == null) { 23 | synchronized (RSGaussian5x5BlurProcessor.class) { 24 | if (INSTANCE == null) { 25 | INSTANCE = new RSGaussian5x5BlurProcessor(context); 26 | } 27 | } 28 | } 29 | return INSTANCE; 30 | } 31 | 32 | 33 | private IBlur mRSGaussian5x5Blur; 34 | 35 | 36 | @Override 37 | public Bitmap process(Bitmap original, int radius) { 38 | return mRSGaussian5x5Blur.blur(radius, original); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/RSGaussianBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.RenderScript; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | import net.robinx.lib.blurview.algorithm.rs.RSGaussianBlur; 9 | 10 | /** 11 | * Created by Robin on 2016/8/20 15:51. 12 | */ 13 | public class RSGaussianBlurProcessor implements BlurProcessor { 14 | 15 | private volatile static RSGaussianBlurProcessor INSTANCE; 16 | 17 | private RSGaussianBlurProcessor(Context context) { 18 | mRSGaussianBlur = new RSGaussianBlur(RenderScript.create(context)); 19 | } 20 | 21 | public static RSGaussianBlurProcessor getInstance(Context context) { 22 | if (INSTANCE == null) { 23 | synchronized (RSGaussianBlurProcessor.class) { 24 | if (INSTANCE == null) { 25 | INSTANCE = new RSGaussianBlurProcessor(context); 26 | } 27 | } 28 | } 29 | return INSTANCE; 30 | } 31 | 32 | 33 | private IBlur mRSGaussianBlur; 34 | 35 | 36 | @Override 37 | public Bitmap process(Bitmap original, int radius) { 38 | return mRSGaussianBlur.blur(radius, original); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/java/net/robinx/lib/blurview/processor/RSStackBlurProcessor.java: -------------------------------------------------------------------------------- 1 | package net.robinx.lib.blurview.processor; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v8.renderscript.RenderScript; 6 | 7 | import net.robinx.lib.blurview.algorithm.IBlur; 8 | import net.robinx.lib.blurview.algorithm.rs.RSStackBlur; 9 | 10 | /** 11 | * Created by Robin on 2016/8/20 15:51. 12 | */ 13 | public class RSStackBlurProcessor implements BlurProcessor { 14 | 15 | private volatile static RSStackBlurProcessor INSTANCE; 16 | 17 | private RSStackBlurProcessor(Context context) { 18 | mRSStackBlur = new RSStackBlur(RenderScript.create(context), context); 19 | } 20 | 21 | public static RSStackBlurProcessor getInstance(Context context) { 22 | if (INSTANCE == null) { 23 | synchronized (RSStackBlurProcessor.class) { 24 | if (INSTANCE == null) { 25 | INSTANCE = new RSStackBlurProcessor(context); 26 | } 27 | } 28 | } 29 | return INSTANCE; 30 | } 31 | 32 | 33 | private IBlur mRSStackBlur; 34 | 35 | 36 | @Override 37 | public Bitmap process(Bitmap original, int radius) { 38 | return mRSStackBlur.blur(radius, original); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib.blurview/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | # Create BitmapUtils library 4 | 5 | include $(CLEAR_VARS) 6 | 7 | LOCAL_LDLIBS := -lm -llog -ljnigraphics 8 | 9 | LOCAL_MODULE := blur 10 | LOCAL_SRC_FILES := blur.c 11 | 12 | #LOCAL_CFLAGS = -ffast-math -O3 -funroll-loops 13 | 14 | include $(BUILD_SHARED_LIBRARY) 15 | 16 | 17 | -------------------------------------------------------------------------------- /lib.blurview/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all 2 | APP_PLATFORM:= android-22 3 | APP_OPTIM := release -------------------------------------------------------------------------------- /lib.blurview/src/main/jni/blur.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define LOG_TAG "libbitmaputils" 8 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 9 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 10 | 11 | #define clamp(a,min,max) \ 12 | ({__typeof__ (a) _a__ = (a); \ 13 | __typeof__ (min) _min__ = (min); \ 14 | __typeof__ (max) _max__ = (max); \ 15 | _a__ < _min__ ? _min__ : _a__ > _max__ ? _max__ : _a__; }) 16 | 17 | // Based heavily on http://vitiy.info/Code/stackblur.cpp 18 | // See http://vitiy.info/stackblur-algorithm-multi-threaded-blur-for-cpp/ 19 | // Stack Blur Algorithm by Mario Klingemann 20 | 21 | static unsigned short const stackblur_mul[255] = 22 | { 23 | 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, 24 | 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, 25 | 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, 26 | 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, 27 | 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, 28 | 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, 29 | 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, 30 | 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, 31 | 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, 32 | 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, 33 | 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, 34 | 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, 35 | 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, 36 | 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, 37 | 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, 38 | 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 39 | }; 40 | 41 | static unsigned char const stackblur_shr[255] = 42 | { 43 | 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 44 | 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 45 | 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 46 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 47 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 48 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 49 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 50 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 51 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 52 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 53 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 54 | 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 55 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 56 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 57 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 58 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 59 | }; 60 | 61 | /// Stackblur algorithm body 62 | void stackblurJob(unsigned char* src, ///< input image data 63 | unsigned int w, ///< image width 64 | unsigned int h, ///< image height 65 | unsigned int radius, ///< blur intensity (should be in 2..254 range) 66 | int cores, ///< total number of working threads 67 | int core, ///< current thread number 68 | int step ///< step of processing (1,2) 69 | ) 70 | { 71 | unsigned int x, y, xp, yp, i; 72 | unsigned int sp; 73 | unsigned int stack_start; 74 | unsigned char* stack_ptr; 75 | 76 | unsigned char* src_ptr; 77 | unsigned char* dst_ptr; 78 | 79 | unsigned long sum_r; 80 | unsigned long sum_g; 81 | unsigned long sum_b; 82 | unsigned long sum_in_r; 83 | unsigned long sum_in_g; 84 | unsigned long sum_in_b; 85 | unsigned long sum_out_r; 86 | unsigned long sum_out_g; 87 | unsigned long sum_out_b; 88 | 89 | unsigned int wm = w - 1; 90 | unsigned int hm = h - 1; 91 | unsigned int w4 = w * 4; 92 | unsigned int div = (radius * 2) + 1; 93 | unsigned int mul_sum = stackblur_mul[radius]; 94 | unsigned char shr_sum = stackblur_shr[radius]; 95 | unsigned char stack[div * 3]; 96 | 97 | if (step == 1) 98 | { 99 | int minY = core * h / cores; 100 | int maxY = (core + 1) * h / cores; 101 | 102 | for(y = minY; y < maxY; y++) 103 | { 104 | sum_r = sum_g = sum_b = 105 | sum_in_r = sum_in_g = sum_in_b = 106 | sum_out_r = sum_out_g = sum_out_b = 0; 107 | 108 | src_ptr = src + w4 * y; // start of line (0,y) 109 | 110 | for(i = 0; i <= radius; i++) 111 | { 112 | stack_ptr = &stack[ 3 * i ]; 113 | stack_ptr[0] = src_ptr[0]; 114 | stack_ptr[1] = src_ptr[1]; 115 | stack_ptr[2] = src_ptr[2]; 116 | sum_r += src_ptr[0] * (i + 1); 117 | sum_g += src_ptr[1] * (i + 1); 118 | sum_b += src_ptr[2] * (i + 1); 119 | sum_out_r += src_ptr[0]; 120 | sum_out_g += src_ptr[1]; 121 | sum_out_b += src_ptr[2]; 122 | } 123 | 124 | 125 | for(i = 1; i <= radius; i++) 126 | { 127 | if (i <= wm) src_ptr += 4; 128 | stack_ptr = &stack[ 3 * (i + radius) ]; 129 | stack_ptr[0] = src_ptr[0]; 130 | stack_ptr[1] = src_ptr[1]; 131 | stack_ptr[2] = src_ptr[2]; 132 | sum_r += src_ptr[0] * (radius + 1 - i); 133 | sum_g += src_ptr[1] * (radius + 1 - i); 134 | sum_b += src_ptr[2] * (radius + 1 - i); 135 | sum_in_r += src_ptr[0]; 136 | sum_in_g += src_ptr[1]; 137 | sum_in_b += src_ptr[2]; 138 | } 139 | 140 | 141 | sp = radius; 142 | xp = radius; 143 | if (xp > wm) xp = wm; 144 | src_ptr = src + 4 * (xp + y * w); // img.pix_ptr(xp, y); 145 | dst_ptr = src + y * w4; // img.pix_ptr(0, y); 146 | for(x = 0; x < w; x++) 147 | { 148 | int alpha = dst_ptr[3]; 149 | dst_ptr[0] = clamp((sum_r * mul_sum) >> shr_sum, 0, alpha); 150 | dst_ptr[1] = clamp((sum_g * mul_sum) >> shr_sum, 0, alpha); 151 | dst_ptr[2] = clamp((sum_b * mul_sum) >> shr_sum, 0, alpha); 152 | dst_ptr += 4; 153 | 154 | sum_r -= sum_out_r; 155 | sum_g -= sum_out_g; 156 | sum_b -= sum_out_b; 157 | 158 | stack_start = sp + div - radius; 159 | if (stack_start >= div) stack_start -= div; 160 | stack_ptr = &stack[3 * stack_start]; 161 | 162 | sum_out_r -= stack_ptr[0]; 163 | sum_out_g -= stack_ptr[1]; 164 | sum_out_b -= stack_ptr[2]; 165 | 166 | if(xp < wm) 167 | { 168 | src_ptr += 4; 169 | ++xp; 170 | } 171 | 172 | stack_ptr[0] = src_ptr[0]; 173 | stack_ptr[1] = src_ptr[1]; 174 | stack_ptr[2] = src_ptr[2]; 175 | 176 | sum_in_r += src_ptr[0]; 177 | sum_in_g += src_ptr[1]; 178 | sum_in_b += src_ptr[2]; 179 | sum_r += sum_in_r; 180 | sum_g += sum_in_g; 181 | sum_b += sum_in_b; 182 | 183 | ++sp; 184 | if (sp >= div) sp = 0; 185 | stack_ptr = &stack[sp*3]; 186 | 187 | sum_out_r += stack_ptr[0]; 188 | sum_out_g += stack_ptr[1]; 189 | sum_out_b += stack_ptr[2]; 190 | sum_in_r -= stack_ptr[0]; 191 | sum_in_g -= stack_ptr[1]; 192 | sum_in_b -= stack_ptr[2]; 193 | } 194 | 195 | } 196 | } 197 | 198 | // step 2 199 | if (step == 2) 200 | { 201 | int minX = core * w / cores; 202 | int maxX = (core + 1) * w / cores; 203 | 204 | for(x = minX; x < maxX; x++) 205 | { 206 | sum_r = sum_g = sum_b = 207 | sum_in_r = sum_in_g = sum_in_b = 208 | sum_out_r = sum_out_g = sum_out_b = 0; 209 | 210 | src_ptr = src + 4 * x; // x,0 211 | for(i = 0; i <= radius; i++) 212 | { 213 | stack_ptr = &stack[i * 3]; 214 | stack_ptr[0] = src_ptr[0]; 215 | stack_ptr[1] = src_ptr[1]; 216 | stack_ptr[2] = src_ptr[2]; 217 | sum_r += src_ptr[0] * (i + 1); 218 | sum_g += src_ptr[1] * (i + 1); 219 | sum_b += src_ptr[2] * (i + 1); 220 | sum_out_r += src_ptr[0]; 221 | sum_out_g += src_ptr[1]; 222 | sum_out_b += src_ptr[2]; 223 | } 224 | for(i = 1; i <= radius; i++) 225 | { 226 | if(i <= hm) src_ptr += w4; // +stride 227 | 228 | stack_ptr = &stack[3 * (i + radius)]; 229 | stack_ptr[0] = src_ptr[0]; 230 | stack_ptr[1] = src_ptr[1]; 231 | stack_ptr[2] = src_ptr[2]; 232 | sum_r += src_ptr[0] * (radius + 1 - i); 233 | sum_g += src_ptr[1] * (radius + 1 - i); 234 | sum_b += src_ptr[2] * (radius + 1 - i); 235 | sum_in_r += src_ptr[0]; 236 | sum_in_g += src_ptr[1]; 237 | sum_in_b += src_ptr[2]; 238 | } 239 | 240 | sp = radius; 241 | yp = radius; 242 | if (yp > hm) yp = hm; 243 | src_ptr = src + 4 * (x + yp * w); // img.pix_ptr(x, yp); 244 | dst_ptr = src + 4 * x; // img.pix_ptr(x, 0); 245 | for(y = 0; y < h; y++) 246 | { 247 | int alpha = dst_ptr[3]; 248 | dst_ptr[0] = clamp((sum_r * mul_sum) >> shr_sum, 0, alpha); 249 | dst_ptr[1] = clamp((sum_g * mul_sum) >> shr_sum, 0, alpha); 250 | dst_ptr[2] = clamp((sum_b * mul_sum) >> shr_sum, 0, alpha); 251 | dst_ptr += w4; 252 | 253 | sum_r -= sum_out_r; 254 | sum_g -= sum_out_g; 255 | sum_b -= sum_out_b; 256 | 257 | stack_start = sp + div - radius; 258 | if(stack_start >= div) stack_start -= div; 259 | stack_ptr = &stack[3 * stack_start]; 260 | 261 | sum_out_r -= stack_ptr[0]; 262 | sum_out_g -= stack_ptr[1]; 263 | sum_out_b -= stack_ptr[2]; 264 | 265 | if(yp < hm) 266 | { 267 | src_ptr += w4; // stride 268 | ++yp; 269 | } 270 | 271 | stack_ptr[0] = src_ptr[0]; 272 | stack_ptr[1] = src_ptr[1]; 273 | stack_ptr[2] = src_ptr[2]; 274 | 275 | sum_in_r += src_ptr[0]; 276 | sum_in_g += src_ptr[1]; 277 | sum_in_b += src_ptr[2]; 278 | sum_r += sum_in_r; 279 | sum_g += sum_in_g; 280 | sum_b += sum_in_b; 281 | 282 | ++sp; 283 | if (sp >= div) sp = 0; 284 | stack_ptr = &stack[sp*3]; 285 | 286 | sum_out_r += stack_ptr[0]; 287 | sum_out_g += stack_ptr[1]; 288 | sum_out_b += stack_ptr[2]; 289 | sum_in_r -= stack_ptr[0]; 290 | sum_in_g -= stack_ptr[1]; 291 | sum_in_b -= stack_ptr[2]; 292 | } 293 | } 294 | } 295 | } 296 | 297 | JNIEXPORT void JNICALL Java_net_robinx_lib_blurview_algorithm_ndk_NdkStackBlur_functionToBlur(JNIEnv* env, jclass clzz, jobject bitmapOut, jint radius, jint threadCount, jint threadIndex, jint round) { 298 | // Properties 299 | AndroidBitmapInfo infoOut; 300 | void* pixelsOut; 301 | 302 | int ret; 303 | 304 | // Get image info 305 | if ((ret = AndroidBitmap_getInfo(env, bitmapOut, &infoOut)) != 0) { 306 | LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 307 | return; 308 | } 309 | 310 | // Check image 311 | if (infoOut.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { 312 | LOGE("Bitmap format is not RGBA_8888!"); 313 | LOGE("==> %d", infoOut.format); 314 | return; 315 | } 316 | 317 | // Lock all images 318 | if ((ret = AndroidBitmap_lockPixels(env, bitmapOut, &pixelsOut)) != 0) { 319 | LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 320 | return; 321 | } 322 | 323 | int h = infoOut.height; 324 | int w = infoOut.width; 325 | 326 | stackblurJob((unsigned char*)pixelsOut, w, h, radius, threadCount, threadIndex, round); 327 | 328 | // Unlocks everything 329 | AndroidBitmap_unlockPixels(env, bitmapOut); 330 | } 331 | -------------------------------------------------------------------------------- /lib.blurview/src/main/jni/hold.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Robin on 2016/8/16. 3 | // 4 | 5 | #include "hold.h" 6 | -------------------------------------------------------------------------------- /lib.blurview/src/main/jni/hold.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Robin on 2016/8/16. 3 | // 4 | 5 | #ifndef BLUR_HOLD_H 6 | #define BLUR_HOLD_H 7 | 8 | 9 | class hold { 10 | 11 | }; 12 | 13 | 14 | #endif //BLUR_HOLD_H 15 | -------------------------------------------------------------------------------- /lib.blurview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Lib.BlurView 3 | 4 | -------------------------------------------------------------------------------- /lib.blurview/src/main/rs/contrast.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ip.rsh" 18 | 19 | static float brightM = 0.f; 20 | static float brightC = 0.f; 21 | 22 | void setBright(float v) { 23 | brightM = pow(2.f, v / 100.f); 24 | brightC = 127.f - brightM * 127.f; 25 | } 26 | 27 | void contrast(const uchar4 *in, uchar4 *out) 28 | { 29 | #if 0 30 | out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255); 31 | out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255); 32 | out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255); 33 | #else 34 | float3 v = convert_float3(in->rgb) * brightM + brightC; 35 | out->rgb = convert_uchar3(clamp(v, 0.f, 255.f)); 36 | #endif 37 | } -------------------------------------------------------------------------------- /lib.blurview/src/main/rs/ip.rsh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma version(1) 18 | #pragma rs java_package_name(at.favre.app.blurbenchmark) 19 | 20 | 21 | -------------------------------------------------------------------------------- /lib.blurview/src/main/rs/stackblur.rs: -------------------------------------------------------------------------------- 1 | #include "ip.rsh" 2 | #pragma rs_fp_inprecise 3 | 4 | static unsigned short const stackblur_mul[255] = 5 | { 6 | 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, 7 | 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, 8 | 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, 9 | 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, 10 | 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, 11 | 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, 12 | 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, 13 | 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, 14 | 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, 15 | 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, 16 | 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, 17 | 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, 18 | 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, 19 | 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, 20 | 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, 21 | 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 22 | }; 23 | 24 | static unsigned char const stackblur_shr[255] = 25 | { 26 | 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 27 | 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 28 | 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 29 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 30 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 31 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 32 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 34 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 35 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 36 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 37 | 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 38 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 39 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 40 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 41 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 42 | }; 43 | 44 | rs_allocation gIn; 45 | 46 | uint32_t width; 47 | uint32_t height; 48 | 49 | uint32_t radius; 50 | 51 | void __attribute__((kernel)) blur_v(uint32_t in) { 52 | uint x, y, xp, yp, i; 53 | uint sp; 54 | uint stack_start; 55 | uchar3* stack_ptr; 56 | 57 | uint32_t src_i; 58 | uint32_t dst_i; 59 | 60 | uint3 sum; 61 | uint3 sum_in; 62 | uint3 sum_out; 63 | uint3 sum_tmp; 64 | 65 | uchar3 inPixel; 66 | 67 | uint32_t wm = width - 1; 68 | uint32_t hm = height - 1; 69 | uint32_t div = (radius * 2) + 1; 70 | uint32_t mul_sum = stackblur_mul[radius]; 71 | uchar shr_sum = stackblur_shr[radius]; 72 | uchar3 stack[div]; 73 | 74 | x = in; 75 | sum = sum_in = sum_out = 0; 76 | 77 | src_i = x; // x,0 78 | for(i = 0; i <= radius; i++) 79 | { 80 | stack_ptr = &stack[i]; 81 | 82 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 83 | 84 | *stack_ptr = inPixel; 85 | 86 | sum_tmp = convert_uint3(inPixel); 87 | sum += sum_tmp * (i + 1); 88 | sum_out += sum_tmp; 89 | } 90 | for(i = 1; i <= radius; i++) 91 | { 92 | if(i <= hm) src_i += width; // +stride 93 | 94 | stack_ptr = &stack[i + radius]; 95 | 96 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 97 | 98 | *stack_ptr = inPixel; 99 | 100 | sum_tmp = convert_uint3(inPixel); 101 | sum += sum_tmp * (radius + 1 - i); 102 | sum_in += sum_tmp; 103 | } 104 | 105 | sp = radius; 106 | yp = radius; 107 | if (yp > hm) yp = hm; 108 | src_i = x + yp * width; // img.pix_ptr(x, yp); 109 | dst_i = x; // img.pix_ptr(x, 0); 110 | for(y = 0; y < height; y++) 111 | { 112 | uchar4 outPixel; 113 | outPixel.xyz = convert_uchar3((sum * mul_sum) >> shr_sum); 114 | outPixel.w = rsGetElementAt_uchar4(gIn, dst_i).w; 115 | outPixel = min(max(outPixel, 0), outPixel.w); 116 | rsSetElementAt_uchar4(gIn, outPixel, dst_i); 117 | dst_i += width; 118 | 119 | sum -= sum_out; 120 | 121 | stack_start = sp + div - radius; 122 | if(stack_start >= div) stack_start -= div; 123 | stack_ptr = &stack[stack_start]; 124 | 125 | sum_out -= convert_uint3(*stack_ptr); 126 | 127 | if(yp < hm) 128 | { 129 | src_i += width; // stride 130 | ++yp; 131 | } 132 | 133 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 134 | 135 | *stack_ptr = inPixel; 136 | 137 | sum_in += convert_uint3(inPixel); 138 | 139 | sum += sum_in; 140 | 141 | ++sp; 142 | if (sp >= div) sp = 0; 143 | stack_ptr = &stack[sp]; 144 | 145 | sum_tmp = convert_uint3(*stack_ptr); 146 | 147 | sum_out += sum_tmp; 148 | sum_in -= sum_tmp; 149 | } 150 | } 151 | 152 | void __attribute__((kernel)) blur_h(uint32_t in) { 153 | uint x, y, xp, yp, i; 154 | uint sp; 155 | uint stack_start; 156 | uchar3* stack_ptr; 157 | 158 | uint32_t src_i; 159 | uint32_t dst_i; 160 | 161 | uint3 sum; 162 | uint3 sum_in; 163 | uint3 sum_out; 164 | uint3 sum_tmp; 165 | 166 | uchar3 inPixel; 167 | 168 | uint32_t wm = width - 1; 169 | uint32_t hm = height - 1; 170 | uint32_t div = (radius * 2) + 1; 171 | uint32_t mul_sum = stackblur_mul[radius]; 172 | uchar shr_sum = stackblur_shr[radius]; 173 | uchar3 stack[div]; 174 | 175 | y = in; 176 | sum = sum_in = sum_out = 0; 177 | 178 | src_i = width * y; // start of line (0,y) 179 | 180 | for(i = 0; i <= radius; i++) 181 | { 182 | stack_ptr = &stack[ i ]; 183 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 184 | *stack_ptr = inPixel; 185 | sum_tmp = convert_uint3(inPixel); 186 | sum_out += sum_tmp; 187 | sum += sum_tmp * (i + 1); 188 | } 189 | 190 | 191 | for(i = 1; i <= radius; i++) 192 | { 193 | if (i <= wm) src_i += 1; 194 | stack_ptr = &stack[ (i + radius) ]; 195 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 196 | 197 | *stack_ptr = inPixel; 198 | sum_tmp = convert_uint3(inPixel); 199 | sum += sum_tmp * (radius + 1 - i); 200 | sum_in += sum_tmp; 201 | } 202 | 203 | sp = radius; 204 | xp = radius; 205 | if (xp > wm) xp = wm; 206 | src_i = xp + y * width; // img.pix_ptr(xp, y); 207 | dst_i = y * width; // img.pix_ptr(0, y); 208 | for(x = 0; x < width; x++) 209 | { 210 | uchar4 outPixel; 211 | outPixel.xyz = convert_uchar3((sum * mul_sum) >> shr_sum); 212 | outPixel.w = rsGetElementAt_uchar4(gIn, dst_i).w; 213 | outPixel = min(max(outPixel, 0), outPixel.w); 214 | 215 | rsSetElementAt_uchar4(gIn, outPixel, dst_i); 216 | dst_i += 1; 217 | 218 | sum -= sum_out; 219 | 220 | stack_start = sp + div - radius; 221 | if (stack_start >= div) stack_start -= div; 222 | stack_ptr = &stack[stack_start]; 223 | 224 | sum_out -= convert_uint3(*stack_ptr); 225 | 226 | if(xp < wm) 227 | { 228 | src_i += 1; 229 | ++xp; 230 | } 231 | 232 | inPixel = rsGetElementAt_uchar4(gIn, src_i).xyz; 233 | 234 | *stack_ptr = inPixel; 235 | sum_in += convert_uint3(inPixel); 236 | sum += sum_in; 237 | 238 | ++sp; 239 | if (sp >= div) sp = 0; 240 | stack_ptr = &stack[sp]; 241 | 242 | sum_out += convert_uint3(*stack_ptr); 243 | sum_in -= convert_uint3(*stack_ptr); 244 | } 245 | 246 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':lib.blurview' 2 | --------------------------------------------------------------------------------