├── .gitignore ├── .idea ├── gradle.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── ShimingImageBlur.c │ ├── com_shiming_imageloader_jnitest_JniUtils.cpp │ └── com_shiming_imageloader_jnitest_JniUtils.h ├── libs │ ├── armeabi-v7a │ │ └── libShimingImageBlur.so │ ├── armeabi │ │ └── libShimingImageBlur.so │ └── x86 │ │ └── libShimingImageBlur.so ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── shiming │ │ └── imageloader │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── shiming │ │ │ └── imageloader │ │ │ ├── GlideV4DemoActivity.java │ │ │ ├── ImageLoaderByNetActivity.java │ │ │ ├── JniImageByNetAndJniActivity.java │ │ │ ├── JniImageByNetNoJniActivity.java │ │ │ ├── JniImageBySDAndJniActivity.java │ │ │ ├── JniImageBySDNoJniActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MyApp.java │ │ │ └── jnitest │ │ │ └── JniUtils.java │ └── res │ │ ├── drawable │ │ └── blur_bg_mask_gradient_shape.xml │ │ ├── layout │ │ ├── activity_glide_v4_demo.xml │ │ ├── activity_image_loader.xml │ │ ├── activity_jni_image.xml │ │ ├── activity_jni_image_by_net_no_jni.xml │ │ ├── activity_jni_image_by_sd.xml │ │ ├── activity_jni_image_by_sd_no_jni.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── icon.jpg │ │ └── test.jpg │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── shiming │ └── imageloader │ └── ExampleUnitTest.java ├── build.gradle ├── build.gradle.bak ├── compresspic ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── shiming │ │ └── compresspic │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── shiming │ │ │ └── compresspic │ │ │ ├── BitmapUtil.java │ │ │ ├── CompressCore.java │ │ │ └── ImageCompress.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── shiming │ └── compresspic │ └── ExampleUnitTest.java ├── glide4.7.1demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── code │ │ └── shiming │ │ └── com │ │ └── glide471demo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── code │ │ │ └── shiming │ │ │ └── com │ │ │ └── glide471demo │ │ │ ├── DemoActivity.java │ │ │ ├── ImageProgressActivity.java │ │ │ ├── MainActivity.java │ │ │ └── TransitionOptionsActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_demo.xml │ │ ├── activity_image_progress.xml │ │ ├── activity_main.xml │ │ └── activity_transition_options.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── icon.jpg │ │ └── test.jpg │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── code │ └── shiming │ └── com │ └── glide471demo │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ ├── gradle-wrapper.properties │ └── gradle-wrapper.properties.bak ├── gradlew ├── gradlew.bat ├── imageloader4.7.1 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── code │ │ └── shiming │ │ └── com │ │ └── imageloader471 │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── code │ │ │ └── shiming │ │ │ └── com │ │ │ └── imageloader471 │ │ │ ├── AppGlideModuleProgress.java │ │ │ ├── ExternalDiskCacheFactory.java │ │ │ ├── GlideImageLoaderClient.java │ │ │ ├── IImageLoaderClient.java │ │ │ ├── ImageLoaderV4.java │ │ │ ├── listener │ │ │ ├── IGetBitmapListener.java │ │ │ ├── IGetDrawableListener.java │ │ │ ├── IImageLoaderListener.java │ │ │ └── ImageSize.java │ │ │ ├── okhttp │ │ │ ├── OnGlideImageViewListener.java │ │ │ ├── OnProgressListener.java │ │ │ ├── ProgressManager.java │ │ │ └── ProgressResponseBody.java │ │ │ └── tranform │ │ │ ├── BlurBitmapTranformation.java │ │ │ ├── GlideCircleTransformation.java │ │ │ └── RoundBitmapTranformation.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── code │ └── shiming │ └── com │ └── imageloader471 │ └── ExampleUnitTest.java ├── imageloaderlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── imageloader │ │ └── shiming │ │ └── com │ │ └── imageloaderlibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── iamgeloader │ │ │ └── client │ │ │ ├── GlideImageLoaderClient.java │ │ │ ├── IImageLoaderClient.java │ │ │ ├── ImageLoader.java │ │ │ ├── listener │ │ │ ├── IGetBitmapListenerByCall.java │ │ │ ├── IGetDrawableListenerByCall.java │ │ │ ├── IImageLoaderListenerByCall.java │ │ │ └── ImageSizeTwo.java │ │ │ └── tranform │ │ │ ├── BlurBitmapTransformationDD.java │ │ │ ├── CircleBitmapTransformationDD.java │ │ │ ├── GlideTransformD.java │ │ │ ├── IBitmapTransformationD.java │ │ │ └── RoundBitmapTransformationD.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── imageloader │ └── shiming │ └── com │ └── imageloaderlibrary │ └── ExampleUnitTest.java └── 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 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 24 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 1.8 50 | 51 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.shiming.imageloader" 8 | minSdkVersion 15 9 | targetSdkVersion 27 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | //ndk编译生成.so文件 14 | // 只要是第一次生成了so库的文件,那么以后就不用生成这个文件,记住一定要记住,如果需要生成so文件 15 | //需要把外面的目录的jni移动到和mian目录下和Java同级的目录下 16 | // ndk { 17 | // moduleName "ShimingImageBlur" //生成的so名字 18 | // abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。 19 | // } 20 | } 21 | sourceSets.main { 22 | jniLibs.srcDirs = ['libs'] 23 | } 24 | sourceSets { 25 | main { 26 | aidl.srcDirs = ['src/main/java'] 27 | assets.srcDirs = ['assets'] 28 | jniLibs.srcDirs = ['libs'] 29 | } 30 | } 31 | buildTypes { 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | 38 | } 39 | 40 | dependencies { 41 | compile fileTree(dir: 'libs', include: ['*.jar']) 42 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 43 | exclude group: 'com.android.support', module: 'support-annotations' 44 | }) 45 | compile project(':imageloaderlibrary') 46 | 47 | //noinspection GradleCompatible 48 | compile 'com.android.support:appcompat-v7:27.0.0' 49 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 50 | testCompile 'junit:junit:4.12' 51 | //依赖图片压缩的 jni 52 | // compile project(':compresspic') 53 | } 54 | -------------------------------------------------------------------------------- /app/jni/Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | LOCAL_PATH := $(call my-dir) 16 | 17 | include $(CLEAR_VARS) 18 | #编译生成的文件的类库叫什么名字 19 | LOCAL_MODULE := ShimingImageBlur 20 | #要编译的c文件 21 | LOCAL_SRC_FILES := com_shiming_imageloader_jnitest_JniUtils.cpp 22 | 23 | include $(BUILD_SHARED_LIBRARY) 24 | -------------------------------------------------------------------------------- /app/jni/Application.mk: -------------------------------------------------------------------------------- 1 | #jni打包的C语言类库默认仅支持 arm架构,需要在jni目录下创建 Android.mk 文件添加如下代码可以支持x86架构 2 | #或者是 :=all 3 | APP_ABI :=armeabi armeabi-v7a x86 -------------------------------------------------------------------------------- /app/jni/ShimingImageBlur.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ABS(a) ((a)<(0)?(-a):(a)) 4 | #define MAX(a,b) ((a)>(b)?(a):(b)) 5 | #define MIN(a,b) ((a)<(b)?(a):(b)) 6 | 7 | 8 | static int* StackBlur(int* pix, int w, int h, int radius) { 9 | int wm = w - 1; 10 | int hm = h - 1; 11 | int wh = w * h; 12 | int div = radius + radius + 1; 13 | // 指针 14 | int *r = (int *)malloc(wh * sizeof(int)); 15 | int *g = (int *)malloc(wh * sizeof(int)); 16 | int *b = (int *)malloc(wh * sizeof(int)); 17 | int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; 18 | 19 | int *vmin = (int *)malloc(MAX(w,h) * sizeof(int)); 20 | 21 | int divsum = (div + 1) >> 1; 22 | divsum *= divsum; 23 | int *dv = (int *)malloc(256 * divsum * sizeof(int)); 24 | for (i = 0; i < 256 * divsum; i++) { 25 | dv[i] = (i / divsum); 26 | } 27 | 28 | yw = yi = 0; 29 | 30 | int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int)); 31 | int stackpointer; 32 | int stackstart; 33 | int *sir; 34 | int rbs; 35 | int r1 = radius + 1; 36 | int routsum, goutsum, boutsum; 37 | int rinsum, ginsum, binsum; 38 | 39 | for (y = 0; y < h; y++) { 40 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 41 | for (i = -radius; i <= radius; i++) { 42 | p = pix[yi + (MIN(wm, MAX(i, 0)))]; 43 | sir = stack[i + radius]; 44 | sir[0] = (p & 0xff0000) >> 16; 45 | sir[1] = (p & 0x00ff00) >> 8; 46 | sir[2] = (p & 0x0000ff); 47 | 48 | rbs = r1 - ABS(i); 49 | rsum += sir[0] * rbs; 50 | gsum += sir[1] * rbs; 51 | bsum += sir[2] * rbs; 52 | if (i > 0) { 53 | rinsum += sir[0]; 54 | ginsum += sir[1]; 55 | binsum += sir[2]; 56 | } 57 | else { 58 | routsum += sir[0]; 59 | goutsum += sir[1]; 60 | boutsum += sir[2]; 61 | } 62 | } 63 | stackpointer = radius; 64 | 65 | for (x = 0; x < w; x++) { 66 | 67 | r[yi] = dv[rsum]; 68 | g[yi] = dv[gsum]; 69 | b[yi] = dv[bsum]; 70 | 71 | rsum -= routsum; 72 | gsum -= goutsum; 73 | bsum -= boutsum; 74 | 75 | stackstart = stackpointer - radius + div; 76 | sir = stack[stackstart % div]; 77 | 78 | routsum -= sir[0]; 79 | goutsum -= sir[1]; 80 | boutsum -= sir[2]; 81 | 82 | if (y == 0) { 83 | vmin[x] = MIN(x + radius + 1, wm); 84 | } 85 | p = pix[yw + vmin[x]]; 86 | 87 | sir[0] = (p & 0xff0000) >> 16; 88 | sir[1] = (p & 0x00ff00) >> 8; 89 | sir[2] = (p & 0x0000ff); 90 | 91 | rinsum += sir[0]; 92 | ginsum += sir[1]; 93 | binsum += sir[2]; 94 | 95 | rsum += rinsum; 96 | gsum += ginsum; 97 | bsum += binsum; 98 | 99 | stackpointer = (stackpointer + 1) % div; 100 | sir = stack[(stackpointer) % div]; 101 | 102 | routsum += sir[0]; 103 | goutsum += sir[1]; 104 | boutsum += sir[2]; 105 | 106 | rinsum -= sir[0]; 107 | ginsum -= sir[1]; 108 | binsum -= sir[2]; 109 | 110 | yi++; 111 | } 112 | yw += w; 113 | } 114 | for (x = 0; x < w; x++) { 115 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 116 | yp = -radius * w; 117 | for (i = -radius; i <= radius; i++) { 118 | yi = MAX(0, yp) + x; 119 | 120 | sir = stack[i + radius]; 121 | 122 | sir[0] = r[yi]; 123 | sir[1] = g[yi]; 124 | sir[2] = b[yi]; 125 | 126 | rbs = r1 - ABS(i); 127 | 128 | rsum += r[yi] * rbs; 129 | gsum += g[yi] * rbs; 130 | bsum += b[yi] * rbs; 131 | 132 | if (i > 0) { 133 | rinsum += sir[0]; 134 | ginsum += sir[1]; 135 | binsum += sir[2]; 136 | } 137 | else { 138 | routsum += sir[0]; 139 | goutsum += sir[1]; 140 | boutsum += sir[2]; 141 | } 142 | 143 | if (i < hm) { 144 | yp += w; 145 | } 146 | } 147 | yi = x; 148 | stackpointer = radius; 149 | for (y = 0; y < h; y++) { 150 | // Preserve alpha channel: ( 0xff000000 & pix[yi] ) 151 | pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; 152 | 153 | rsum -= routsum; 154 | gsum -= goutsum; 155 | bsum -= boutsum; 156 | 157 | stackstart = stackpointer - radius + div; 158 | sir = stack[stackstart % div]; 159 | 160 | routsum -= sir[0]; 161 | goutsum -= sir[1]; 162 | boutsum -= sir[2]; 163 | 164 | if (x == 0) { 165 | vmin[y] = MIN(y + r1, hm) * w; 166 | } 167 | p = x + vmin[y]; 168 | 169 | sir[0] = r[p]; 170 | sir[1] = g[p]; 171 | sir[2] = b[p]; 172 | 173 | rinsum += sir[0]; 174 | ginsum += sir[1]; 175 | binsum += sir[2]; 176 | 177 | rsum += rinsum; 178 | gsum += ginsum; 179 | bsum += binsum; 180 | 181 | stackpointer = (stackpointer + 1) % div; 182 | sir = stack[stackpointer]; 183 | 184 | routsum += sir[0]; 185 | goutsum += sir[1]; 186 | boutsum += sir[2]; 187 | 188 | rinsum -= sir[0]; 189 | ginsum -= sir[1]; 190 | binsum -= sir[2]; 191 | 192 | yi += w; 193 | } 194 | } 195 | //记得要释放掉 196 | free(r); 197 | free(g); 198 | free(b); 199 | free(vmin); 200 | free(dv); 201 | free(stack); 202 | return(pix); 203 | } 204 | -------------------------------------------------------------------------------- /app/jni/com_shiming_imageloader_jnitest_JniUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "com_shiming_imageloader_jnitest_JniUtils.h" 2 | #include "ShimingImageBlur.c" 3 | #include 4 | 5 | //用c++实现的,方法名必须为本地方法的全类名改为下划线 6 | //第一个参数为java虚拟机的内存地址的二级指正,用于本地方法与java虚拟机在内存中的交互 7 | //第二个参数为一个java对象,即是那个对象调用了这个c的方法 , 8 | //后面的参数就是我们java的方法参数 9 | JNIEXPORT void JNICALL Java_com_shiming_imageloader_jnitest_JniUtils_blurIntArray 10 | (JNIEnv *env, jclass obj, jintArray arrIn, jint w, jint h, jint r) 11 | { 12 | jint *pix; 13 | pix = env->GetIntArrayElements(arrIn, 0); 14 | if (pix == NULL) 15 | return; 16 | //Start 17 | pix = StackBlur(pix, w, h, r); 18 | //End 19 | //int size = w * h; 20 | //jintArray result = env->NewIntArray(size); 21 | //env->SetIntArrayRegion(result, 0, size, pix); 22 | env->ReleaseIntArrayElements(arrIn, pix, 0); 23 | //return result; 24 | } 25 | -------------------------------------------------------------------------------- /app/jni/com_shiming_imageloader_jnitest_JniUtils.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_shiming_imageloader_jni_JniUtils */ 4 | 5 | #ifndef _Included_com_shiming_imageloader_jnitest_JniUtils 6 | #define _Included_com_shiming_imageloader_jnitest_JniUtils 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: Java_com_shiming_imageloader_jnitest_JniUtils 12 | * Method: blurIntArray 13 | * Signature: ([IIII)V 14 | * 可千万要加上 Java_的前缀 ,要不然找不到啊 15 | */ 16 | 17 | JNIEXPORT void JNICALL Java_com_shiming_imageloader_jnitest_JniUtils_blurIntArray 18 | (JNIEnv *, jclass, jintArray, jint, jint, jint); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | #endif 24 | -------------------------------------------------------------------------------- /app/libs/armeabi-v7a/libShimingImageBlur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shimingli/ImageLoader/0805ba9384d2836e6c5a6af2bafa431d6e8b01dc/app/libs/armeabi-v7a/libShimingImageBlur.so -------------------------------------------------------------------------------- /app/libs/armeabi/libShimingImageBlur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shimingli/ImageLoader/0805ba9384d2836e6c5a6af2bafa431d6e8b01dc/app/libs/armeabi/libShimingImageBlur.so -------------------------------------------------------------------------------- /app/libs/x86/libShimingImageBlur.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shimingli/ImageLoader/0805ba9384d2836e6c5a6af2bafa431d6e8b01dc/app/libs/x86/libShimingImageBlur.so -------------------------------------------------------------------------------- /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 E:\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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/shiming/imageloader/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.shiming.imageloader", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/GlideV4DemoActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.widget.ImageView; 6 | 7 | public class GlideV4DemoActivity extends AppCompatActivity { 8 | private ImageView mImageView_1; 9 | private ImageView mImageView_2; 10 | private ImageView mImageView_3; 11 | private ImageView mImageView_4; 12 | private ImageView mImageView_5; 13 | private ImageView mImageView_6; 14 | private ImageView mImageView_7; 15 | private ImageView mImageView_8; 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_glide_v4_demo); 20 | findView(); 21 | // // //圆形图片 22 | // ImageLoaderV4.getInstance().displayCircleImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_1, R.mipmap.ic_launcher_round); 23 | // //圆角图片 24 | // ImageLoaderV4.getInstance().displayRoundImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_2, R.mipmap.ic_launcher_round, 40); 25 | // //模糊图片 26 | // ImageLoaderV4.getInstance().displayBlurImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_3, R.mipmap.ic_launcher_round, 10); 27 | // 28 | // //本地图片 不做处理 29 | // ImageLoaderV4.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_4); 30 | // //本地图片,模糊处理 31 | // ImageLoaderV4.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_5, new BlurBitmapTranformation( 200)); 32 | // //本地图片,裁圆角处理 33 | // ImageLoaderV4.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_6, new GlideCircleTransformation()); 34 | // //四周倒角处理 35 | // ImageLoaderV4.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_7, new RoundBitmapTranformation( 40)); 36 | } 37 | 38 | private void findView() { 39 | mImageView_1 = (ImageView) findViewById(R.id.image_view_1); 40 | mImageView_2 = (ImageView) findViewById(R.id.image_view_2); 41 | mImageView_3 = (ImageView) findViewById(R.id.image_view_3); 42 | mImageView_4 = (ImageView) findViewById(R.id.image_view_4); 43 | mImageView_5 = (ImageView) findViewById(R.id.image_view_5); 44 | mImageView_6 = (ImageView) findViewById(R.id.image_view_6); 45 | mImageView_7 = (ImageView) findViewById(R.id.image_view_7); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/ImageLoaderByNetActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.graphics.BitmapShader; 6 | import android.graphics.Canvas; 7 | import android.graphics.Matrix; 8 | import android.graphics.Paint; 9 | import android.os.Bundle; 10 | import android.support.annotation.Nullable; 11 | import android.support.v4.app.FragmentActivity; 12 | import android.widget.ImageView; 13 | 14 | import iamgeloader.client.ImageLoader; 15 | import iamgeloader.client.tranform.BlurBitmapTransformationDD; 16 | import iamgeloader.client.tranform.CircleBitmapTransformationDD; 17 | import iamgeloader.client.tranform.RoundBitmapTransformationD; 18 | 19 | 20 | /** 21 | * @author shiming 22 | * @version v1.0 create at 2017/9/26 23 | * @des 通过imageloader 处理图片 24 | */ 25 | public class ImageLoaderByNetActivity extends FragmentActivity { 26 | 27 | 28 | private ImageView mImageView_1; 29 | private ImageView mImageView_2; 30 | private ImageView mImageView_3; 31 | private ImageView mImageView_4; 32 | private ImageView mImageView_5; 33 | private ImageView mImageView_6; 34 | private ImageView mImageView_7; 35 | private ImageView mImageView_8; 36 | 37 | @Override 38 | protected void onCreate(@Nullable Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | setContentView(R.layout.activity_image_loader); 41 | findView(); 42 | loadData(); 43 | } 44 | 45 | private void loadData() { 46 | //圆形图片 47 | ImageLoader.getInstance().displayCircleImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_1, R.mipmap.ic_launcher_round); 48 | //圆角图片 49 | ImageLoader.getInstance().displayRoundImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_2, R.mipmap.ic_launcher_round, 40); 50 | //模糊图片 51 | ImageLoader.getInstance().displayBlurImage(this, "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg", mImageView_3, R.mipmap.ic_launcher_round, 100); 52 | 53 | //本地图片 不做处理 54 | ImageLoader.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_4); 55 | //本地图片,模糊处理 56 | ImageLoader.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_5, new BlurBitmapTransformationDD(this, 200)); 57 | //本地图片,裁圆角处理 58 | ImageLoader.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_6, new CircleBitmapTransformationDD(this)); 59 | //四周倒角处理 60 | ImageLoader.getInstance().displayImageInResource(this, R.mipmap.test, mImageView_7, new RoundBitmapTransformationD(this, 40)); 61 | //通过代码实现裁剪为圆形图片 62 | drawCicriBitmap(); 63 | 64 | } 65 | 66 | private void drawCicriBitmap() { 67 | Bitmap source = BitmapFactory.decodeResource(getResources(), R.mipmap.icon); 68 | int size = Math.min(source.getWidth(), source.getHeight()); 69 | int width = (source.getWidth() - size) / 2; 70 | int height = (source.getHeight() - size) / 2; 71 | Bitmap target = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_4444); 72 | Canvas canvas = new Canvas(target); 73 | Paint paint = new Paint(); 74 | // Call this to create a new shader that will draw with a bitmap. 75 | BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); 76 | if (width != 0 || height != 0) { 77 | Matrix matrix = new Matrix(); 78 | matrix.setTranslate(-width, -height); 79 | shader.setLocalMatrix(matrix); 80 | } 81 | paint.setShader(shader); 82 | paint.setAntiAlias(true); 83 | float r = size / 2f; 84 | canvas.drawCircle(r, r, r, paint); 85 | mImageView_8.setImageBitmap(target); 86 | } 87 | 88 | private void findView() { 89 | mImageView_1 = (ImageView) findViewById(R.id.image_view_1); 90 | mImageView_2 = (ImageView) findViewById(R.id.image_view_2); 91 | mImageView_3 = (ImageView) findViewById(R.id.image_view_3); 92 | mImageView_4 = (ImageView) findViewById(R.id.image_view_4); 93 | mImageView_5 = (ImageView) findViewById(R.id.image_view_5); 94 | mImageView_6 = (ImageView) findViewById(R.id.image_view_6); 95 | mImageView_7 = (ImageView) findViewById(R.id.image_view_7); 96 | mImageView_8 = (ImageView) findViewById(R.id.image_view_8); 97 | } 98 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/JniImageByNetAndJniActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.widget.ImageView; 7 | 8 | 9 | import com.shiming.imageloader.jnitest.JniUtils; 10 | 11 | import iamgeloader.client.ImageLoader; 12 | import iamgeloader.client.listener.IGetBitmapListenerByCall; 13 | 14 | 15 | /** 16 | * @author shiming 17 | * @version v1.0 create at 2017/9/26 18 | * @des 通过jni实现的高斯模糊图片 19 | */ 20 | public class JniImageByNetAndJniActivity extends AppCompatActivity { 21 | 22 | private ImageView mImageView_1; 23 | private ImageView mImageView_2; 24 | private String mUrl; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_jni_image); 30 | findView(); 31 | mUrl = "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg"; 32 | initData(); 33 | JniUtils.test(); 34 | } 35 | 36 | private void initData() { 37 | JniUtils.loadBlurImg(this,mUrl,mImageView_2,true); 38 | ImageLoader.getInstance().getBitmapFromCache(this, mUrl, new IGetBitmapListenerByCall() { 39 | @Override 40 | public void onBitmap(Bitmap bitmap) { 41 | mImageView_1.setImageBitmap(bitmap); 42 | } 43 | }); 44 | } 45 | 46 | private void findView() { 47 | mImageView_1 = (ImageView) findViewById(R.id.image_view_1); 48 | mImageView_2 = (ImageView) findViewById(R.id.image_view_2); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/JniImageByNetNoJniActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.FragmentActivity; 6 | import android.widget.ImageView; 7 | 8 | import com.shiming.imageloader.jnitest.JniUtils; 9 | 10 | import iamgeloader.client.ImageLoader; 11 | 12 | 13 | /** 14 | * @author shiming 15 | * @version v1.0 create at 2017/9/27 16 | * @des 通过网络获取图片没有使用到jni里面的算法 17 | */ 18 | public class JniImageByNetNoJniActivity extends FragmentActivity{ 19 | 20 | private ImageView mImageView_1; 21 | private ImageView mImageView_2; 22 | private String mUrl; 23 | 24 | @Override 25 | protected void onCreate(@Nullable Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_jni_image_by_net_no_jni); 28 | findView(); 29 | mUrl = "http://imgsrc.baidu.com/imgad/pic/item/267f9e2f07082838b5168c32b299a9014c08f1f9.jpg"; 30 | initData(); 31 | JniUtils.test(); 32 | } 33 | 34 | private void initData() { 35 | JniUtils.loadBlurImg(this,mUrl,mImageView_1,false); 36 | ImageLoader.getInstance().displayImage(this,mUrl,mImageView_2); 37 | } 38 | 39 | private void findView() { 40 | mImageView_1 = (ImageView) findViewById(R.id.image_view_1); 41 | mImageView_2 = (ImageView) findViewById(R.id.image_view_2); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/JniImageBySDAndJniActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.FragmentActivity; 6 | import android.widget.ImageView; 7 | 8 | import com.shiming.imageloader.jnitest.JniUtils; 9 | 10 | import iamgeloader.client.ImageLoader; 11 | 12 | 13 | /** 14 | * @author shiming 15 | * @version v1.0 create at 2017/9/26 16 | * @des 获取本地了图片,使用了jni里面的算法 17 | */ 18 | public class JniImageBySDAndJniActivity extends FragmentActivity { 19 | 20 | private ImageView mImageView; 21 | private ImageView mImageView2; 22 | 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_jni_image_by_sd); 27 | mImageView = (ImageView) findViewById(R.id.image_view_1); 28 | mImageView2 = (ImageView) findViewById(R.id.image_view_2); 29 | mImageView.setImageResource(R.mipmap.icon); 30 | JniUtils.applyBlur(mImageView,true); 31 | ImageLoader.getInstance().displayImage(this,R.mipmap.icon,mImageView2); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/JniImageBySDNoJniActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.FragmentActivity; 6 | import android.widget.ImageView; 7 | 8 | import com.shiming.imageloader.jnitest.JniUtils; 9 | 10 | import iamgeloader.client.ImageLoader; 11 | 12 | 13 | /** 14 | * @author shiming 15 | * @version v1.0 create at 2017/9/27 16 | * @des 我是没有使用jni里面算法实现的高斯模糊,通过本地获取的图片" 17 | 18 | */ 19 | public class JniImageBySDNoJniActivity extends FragmentActivity { 20 | 21 | private ImageView mImageView; 22 | private ImageView mImageView2; 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_jni_image_by_sd_no_jni); 27 | mImageView = (ImageView) findViewById(R.id.image_view_1); 28 | mImageView2 = (ImageView) findViewById(R.id.image_view_2); 29 | mImageView.setImageResource(R.mipmap.icon); 30 | JniUtils.applyBlur(mImageView,false); 31 | ImageLoader.getInstance().displayImage(this,R.mipmap.icon,mImageView2); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 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 | 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_main); 16 | findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() { 17 | @Override 18 | public void onClick(View v) { 19 | startActivity(new Intent(MainActivity.this,JniImageByNetAndJniActivity.class)); 20 | } 21 | }); 22 | 23 | findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() { 24 | @Override 25 | public void onClick(View v) { 26 | startActivity(new Intent(MainActivity.this,ImageLoaderByNetActivity.class)); 27 | } 28 | }); 29 | findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | startActivity(new Intent(MainActivity.this,JniImageBySDAndJniActivity.class)); 33 | } 34 | }); 35 | findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() { 36 | @Override 37 | public void onClick(View v) { 38 | startActivity(new Intent(MainActivity.this,JniImageByNetNoJniActivity.class)); 39 | } 40 | }); 41 | findViewById(R.id.btn5).setOnClickListener(new View.OnClickListener() { 42 | @Override 43 | public void onClick(View v) { 44 | startActivity(new Intent(MainActivity.this,JniImageBySDNoJniActivity.class)); 45 | } 46 | }); 47 | 48 | findViewById(R.id.btn6).setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | startActivity(new Intent(MainActivity.this,GlideV4DemoActivity.class)); 52 | } 53 | }); 54 | 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/MyApp.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | 7 | 8 | /** 9 | * @author shiming 10 | * @version v1.0 create at 2017/9/26 11 | * @des 12 | */ 13 | public class MyApp extends Application { 14 | 15 | private static Context mInstance; 16 | 17 | public static Context getInstance() { 18 | return mInstance; 19 | } 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | mInstance=this; 25 | //方法失效了 这个还没有成功尝试 26 | // CompressCore compressCore = new CompressCore(); 27 | 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/shiming/imageloader/jnitest/JniUtils.java: -------------------------------------------------------------------------------- 1 | package com.shiming.imageloader.jnitest; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Canvas; 6 | import android.graphics.Paint; 7 | import android.graphics.drawable.BitmapDrawable; 8 | import android.view.View; 9 | import android.view.ViewTreeObserver; 10 | import android.widget.ImageView; 11 | 12 | import com.shiming.imageloader.MyApp; 13 | 14 | import java.util.ArrayList; 15 | 16 | import iamgeloader.client.ImageLoader; 17 | import iamgeloader.client.listener.IGetBitmapListenerByCall; 18 | 19 | 20 | /** 21 | * @author shiming 22 | * @version v1.0 create at 2017/9/26 23 | * @des 24 | */ 25 | public class JniUtils { 26 | 27 | private final static float DEFAULT_BLUR_FACTOR = 7f; //模糊因子 越大越模糊 28 | 29 | private final static float DEFAULT_BLUR_RADIUS = 2f; //模糊半径 30 | //此处命名要和com_shiming_imageloader_jnitest_JniUtils.cpp 中的一样才可以 出错一步没得商量,要不断的检查 31 | public static native void blurIntArray(int[] pImg, int w, int h, int r); 32 | 33 | /** 34 | * 参照:MediaPlayer的写法 35 | static { 36 | System.loadLibrary("media_jni"); 37 | native_init(); 38 | } 39 | */ 40 | static { 41 | /** 42 | * #编译生成的文件的类库叫什么名字 43 | LOCAL_MODULE := ShimingImageBlur 44 | 必须和Android.mk中的一样,生成的so库虽然会加上libShimingImageBlur.so 但是调用得到 45 | */ 46 | System.loadLibrary("ShimingImageBlur"); 47 | 48 | } 49 | 50 | /** 51 | * 已设置图片的view模糊 可设置其他view的background 52 | * 53 | * @param view 54 | */ 55 | public static void applyBlur(final View view, final boolean flag) { 56 | // Register a callback to be invoked when the view tree is about to be drawn 57 | //翻译注册一个回调,view将要drawn,意思还没有drawn上去 58 | view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 59 | /** 60 | * 再绘图前加上 61 | * @return 62 | */ 63 | @Override 64 | public boolean onPreDraw() { 65 | view.getViewTreeObserver().removeOnPreDrawListener(this); 66 | //buildDrawingCache(false); 67 | //如果绘制无效,则强制构建绘图缓存, 68 | view.buildDrawingCache(); 69 | 70 | Bitmap bmp = view.getDrawingCache(); 71 | blur(bmp, view,flag); 72 | //通常cache会占用一定量的内存,所以必须销毁 73 | view.destroyDrawingCache(); 74 | //返回 true 继续绘制,返回false取消。 如果返回为false的,页面就不会绘制了 75 | return true; 76 | } 77 | }); 78 | } 79 | 80 | /** 81 | * 模糊图片 82 | * @param blurFactor 模糊因子 83 | * @param blurRadius 模糊半径 84 | * @param bitmap 图片 85 | * @param view view 86 | * @param flag 是否需要jni里面的算法 87 | */ 88 | public static void blur(float blurFactor, float blurRadius, Bitmap bitmap, final View view, boolean flag) { 89 | 90 | Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasuredWidth() / blurFactor), 91 | (int) (view.getMeasuredHeight() / blurFactor), Bitmap.Config.ARGB_8888); 92 | overlay.getHeight(); 93 | overlay.getWidth(); 94 | Canvas canvas = new Canvas(overlay); 95 | //如果我们需要放大1倍,即 scale(2, 2);缩放的中心点默认也是canvas的左上角,所以先要进行坐标平移,才能去缩放 96 | //平移,将画布的坐标原点向左右方向移动x,向上下方向移动y.canvas的默认位置是在(0,0) 97 | canvas.translate(-view.getLeft() / blurFactor, -view.getTop() / blurFactor); 98 | canvas.scale(1 / blurFactor, 1 / blurFactor); 99 | Paint paint = new Paint(); 100 | //抗锯齿 101 | paint.setFlags(Paint.FILTER_BITMAP_FLAG); 102 | canvas.drawBitmap(bitmap, 0, 0, paint); 103 | //这里的overlay已经包含了信息 104 | //是否需要jni的计算 105 | if (flag) { 106 | overlay = doBlurJniArray(overlay, (int) blurRadius, true); 107 | } 108 | //可以简单地理解为 Bitmap 储存的是 像素信息,Drawable 储存的是 对 Canvas 的一系列操作。 109 | //而 BitmapDrawable 储存的是「把 Bitmap 渲染到 Canvas 上」这个操作。 110 | BitmapDrawable blurDrawable = new BitmapDrawable(MyApp.getInstance().getApplicationContext() 111 | .getResources(), overlay); 112 | if (view instanceof ImageView) { 113 | ((ImageView)view).setImageDrawable(blurDrawable); 114 | System.out.println("shiming blurDrawable" +blurDrawable); 115 | } else { 116 | view.setBackgroundDrawable(blurDrawable); 117 | } 118 | } 119 | 120 | /** 121 | * 模糊图片 122 | * @param bitmap 123 | * @param view 124 | * @param flag 是否需要jni来模糊 125 | */ 126 | public static void blur(Bitmap bitmap, View view,boolean flag) { 127 | blur(DEFAULT_BLUR_FACTOR, DEFAULT_BLUR_RADIUS, bitmap, view,flag); 128 | } 129 | 130 | 131 | /** 132 | * 模糊网络图片 133 | * 134 | * @param context 135 | * @param url 136 | * @param imageView 137 | */ 138 | public static void loadBlurImg(Context context, String url, final ImageView imageView, final boolean flag) { 139 | ImageLoader.getInstance().getBitmapFromCache(context, url, new IGetBitmapListenerByCall() { 140 | @Override 141 | public void onBitmap(Bitmap bitmap) { 142 | imageView.setImageBitmap(bitmap); 143 | applyBlur(imageView,flag); 144 | } 145 | }); 146 | } 147 | 148 | /** 149 | * 150 | * @param sentBitmap 151 | * @param radius 152 | * @param canReuseInBitmap 153 | * @return 154 | * 155 | 参数 :http://ranlic.iteye.com/blog/1313735 156 | pixels 接收位图颜色值的数组 157 | offset 写入到pixels[]中的第一个像素索引值 158 | stride pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数 159 | x  从位图中读取的第一个像素的x坐标值。 160 | y 从位图中读取的第一个像素的y坐标值 161 | width   从每一行中读取的像素宽度 162 | height    读取的行数 163 | 异常 164 | IilegalArgumentExcepiton 如果x,y,width,height越界或stride的绝对值小于位图宽度时将被抛出。 165 | ArrayIndexOutOfBoundsException 如果像素数组太小而无法接收指定书目的像素值时将被抛出。 166 | */ 167 | private static Bitmap doBlurJniArray(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { 168 | Bitmap bitmap; 169 | if (canReuseInBitmap) { 170 | bitmap = sentBitmap; 171 | } else { 172 | bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); 173 | } 174 | 175 | if (radius < 1) { 176 | return (null); 177 | } 178 | int w = bitmap.getWidth(); 179 | int h = bitmap.getHeight(); 180 | int[] pix = new int[w * h]; 181 | bitmap.getPixels(pix, 0, w, 0, 0, w, h); 182 | //pix数组,所有的关键的逻辑都是这个pix的操作,这里我们去交给了so.库去处理了,所以这里才是关键 183 | JniUtils.blurIntArray(pix, w, h, radius); 184 | bitmap.setPixels(pix, 0, w, 0, 0, w, h); 185 | return (bitmap); 186 | } 187 | 188 | /** 189 | * Copy on write array. This array is not thread safe, and only one loop can 190 | * iterate over this array at any given time. This class avoids allocations 191 | * until a concurrent modification happens. 192 | * 193 | * 复制一个集合,线程不安全。只能有一个线程能够loop便利,但是这类能够避免并发修改的发生,如果出现了 194 | * 并发修改的了,马上抛出异常 195 | */ 196 | public static void test(){ 197 | final CopyOnWriteArray listeners = 198 | new CopyOnWriteArray<>(); 199 | listeners.add("1"); 200 | listeners.add("2"); 201 | listeners.add("3"); 202 | listeners.add("4"); 203 | listeners.add("5"); 204 | if (listeners != null && listeners.size() > 0) { 205 | CopyOnWriteArray.Access access = listeners.start(); 206 | try { 207 | int count = access.size(); 208 | for (int i = 0; i < count; i++) { 209 | String s = access.get(i); 210 | System.out.println("shiming==="+s); 211 | } 212 | } finally { 213 | listeners.end(); 214 | } 215 | } 216 | } 217 | 218 | static class CopyOnWriteArray { 219 | private ArrayList mData = new ArrayList(); 220 | private ArrayList mDataCopy; 221 | 222 | private final Access mAccess = new Access(); 223 | 224 | private boolean mStart; 225 | 226 | static class Access { 227 | private ArrayList mData; 228 | private int mSize; 229 | 230 | T get(int index) { 231 | return mData.get(index); 232 | } 233 | 234 | int size() { 235 | return mSize; 236 | } 237 | } 238 | 239 | CopyOnWriteArray() { 240 | } 241 | 242 | private ArrayList getArray() { 243 | if (mStart) { 244 | if (mDataCopy == null) mDataCopy = new ArrayList(mData); 245 | return mDataCopy; 246 | } 247 | return mData; 248 | } 249 | 250 | Access start() { 251 | if (mStart) throw new IllegalStateException("Iteration already started"); 252 | mStart = true; 253 | mDataCopy = null; 254 | mAccess.mData = mData; 255 | mAccess.mSize = mData.size(); 256 | return mAccess; 257 | } 258 | 259 | void end() { 260 | if (!mStart) throw new IllegalStateException("Iteration not started"); 261 | mStart = false; 262 | if (mDataCopy != null) { 263 | mData = mDataCopy; 264 | mAccess.mData.clear(); 265 | mAccess.mSize = 0; 266 | } 267 | mDataCopy = null; 268 | } 269 | 270 | int size() { 271 | return getArray().size(); 272 | } 273 | 274 | void add(T item) { 275 | getArray().add(item); 276 | } 277 | 278 | void addAll(CopyOnWriteArray array) { 279 | getArray().addAll(array.mData); 280 | } 281 | 282 | void remove(T item) { 283 | getArray().remove(item); 284 | } 285 | 286 | void clear() { 287 | getArray().clear(); 288 | } 289 | } 290 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/blur_bg_mask_gradient_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_glide_v4_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 17 | 18 | 23 | 24 | 29 | 30 | 36 | 37 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_image_loader.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 17 | 18 | 23 | 24 | 29 | 30 | 35 | 36 | 41 | 42 | 47 | 48 | 53 | 54 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jni_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 16 | 20 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jni_image_by_net_no_jni.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 16 | 20 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jni_image_by_sd.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 16 | 20 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jni_image_by_sd_no_jni.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 16 | 20 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |