├── app
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_pic_errow.png
│ │ │ └── icon_pic_loding.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ └── layout
│ │ │ └── activity_main.xml
│ │ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── vankain
│ │ │ └── imageloaderfactory
│ │ │ ├── ImageFrameworkFactory.java
│ │ │ ├── ImageLoaderProduct.java
│ │ │ ├── ImageConfigProduct.java
│ │ │ ├── UILFraworkFactory.java
│ │ │ ├── GlideFrameworkFactory.java
│ │ │ ├── PicassoFramworkFactory.java
│ │ │ ├── UILLoaderProduct.java
│ │ │ ├── ImageLoaderUtils.java
│ │ │ ├── PicassoWrapper.java
│ │ │ ├── PicassoLoaderProduct.java
│ │ │ ├── GlideLoaderProduct.java
│ │ │ ├── GlideWrapper.java
│ │ │ ├── GlideConfigProduct.java
│ │ │ ├── PicassoConfigProduct.java
│ │ │ ├── UILConfigProduct.java
│ │ │ ├── BaseApplication.java
│ │ │ ├── MainActivity.java
│ │ │ ├── ImageLoaderWrapper.java
│ │ │ └── BitmapUtils.java
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── .gitignore
└── README.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ImageLoaderFactory
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_pic_errow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-xhdpi/icon_pic_errow.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_pic_loding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VankaIn/ImageLoaderFactory/HEAD/app/src/main/res/mipmap-xhdpi/icon_pic_loding.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/java/com/github/vankain/imageloaderfactory/ImageFrameworkFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/2/29.
5 | */
6 | public interface ImageFrameworkFactory {
7 | ImageLoaderProduct createImageLoader();
8 | ImageConfigProduct createImageConfig();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ImageLoaderFactory
2 | 这个项目统一了图片 显示的方法
3 |
4 | # 有什么用?
5 | 当我们用了[Android-Universal-Image-Loader](https://github.com/nostra13/Android-Universal-Image-Loader/).加载图片的时候。
6 | 突然我们想更换加载图片的框架([Glide](https://github.com/bumptech/glide)),我们只能去修改我们之前自己再封装Android-Universal-Image-Loader的代码。
7 | 假如你没有再分装Android-Universal-Image-Loader,那更可怕,你只能每个activity都去改。
8 | 而这个框架是用抽象工厂分装好的,如果你想更换glide框架,只要建立glide的工厂然后进行对应的实现就可以,这样就不用修改原来的代码了。
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/ImageLoaderProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by Administrator on 2016/2/29.
7 | */
8 | public interface ImageLoaderProduct {
9 | void display(String imageUri, ImageView imageView);
10 | void display(String imageUrl, ImageView imageView, ImageConfigProduct config);
11 | void cleanImageCache(String imageUrl);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/ImageConfigProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/2/29.
5 | */
6 | public interface ImageConfigProduct {
7 | void setDefaulRes(int defaulRes);
8 | void setLoadingRes(int loadingRes);
9 | void setFailRes(int failRes);
10 | void setsupportMemoryCache(boolean flag);
11 | void setsupportDiskCache(boolean flag);
12 | void setFadeIn(int duration);
13 | Object get();
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/UILFraworkFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/2/29.
5 | */
6 | public class UILFraworkFactory implements ImageFrameworkFactory {
7 | @Override
8 | public ImageLoaderProduct createImageLoader() {
9 | return new UILLoaderProduct();
10 | }
11 |
12 | @Override
13 | public ImageConfigProduct createImageConfig(){
14 | return new UILConfigProduct();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/GlideFrameworkFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/2/29.
5 | */
6 | public class GlideFrameworkFactory implements ImageFrameworkFactory {
7 |
8 | @Override
9 | public ImageLoaderProduct createImageLoader() {
10 | return new GlideLoaderProduct();
11 | }
12 |
13 | @Override
14 | public ImageConfigProduct createImageConfig() {
15 | return new GlideConfigProduct();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/PicassoFramworkFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/3/2.
5 | */
6 | public class PicassoFramworkFactory implements ImageFrameworkFactory {
7 | @Override
8 | public ImageLoaderProduct createImageLoader() {
9 | return new PicassoLoaderProduct();
10 | }
11 |
12 | @Override
13 | public ImageConfigProduct createImageConfig() {
14 | return new PicassoConfigProduct();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/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:\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/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.github.vankain.imageloaderfactory"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.1.1'
26 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
27 | compile 'com.github.bumptech.glide:glide:3.6.1'
28 | compile 'com.squareup.picasso:picasso:2.5.2'
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/UILLoaderProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by Administrator on 2016/2/29.
7 | */
8 | public class UILLoaderProduct implements ImageLoaderProduct {
9 |
10 | @Override
11 | public void display(String imageUri, ImageView imageView) {
12 | ImageLoaderWrapper.getDefault().displayImage(imageUri, imageView);
13 | }
14 |
15 | @Override
16 | public void display(String imageUrl, ImageView imageView, ImageConfigProduct config) {
17 | ImageLoaderWrapper.DisplayConfig mConfig = (ImageLoaderWrapper.DisplayConfig) config.get();
18 | ImageLoaderWrapper.getDefault().displayImage(imageUrl, imageView, mConfig);
19 | }
20 |
21 | @Override
22 | public void cleanImageCache(String url) {
23 | ImageLoaderWrapper.getDefault().clearDefaultLoaderCache(url);
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/ImageLoaderUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.File;
6 |
7 | /**
8 | * Created by Administrator on 2016/2/29.
9 | */
10 | public class ImageLoaderUtils {
11 | public static void init(Context context, File file, boolean debug) {
12 | // if() 写在配置文件,根据不同的配置创建不同的图片加载器
13 | // 初始化图片加载器模块
14 | ImageLoaderWrapper.initDefault(context, file,
15 | debug);
16 | GlideWrapper.init(context);
17 | PicassoWrapper.init(context);
18 | }
19 |
20 | public static ImageFrameworkFactory getFramework(int frameworkType) {
21 | if (frameworkType == 1) {
22 | return new UILFraworkFactory();
23 | } else if (frameworkType == 2) {
24 | return new GlideFrameworkFactory();
25 | } else {
26 | return new PicassoFramworkFactory();
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/PicassoWrapper.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.content.Context;
4 |
5 | import com.squareup.picasso.Picasso;
6 |
7 | /**
8 | * Created by Administrator on 2016/3/1.
9 | */
10 | public class PicassoWrapper {
11 | private static PicassoWrapper sDefaultInstance;
12 | private Context mContext;
13 |
14 | public PicassoWrapper(Context context) {
15 | mContext = context;
16 | }
17 |
18 | public static PicassoWrapper init(Context context) {
19 | if (sDefaultInstance == null) {
20 | sDefaultInstance = new PicassoWrapper(context);
21 | }
22 | return sDefaultInstance;
23 | }
24 |
25 |
26 | public static PicassoWrapper getDefalt() {
27 | if (sDefaultInstance == null) {
28 | throw new RuntimeException(
29 | "Must be call init(Context) befor!");
30 | }
31 | return sDefaultInstance;
32 | }
33 |
34 |
35 | public Picasso getPicasso(){
36 | Picasso.with(mContext).setIndicatorsEnabled(true);
37 | return Picasso.with(mContext);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/PicassoLoaderProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by Administrator on 2016/3/2.
7 | */
8 | public class PicassoLoaderProduct implements ImageLoaderProduct {
9 | @Override
10 | public void display(String imageUri, ImageView imageView) {
11 | PicassoWrapper.getDefalt().getPicasso()
12 | .load(imageUri).into(imageView);
13 | }
14 |
15 | @Override
16 | public void display(String imageUrl, ImageView imageView, ImageConfigProduct config) {
17 | PicassoConfigProduct mConfig = (PicassoConfigProduct) config.get();
18 | PicassoWrapper.getDefalt()
19 | .getPicasso()
20 | .load(imageUrl)
21 | .placeholder(mConfig.loadingRes) // can also be a drawable
22 | .error(mConfig.failRes) // will be displayed if the image cannot be loaded
23 | .into(imageView);
24 | }
25 |
26 | @Override
27 | public void cleanImageCache(String url) {
28 | PicassoWrapper.getDefalt()
29 | .getPicasso()
30 | .invalidate(url);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/GlideLoaderProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by Administrator on 2016/3/1.
7 | */
8 | public class GlideLoaderProduct implements ImageLoaderProduct {
9 | @Override
10 | public void display(String imageUri, ImageView imageView) {
11 | GlideWrapper.getDefalt()
12 | .getGlide()
13 | .load(imageUri)
14 | .centerCrop()
15 | .into(imageView);
16 | }
17 |
18 | @Override
19 | public void display(String imageUrl, ImageView imageView, ImageConfigProduct config) {
20 | GlideConfigProduct mConfig = (GlideConfigProduct) config.get();
21 | GlideWrapper.getDefalt()
22 | .getGlide()
23 | .load(imageUrl)
24 | .centerCrop()
25 | .placeholder(mConfig.loadingRes) // can also be a drawable
26 | .error(mConfig.failRes) // will be displayed if the image cannot be loaded
27 | .crossFade(mConfig.duration)
28 | .into(imageView);
29 | }
30 |
31 | @Override
32 | public void cleanImageCache(String url) {
33 | GlideWrapper.getDefalt().cleanCache();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/GlideWrapper.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.content.Context;
4 |
5 | import com.bumptech.glide.Glide;
6 | import com.bumptech.glide.RequestManager;
7 |
8 | /**
9 | * Created by Administrator on 2016/3/1.
10 | */
11 | public class GlideWrapper {
12 | private static GlideWrapper sDefaultInstance;
13 | private Context mContext;
14 |
15 | public GlideWrapper(Context context) {
16 | mContext = context;
17 | }
18 |
19 | public static GlideWrapper init(Context context) {
20 | if (sDefaultInstance == null) {
21 | sDefaultInstance = new GlideWrapper(context);
22 | }
23 | return sDefaultInstance;
24 | }
25 |
26 |
27 | public static GlideWrapper getDefalt() {
28 | if (sDefaultInstance == null) {
29 | throw new RuntimeException(
30 | "Must be call init(Context) befor!");
31 | }
32 | return sDefaultInstance;
33 | }
34 |
35 |
36 | public RequestManager getGlide(){
37 | return Glide.with(mContext);
38 | }
39 |
40 | public void cleanCache(){
41 | // crash: method on a background thread
42 | // you should put it on threadpool
43 | new Thread(new Runnable() {
44 | @Override
45 | public void run() {
46 | Glide.get(mContext).clearMemory();
47 | Glide.get(mContext).clearDiskCache();
48 | }
49 | });
50 |
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/GlideConfigProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/3/1.
5 | */
6 | public class GlideConfigProduct implements ImageConfigProduct {
7 | //default true
8 | public boolean isSupportMemoryCache;
9 | public boolean isSupportDiskCache;
10 | public int defaulRes;
11 | public int loadingRes;
12 | public int failRes;
13 | public int duration;
14 |
15 |
16 | public GlideConfigProduct() {
17 | this.isSupportMemoryCache = true;
18 | this.isSupportDiskCache = true;
19 | this.loadingRes = 0;
20 | this.failRes = 0;
21 | this.duration = 0;
22 | }
23 |
24 | @Override
25 | public void setDefaulRes(int defaulRes) {
26 | this.defaulRes = defaulRes;
27 | }
28 |
29 | @Override
30 | public void setLoadingRes(int loadingRes) {
31 | this.loadingRes = loadingRes;
32 | }
33 |
34 | @Override
35 | public void setFailRes(int failRes) {
36 | this.failRes = failRes;
37 | }
38 |
39 | @Override
40 | public void setsupportMemoryCache(boolean flag) {
41 | this.isSupportMemoryCache = flag;
42 | }
43 |
44 | @Override
45 | public void setsupportDiskCache(boolean flag) {
46 | this.isSupportDiskCache = flag;
47 | }
48 |
49 | @Override
50 | public void setFadeIn(int duration) {
51 | this.duration = duration;
52 | }
53 |
54 | @Override
55 | public Object get() {
56 | return this;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/PicassoConfigProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/3/2.
5 | */
6 | public class PicassoConfigProduct implements ImageConfigProduct {
7 | //default true
8 | public boolean isSupportMemoryCache;
9 | public boolean isSupportDiskCache;
10 | public int defaulRes;
11 | public int loadingRes;
12 | public int failRes;
13 | public int duration;
14 |
15 |
16 | public PicassoConfigProduct() {
17 | this.isSupportMemoryCache = true;
18 | this.isSupportDiskCache = true;
19 | this.loadingRes = 0;
20 | this.failRes = 0;
21 | this.duration = 0;
22 | }
23 |
24 | @Override
25 | public void setDefaulRes(int defaulRes) {
26 | this.defaulRes = defaulRes;
27 | }
28 |
29 | @Override
30 | public void setLoadingRes(int loadingRes) {
31 | this.loadingRes = loadingRes;
32 | }
33 |
34 | @Override
35 | public void setFailRes(int failRes) {
36 | this.failRes = failRes;
37 | }
38 |
39 | @Override
40 | public void setsupportMemoryCache(boolean flag) {
41 | this.isSupportMemoryCache = flag;
42 | }
43 |
44 | @Override
45 | public void setsupportDiskCache(boolean flag) {
46 | this.isSupportDiskCache = flag;
47 | }
48 |
49 | @Override
50 | public void setFadeIn(int duration) {
51 | this.duration = duration;
52 | }
53 |
54 | @Override
55 | public Object get() {
56 | return this;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
19 |
25 |
26 |
32 |
33 |
39 |
40 |
44 |
45 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/UILConfigProduct.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | /**
4 | * Created by Administrator on 2016/2/29.
5 | */
6 | public class UILConfigProduct implements ImageConfigProduct {
7 | //default true
8 | public boolean isSupportMemoryCache;
9 | public boolean isSupportDiskCache;
10 | public int defaulRes;
11 | public int loadingRes;
12 | public int failRes;
13 | public int duration;
14 |
15 | public UILConfigProduct() {
16 | this.isSupportMemoryCache = true;
17 | this.isSupportDiskCache = true;
18 | this.loadingRes = 0;
19 | this.failRes = 0;
20 | this.duration = 0;
21 | }
22 |
23 | @Override
24 | public void setDefaulRes(int defaulRes) {
25 | this.defaulRes = defaulRes;
26 | }
27 |
28 | @Override
29 | public void setLoadingRes(int loadingRes) {
30 | this.loadingRes = loadingRes;
31 | }
32 |
33 | @Override
34 | public void setFailRes(int failRes) {
35 | this.failRes = failRes;
36 | }
37 |
38 | @Override
39 | public void setsupportMemoryCache(boolean flag) {
40 | this.isSupportMemoryCache = flag;
41 | }
42 |
43 | @Override
44 | public void setsupportDiskCache(boolean flag) {
45 | this.isSupportDiskCache = flag;
46 | }
47 |
48 | @Override
49 | public void setFadeIn(int duration) {
50 | this.duration = duration;
51 | }
52 |
53 | @Override
54 | public Object get() {
55 | ImageLoaderWrapper.DisplayConfig config = new ImageLoaderWrapper.DisplayConfig.Builder().build();
56 | config.loadFailImageRes = this.loadingRes;
57 | config.loadFailImageRes = this.failRes;
58 | config.stubImageRes = this.defaulRes;
59 | config.supportMemoryCache = this.isSupportMemoryCache;
60 | config.supportDiskCache = this.isSupportDiskCache;
61 | return config;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.app.Application;
4 | import android.os.Environment;
5 |
6 | import java.io.File;
7 |
8 | /**
9 | * Created by Administrator on 2016/2/29.
10 | */
11 | public class BaseApplication extends Application {
12 |
13 | @Override
14 | public void onCreate() {
15 | super.onCreate();
16 | ImageLoaderUtils.init(this, getImageTmpDir(), true);
17 | }
18 |
19 | /**
20 | * 获取图片临时目录(网络图片缓存)
21 | *
22 | * @return
23 | */
24 | public File getImageTmpDir() {
25 | File dir = new File(getTmpDir(), "image_cache");
26 | if (!dir.exists()) {
27 | dir.mkdirs();
28 | }
29 | return dir;
30 | }
31 |
32 | /**
33 | * 获取临时目录
34 | *
35 | * @return
36 | */
37 | public File getTmpDir() {
38 | return getTmpDir(false);
39 | }
40 |
41 | /**
42 | * 获取临时目录
43 | *
44 | * @param isSdcard 是否只取sd卡上的目录
45 | * @return
46 | */
47 | public File getTmpDir(boolean isSdcard) {
48 | File tmpDir = null;
49 | // 判断sd卡是否存在
50 | boolean sdCardExist = Environment.getExternalStorageState().equals(
51 | Environment.MEDIA_MOUNTED);
52 | if (isSdcard && !sdCardExist) {
53 | if (!sdCardExist) {
54 | return null;
55 | }
56 | }
57 |
58 | if (sdCardExist || isSdcard) {
59 | tmpDir = new File(Environment.getExternalStorageDirectory(),
60 | getTmpDirName());
61 | } else {
62 | tmpDir = new File(getCacheDir(), getTmpDirName());
63 | }
64 |
65 | if (!tmpDir.exists()) {
66 | tmpDir.mkdirs();
67 | }
68 |
69 | return tmpDir;
70 | }
71 |
72 | /**
73 | * 获取缓存目录名
74 | *
75 | * @return
76 | */
77 | public String getTmpDirName() {
78 | return "ImageLoaderFactory";
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 | ImageView mIvUIL;
10 | ImageView mIvGlide;
11 | ImageView mIvPicasso;
12 |
13 | public int mLastFrameWorkType = 1;
14 |
15 | // public final static String url = "http://desk.fd.zol-img.com.cn/g5/M00/05/02/ChMkJ1bD1HCIY1ATAA-BspTxVL8AAKTXwOOeQsAD4HK484.jpg";
16 | public final static String url = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/abstract-factory/etc/abstract-factory_1.png";
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_main);
22 | mIvUIL = (ImageView) findViewById(R.id.iv_uil);
23 | mIvGlide = (ImageView) findViewById(R.id.iv_glide);
24 | }
25 |
26 | public void loadUIL(View view) {
27 | loadPic(1);
28 | }
29 |
30 | public void loadGlide(View view) {
31 | loadPic(2);
32 | }
33 |
34 | public void loadPicasso(View view) {
35 | loadPic(3);
36 | }
37 |
38 | private void loadPic(int loadFrameworkType) {
39 | //清楚之前的缓存
40 | if (mLastFrameWorkType != loadFrameworkType) {
41 | ImageLoaderUtils.getFramework(mLastFrameWorkType)
42 | .createImageLoader()
43 | .cleanImageCache(url);
44 | }
45 |
46 | ImageConfigProduct configProduct = ImageLoaderUtils.getFramework(loadFrameworkType)
47 | .createImageConfig();
48 | configProduct.setDefaulRes(R.mipmap.icon_pic_loding);
49 | configProduct.setLoadingRes(R.mipmap.icon_pic_loding);
50 | configProduct.setFailRes(R.mipmap.icon_pic_errow);
51 | configProduct.setFadeIn(0);
52 | ImageLoaderUtils.getFramework(loadFrameworkType)
53 | .createImageLoader()
54 | .display(
55 | url, mIvUIL, configProduct);
56 | mLastFrameWorkType = loadFrameworkType;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/ImageLoaderWrapper.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.app.ActivityManager;
6 | import android.content.Context;
7 | import android.content.pm.ApplicationInfo;
8 | import android.graphics.Bitmap;
9 | import android.graphics.Bitmap.Config;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.text.TextUtils;
13 | import android.widget.AbsListView.OnScrollListener;
14 | import android.widget.ImageView;
15 |
16 | import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
17 | import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
18 | import com.nostra13.universalimageloader.cache.memory.impl.FIFOLimitedMemoryCache;
19 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
20 | import com.nostra13.universalimageloader.core.ImageLoader;
21 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
22 | import com.nostra13.universalimageloader.core.assist.ImageScaleType;
23 | import com.nostra13.universalimageloader.core.assist.LoadedFrom;
24 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
25 | import com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
26 | import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
27 | import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
28 | import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
29 | import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
30 | import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
31 | import com.nostra13.universalimageloader.core.imageaware.ImageAware;
32 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
33 | import com.nostra13.universalimageloader.core.listener.PauseOnScrollListener;
34 | import com.nostra13.universalimageloader.utils.DiskCacheUtils;
35 | import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
36 |
37 | import java.io.File;
38 | import java.io.FileFilter;
39 | import java.util.List;
40 | import java.util.regex.Pattern;
41 |
42 |
43 | /**
44 | * 一个用于加载图片到ImageView的工具类,可加载网络图片 使用时先调用init进行初始化
45 | *
46 | * 包装了Universal-Image-Loader开源项目
47 | *
48 | * String imageUri = "http://site.com/image.png"; // from Web String imageUri =
49 | * "file:///mnt/sdcard/image.png"; // from SD card String imageUri =
50 | * "content://media/external/audio/albumart/13"; // from content provider String
51 | * imageUri = "assets://image.png"; // from assets String imageUri =
52 | * "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)
53 | *
54 | * @author Huyf Email:my519820363@gmail.com
55 | *
56 | */
57 | public class ImageLoaderWrapper {
58 | private static ImageLoaderWrapper sDefaultInstance;
59 | private ImageLoader mDefaultImageLoader;
60 |
61 | private ImageLoaderWrapper(Context context, File cacheDir, boolean debug) {
62 | context = context.getApplicationContext();
63 | int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
64 | int screenHeight = context.getResources().getDisplayMetrics().heightPixels;
65 |
66 | ImageLoaderConfiguration.Builder imageLoaderConfigurationBuilder = new ImageLoaderConfiguration.Builder(
67 | context.getApplicationContext())
68 | .threadPoolSize(5 * getNumCores())
69 | .threadPriority(Thread.NORM_PRIORITY - 2)
70 | .tasksProcessingOrder(QueueProcessingType.FIFO)
71 | .denyCacheImageMultipleSizesInMemory();
72 |
73 | imageLoaderConfigurationBuilder.diskCacheExtraOptions(screenWidth,
74 | screenHeight, null);
75 | imageLoaderConfigurationBuilder.diskCache(new UnlimitedDiscCache(
76 | cacheDir));
77 | imageLoaderConfigurationBuilder.diskCacheSize(50 * 1024 * 1024);
78 | imageLoaderConfigurationBuilder
79 | .diskCacheFileNameGenerator(new HashCodeFileNameGenerator());
80 |
81 | imageLoaderConfigurationBuilder.memoryCache(new FIFOLimitedMemoryCache(
82 | calculateDefaultMaxSize(context, 4)));
83 | imageLoaderConfigurationBuilder.memoryCacheSizePercentage(13);
84 | imageLoaderConfigurationBuilder.memoryCacheExtraOptions(screenWidth,
85 | screenHeight);
86 |
87 | imageLoaderConfigurationBuilder
88 | .imageDownloader(new BaseImageDownloader(context));
89 | imageLoaderConfigurationBuilder
90 | .imageDecoder(new BaseImageDecoder(debug));
91 | imageLoaderConfigurationBuilder
92 | .defaultDisplayImageOptions(DisplayImageOptions.createSimple());
93 | if (debug) {
94 | imageLoaderConfigurationBuilder.writeDebugLogs();
95 | }
96 |
97 | ImageLoader.getInstance().init(imageLoaderConfigurationBuilder.build());
98 | mDefaultImageLoader = ImageLoader.getInstance();
99 | }
100 |
101 | public synchronized static ImageLoaderWrapper initDefault(Context context,
102 | File discCacheDir, boolean debug) {
103 | if (sDefaultInstance == null) {
104 | sDefaultInstance = new ImageLoaderWrapper(context, discCacheDir,
105 | debug);
106 | }
107 | return sDefaultInstance;
108 | }
109 |
110 | public synchronized static ImageLoaderWrapper getDefault() {
111 | if (sDefaultInstance == null) {
112 | throw new RuntimeException(
113 | "Must be call initDefault(Context, File) befor!");
114 | }
115 |
116 | return sDefaultInstance;
117 | }
118 |
119 | public OnScrollListener newScrollListenerWithTheImageLoader(
120 | boolean pauseOnScroll, boolean pauseOnFling) {
121 | return new PauseOnScrollListener(mDefaultImageLoader, pauseOnScroll,
122 | pauseOnFling);
123 | }
124 |
125 | public OnScrollListener newScrollListenerWithTheImageLoader(
126 | boolean pauseOnScroll, boolean pauseOnFling,
127 | OnScrollListener customListener) {
128 | return new PauseOnScrollListener(mDefaultImageLoader, pauseOnScroll,
129 | pauseOnFling, customListener);
130 | }
131 |
132 | public ImageLoader getImageLoader() {
133 | return mDefaultImageLoader;
134 | }
135 |
136 | public void loadImage(String imageUri) {
137 | loadImage(imageUri, null, null);
138 | }
139 |
140 | public void loadImage(String imageUri, ImageLoadingListener listener) {
141 | loadImage(imageUri, null, listener);
142 | }
143 |
144 | public void loadImage(String imageUri, DisplayConfig config) {
145 | loadImage(imageUri, config, null);
146 | }
147 |
148 | public void loadImage(String imageUri, DisplayConfig config,
149 | ImageLoadingListener listener) {
150 | if (config == null) {
151 | config = new DisplayConfig();
152 | }
153 |
154 | if (!TextUtils.isEmpty(imageUri)) {
155 | Uri uri = Uri.parse(imageUri);
156 | String scheme = uri.getScheme();
157 | if ("http".equals(scheme)) {
158 | config.supportDiskCache = true;
159 | } else {
160 | config.supportDiskCache = false;
161 | }
162 | }
163 |
164 | DisplayImageOptions options = new DisplayImageOptions.Builder()
165 | .showImageOnLoading(config.stubImageRes)
166 | .showImageForEmptyUri(config.loadFailImageRes)
167 | .showImageOnFail(config.loadFailImageRes)
168 | .cacheInMemory(config.supportMemoryCache)
169 | .cacheOnDisk(config.supportDiskCache)
170 | .imageScaleType(config.imageScaleType)
171 | .resetViewBeforeLoading(config.isResetView)
172 | .displayer(config.displayer).build();
173 |
174 | mDefaultImageLoader.loadImage(imageUri, options, listener);
175 | }
176 |
177 | public void displayImage(String imageUri, ImageView imageView) {
178 | displayImage(imageUri, imageView, null, null);
179 | }
180 |
181 | public void displayImage(String imageUri, ImageView imageView,
182 | ImageLoadingListener listener) {
183 | displayImage(imageUri, imageView, null, listener);
184 | }
185 |
186 | public void displayImage(String imageUri, ImageView imageView,
187 | DisplayConfig config) {
188 | displayImage(imageUri, imageView, config, null);
189 | }
190 |
191 | public void displayImage(String imageUri, ImageView imageView,
192 | DisplayConfig config, ImageLoadingListener listener) {
193 | if (config == null) {
194 | config = new DisplayConfig();
195 | }
196 |
197 | if (!TextUtils.isEmpty(imageUri)) {
198 | Uri uri = Uri.parse(imageUri);
199 | String scheme = uri.getScheme();
200 | if ("http".equals(scheme)) {
201 | config.supportDiskCache = true;
202 | } else {
203 | config.supportDiskCache = false;
204 | }
205 | }
206 |
207 | DisplayImageOptions options = new DisplayImageOptions.Builder()
208 | .showImageOnLoading(config.stubImageRes)
209 | .showImageForEmptyUri(config.loadFailImageRes)
210 | .showImageOnFail(config.loadFailImageRes)
211 | .cacheInMemory(config.supportMemoryCache)
212 | .cacheOnDisk(config.supportDiskCache)
213 | .imageScaleType(config.imageScaleType)
214 | .resetViewBeforeLoading(config.isResetView)
215 | .bitmapConfig(Config.RGB_565).displayer(config.displayer)
216 | .considerExifParams(false).build();
217 | mDefaultImageLoader
218 | .displayImage(imageUri, imageView, options, listener);
219 | }
220 |
221 | public void clearDefaultLoaderMemoryCache() {
222 | mDefaultImageLoader.clearMemoryCache();
223 | }
224 |
225 | public void clearDefaultLoaderDiscCache() {
226 | mDefaultImageLoader.clearDiskCache();
227 | }
228 |
229 | /**
230 | * 清除单张
231 | */
232 | public void clearDefaultLoaderCache(String url){
233 | removeMemoryFromCache(url);
234 | removeDiscFromCache(url);
235 | }
236 |
237 | /**
238 | * 停止所有下载图片的任务
239 | */
240 | public void pause() {
241 | mDefaultImageLoader.pause();
242 | }
243 |
244 | /**
245 | * 恢复被暂停的任务
246 | */
247 | public void resume() {
248 | mDefaultImageLoader.resume();
249 | }
250 |
251 | /**
252 | * 取消所有的下载图片的任务
253 | */
254 | public void stop() {
255 | mDefaultImageLoader.stop();
256 | }
257 |
258 | /**
259 | * 根据传入的URI搜索所有在内存中缓存的位图 注意:内存缓存可以包含不同尺寸的相同图像
260 | *
261 | * @param imageUri
262 | */
263 | public List findMemoryCachedBitmapsForImageUri(String imageUri) {
264 | if (TextUtils.isEmpty(imageUri)) {
265 | return null;
266 | }
267 |
268 | return MemoryCacheUtils.findCachedBitmapsForImageUri(imageUri,
269 | mDefaultImageLoader.getMemoryCache());
270 | }
271 |
272 | /**
273 | * 根据传入的URI删除位图缓存
274 | *
275 | * @param imageUri
276 | */
277 | public void removeMemoryFromCache(String imageUri) {
278 | MemoryCacheUtils.removeFromCache(imageUri,
279 | mDefaultImageLoader.getMemoryCache());
280 | }
281 |
282 | /**
283 | * 根据传入的URI搜索所有在磁盘中缓存的位图文件
284 | *
285 | * @param imageUri
286 | */
287 | public File findDiscCachedBitmapsForImageUri(String imageUri) {
288 | return DiskCacheUtils.findInCache(imageUri,
289 | mDefaultImageLoader.getDiskCache());
290 | }
291 |
292 | /**
293 | * 根据传入的URI删除位图缓存
294 | *
295 | * @param imageUri
296 | */
297 | public void removeDiscFromCache(String imageUri) {
298 | DiskCacheUtils.removeFromCache(imageUri,
299 | mDefaultImageLoader.getDiskCache());
300 | }
301 |
302 | // CPU个数
303 | private int getNumCores() {
304 | class CpuFilter implements FileFilter {
305 |
306 | @Override
307 | public boolean accept(File pathname) {
308 | if (Pattern.matches("cpu[0-9]", pathname.getName())) {
309 | return true;
310 | }
311 | return false;
312 | }
313 | }
314 |
315 | try {
316 | File dir = new File("/sys/devices/system/cpu/");
317 | File[] files = dir.listFiles(new CpuFilter());
318 | return Math.max(1, files.length);
319 | } catch (Exception e) {
320 | return 1;
321 | }
322 | }
323 |
324 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
325 | private int calculateDefaultMaxSize(Context context, int weight) {
326 | ActivityManager am = (ActivityManager) context
327 | .getSystemService(Activity.ACTIVITY_SERVICE);
328 | boolean largeHeap = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0;
329 | int memoryClass = am.getMemoryClass();
330 | if (largeHeap && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
331 | memoryClass = am.getLargeMemoryClass();
332 | }
333 |
334 | return 1024 * 1024 * Math.min(12, memoryClass / weight);
335 | }
336 |
337 | public static class DisplayConfig {
338 | public boolean supportMemoryCache;
339 | public boolean supportDiskCache;
340 | public boolean isResetView;
341 | public int stubImageRes;
342 | public int loadFailImageRes;
343 | private BitmapDisplayer displayer;
344 | private final ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2;
345 | private static final BitmapDisplayer sDefault = new SimpleBitmapDisplayer();
346 | private static final BitmapDisplayer sDefaultFadein = new FadeInBitmapDisplayer(
347 | 300);
348 | private static final BitmapDisplayer sDefaultRound = new RoundedBitmapDisplayer(
349 | 10);
350 | private static final BitmapDisplayer sDefaultCircular = new CircularBitmapDisplayer();
351 |
352 | private DisplayConfig() {
353 | supportMemoryCache = true;
354 | supportDiskCache = true;
355 | isResetView = true;
356 | stubImageRes = 0;
357 | loadFailImageRes = 0;
358 | displayer = new SimpleBitmapDisplayer();
359 | }
360 |
361 | public static class Builder {
362 | public Builder() {
363 | }
364 |
365 | public DisplayConfig build() {
366 | DisplayConfig config = new DisplayConfig();
367 | config.displayer = sDefault;
368 | return config;
369 | }
370 |
371 | public DisplayConfig buildFadein() {
372 | DisplayConfig config = new DisplayConfig();
373 | config.displayer = sDefaultFadein;
374 | return config;
375 | }
376 |
377 | public DisplayConfig buildRounded() {
378 | DisplayConfig config = new DisplayConfig();
379 | config.displayer = sDefaultRound;
380 | return config;
381 | }
382 |
383 | public DisplayConfig buildCircular() {
384 | DisplayConfig config = new DisplayConfig();
385 | config.displayer = sDefaultCircular;
386 | return config;
387 | }
388 |
389 | public DisplayConfig buildFadein(int fadeInTime) {
390 | DisplayConfig config = new DisplayConfig();
391 | config.displayer = new FadeInBitmapDisplayer(fadeInTime);
392 | return config;
393 | }
394 |
395 | public DisplayConfig buildRounded(int round) {
396 | DisplayConfig config = new DisplayConfig();
397 | config.displayer = new RoundedBitmapDisplayer(round);
398 | return config;
399 | }
400 |
401 | public DisplayConfig buildBlur(Context context, int radius) {
402 | DisplayConfig config = new DisplayConfig();
403 | config.displayer = new BlurBitmapDisplayer(context, radius);
404 | return config;
405 | }
406 |
407 | public DisplayConfig buildGray() {
408 | DisplayConfig config = new DisplayConfig();
409 | config.displayer = new GrayBitmapDisplayer();
410 | return config;
411 | }
412 |
413 | public DisplayConfig buildAlpha(int alpha) {
414 | DisplayConfig config = new DisplayConfig();
415 | config.displayer = new AlphaBitmapDisplayer(alpha);
416 | return config;
417 | }
418 | }
419 | }
420 |
421 | /**
422 | * 将图片显示为半透明模糊效果,必须将图片的inPreferredConfig设置为ARGB8888,否则会崩溃
423 | *
424 | * Just displays {@link android.graphics.Bitmap} in
425 | * {@link com.nostra13.universalimageloader.core.imageaware.ImageAware}
426 | *
427 | * @author Huyunfeng (my519820363[at]gmail[dot]com)
428 | * @since 0.0.1
429 | */
430 | public final static class BlurBitmapDisplayer implements BitmapDisplayer {
431 | private Context mContext;
432 | private int mRadius = 1;
433 |
434 | public BlurBitmapDisplayer(Context context) {
435 | mContext = context;
436 | }
437 |
438 | public BlurBitmapDisplayer(Context context, int radius) {
439 | mContext = context.getApplicationContext();
440 | mRadius = radius;
441 | }
442 |
443 | @Override
444 | public void display(Bitmap bitmap, ImageAware imageAware,
445 | LoadedFrom loadedFrom) {
446 | Bitmap blurBitmap = BitmapUtils.fastblur(mContext, bitmap,
447 | Math.max(1, mRadius));
448 | if (blurBitmap != null && !blurBitmap.isRecycled()) {
449 | imageAware.setImageBitmap(blurBitmap);
450 | } else {
451 | imageAware.setImageBitmap(bitmap);
452 | }
453 | }
454 | }
455 |
456 | /**
457 | * 将图片显示为灰色效果
458 | *
459 | * Just displays {@link android.graphics.Bitmap} in
460 | * {@link com.nostra13.universalimageloader.core.imageaware.ImageAware}
461 | *
462 | * @author Huyunfeng (my519820363[at]gmail[dot]com)
463 | * @since 0.0.1
464 | */
465 | public final static class GrayBitmapDisplayer implements BitmapDisplayer {
466 |
467 | @Override
468 | public void display(Bitmap bitmap, ImageAware imageAware,
469 | LoadedFrom loadedFrom) {
470 | Bitmap grayBitmap = BitmapUtils.grey(bitmap);
471 | if (grayBitmap != null && !grayBitmap.isRecycled()) {
472 | imageAware.setImageBitmap(grayBitmap);
473 | } else {
474 | imageAware.setImageBitmap(bitmap);
475 | }
476 | }
477 | }
478 |
479 | public final static class CircularBitmapDisplayer implements
480 | BitmapDisplayer {
481 |
482 | @Override
483 | public void display(Bitmap bitmap, ImageAware imageAware,
484 | LoadedFrom loadedFrom) {
485 | Bitmap circularBitmap = BitmapUtils.circular(bitmap);
486 | if (circularBitmap != null && !circularBitmap.isRecycled()) {
487 | imageAware.setImageBitmap(circularBitmap);
488 | } else {
489 | imageAware.setImageBitmap(bitmap);
490 | }
491 | }
492 | }
493 |
494 | public final static class AlphaBitmapDisplayer implements BitmapDisplayer {
495 | private int alpha;
496 |
497 | public AlphaBitmapDisplayer(int alpha) {
498 | this.alpha = alpha;
499 | }
500 |
501 | @Override
502 | public void display(Bitmap bitmap, ImageAware imageAware,
503 | LoadedFrom loadedFrom) {
504 | Bitmap grayBitmap = BitmapUtils.alpha(bitmap, alpha);
505 | if (grayBitmap != null && !grayBitmap.isRecycled()) {
506 | imageAware.setImageBitmap(grayBitmap);
507 | } else {
508 | imageAware.setImageBitmap(bitmap);
509 | }
510 | }
511 | }
512 | }
513 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/vankain/imageloaderfactory/BitmapUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vankain.imageloaderfactory;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Bitmap.Config;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.BitmapFactory.Options;
8 | import android.graphics.Canvas;
9 | import android.graphics.ColorMatrix;
10 | import android.graphics.ColorMatrixColorFilter;
11 | import android.graphics.Matrix;
12 | import android.graphics.Paint;
13 | import android.graphics.PorterDuff.Mode;
14 | import android.graphics.PorterDuffXfermode;
15 | import android.graphics.Rect;
16 | import android.graphics.RectF;
17 | import android.media.ExifInterface;
18 | import android.net.Uri;
19 | import android.util.Log;
20 |
21 | import java.io.BufferedOutputStream;
22 | import java.io.ByteArrayInputStream;
23 | import java.io.ByteArrayOutputStream;
24 | import java.io.File;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 |
29 |
30 | public class BitmapUtils {
31 |
32 | public static Bitmap toBitmap(Context context, int resId, Integer maxWidth, Integer maxHeight) {
33 | Bitmap bitmap = BitmapFactory.decodeResource(
34 | context.getResources(), resId);
35 | Bitmap scaled = Bitmap.createScaledBitmap(bitmap, maxWidth, maxHeight,
36 | true);
37 | bitmap.recycle();
38 | return scaled;
39 | }
40 |
41 | public static Bitmap toBitmap(InputStream input, Integer maxWidth,
42 | Integer maxHeight) {
43 |
44 | Options options = new Options();
45 | if ((maxWidth != null) && (maxHeight != null)) {
46 | // Set the scaling options.
47 | float scale = Math.min(maxWidth.floatValue() / options.outWidth,
48 | maxHeight.floatValue() / options.outHeight);
49 | options.inSampleSize = Math.round(1 / scale);
50 | }
51 | options.inJustDecodeBounds = false;
52 | return BitmapFactory.decodeStream(input, null, options);
53 | }
54 |
55 | /**
56 | * Gets a {@link Bitmap} from a {@link Uri}. Resizes the image to a
57 | * determined width and height.
58 | *
59 | * @param uri The {@link Uri} from which the image is obtained.
60 | * @param maxWidth The maximum width of the image used to scale it. If null, the
61 | * image won't be scaled
62 | * @param maxHeight The maximum height of the image used to scale it. If null, the
63 | * image won't be scaled
64 | * @return {@link Bitmap} The resized image.
65 | */
66 | public static Bitmap toBitmap(Context context, Uri uri, Integer maxWidth, Integer maxHeight) {
67 | try {
68 | // First decode with inJustDecodeBounds=true to check dimensions
69 | Options options = new Options();
70 | options.inJustDecodeBounds = true;
71 | InputStream openInputStream = context.getContentResolver()
72 | .openInputStream(uri);
73 | BitmapFactory.decodeStream(openInputStream, null, options);
74 | openInputStream.close();
75 |
76 | // Calculate inSampleSize
77 | if ((maxWidth != null) && (maxHeight != null)) {
78 | float scale = Math.min(
79 | maxWidth.floatValue() / options.outWidth,
80 | maxHeight.floatValue() / options.outHeight);
81 | options.inSampleSize = Math.round(1 / scale);
82 | }
83 |
84 | // Decode bitmap with inSampleSize set
85 | openInputStream = context.getContentResolver().openInputStream(uri);
86 | options.inJustDecodeBounds = false;
87 | Bitmap result = BitmapFactory.decodeStream(openInputStream, null,
88 | options);
89 | openInputStream.close();
90 | return result;
91 | } catch (Exception e) {
92 | Log.e(BitmapUtils.class.getSimpleName(), e.getMessage());
93 | return null;
94 | }
95 | }
96 |
97 | public static ByteArrayInputStream toPNGInputStream(Context context, Uri uri,
98 | Integer maxWidth, Integer maxHeight) {
99 | Bitmap bitmap = BitmapUtils.toBitmap(context, uri, maxWidth, maxHeight);
100 | return BitmapUtils.toPNGInputStream(bitmap);
101 | }
102 |
103 | /**
104 | * Compress the bitmap to a PNG and return its {@link ByteArrayInputStream}
105 | *
106 | * @param bitmap The {@link Bitmap} to compress
107 | * @return The {@link ByteArrayInputStream}
108 | */
109 | public static ByteArrayInputStream toPNGInputStream(Bitmap bitmap) {
110 | ByteArrayOutputStream bytes = new ByteArrayOutputStream();
111 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);
112 | return new ByteArrayInputStream(bytes.toByteArray());
113 | }
114 |
115 | public static int getExifRotation(String imageFilePath) {
116 | if (imageFilePath == null)
117 | return 0;
118 | try {
119 | ExifInterface exif = new ExifInterface(imageFilePath);
120 | // We only recognize a subset of orientation tag values
121 | switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
122 | ExifInterface.ORIENTATION_UNDEFINED)) {
123 | case ExifInterface.ORIENTATION_ROTATE_90:
124 | return 90;
125 | case ExifInterface.ORIENTATION_ROTATE_180:
126 | return 180;
127 | case ExifInterface.ORIENTATION_ROTATE_270:
128 | return 270;
129 | default:
130 | return ExifInterface.ORIENTATION_UNDEFINED;
131 | }
132 | } catch (IOException e) {
133 | return 0;
134 | }
135 | }
136 |
137 | public static int calculateInSampleSize(Options options,
138 | int reqWidth, int reqHeight) {
139 | // Raw height and width of image
140 | final int height = options.outHeight;
141 | final int width = options.outWidth;
142 |
143 | return calculateInSampleSize(width, height, reqWidth, reqHeight);
144 | }
145 |
146 | public static int calculateInSampleSize(int width, int height,
147 | int reqWidth, int reqHeight) {
148 | int inSampleSize = 1;
149 | if (height > reqHeight || width > reqWidth) {
150 | if (width > height) {
151 | inSampleSize = Math.round((float) height / (float) reqHeight);
152 | } else {
153 | inSampleSize = Math.round((float) width / (float) reqWidth);
154 | }
155 | }
156 |
157 | return inSampleSize;
158 | }
159 |
160 | public static Bitmap decodeSampledBitmapFromFile(File file, int reqWidth,
161 | int reqHeight) {
162 | // First decode with inJustDecodeBounds=true to check dimensions
163 | final Options options = new Options();
164 | options.inJustDecodeBounds = true;
165 | BitmapFactory.decodeFile(file.getAbsolutePath(), options);
166 |
167 | // Calculate inSampleSize
168 | options.inSampleSize = calculateInSampleSize(options, reqWidth,
169 | reqHeight);
170 |
171 | // Decode bitmap with inSampleSize set
172 | options.inJustDecodeBounds = false;
173 | return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
174 | }
175 |
176 | public static int getExifRotation(File tempFile, Bitmap bitmap) {
177 | try {
178 | // 将图片保存
179 | FileOutputStream b = new FileOutputStream(tempFile);
180 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);
181 | b.flush();
182 | b.close();
183 | return getExifRotation(tempFile.getAbsolutePath());
184 | } catch (IOException e) {
185 | e.printStackTrace();
186 | return 0;
187 | }
188 | }
189 |
190 | public static Bitmap decodeSampledBitmapFromBitmap(Bitmap bitmap,
191 | int reqWidth, int reqHeight) {
192 | // Calculate inSampleSize
193 | final Options options = new Options();
194 | options.inSampleSize = calculateInSampleSize(bitmap.getWidth(),
195 | bitmap.getHeight(), reqWidth, reqHeight);
196 | // Decode bitmap with inSampleSize set
197 | options.inJustDecodeBounds = false;
198 | byte[] data = bitmap2Bytes(bitmap);
199 | if (data != null) {
200 | bitmap.recycle();
201 | return BitmapFactory.decodeByteArray(data, 0, data.length, options);
202 | } else {
203 | return bitmap;
204 | }
205 | }
206 |
207 | public static Bitmap rotaingBitmap(int angle, Bitmap bitmap) {
208 | Matrix matrix = new Matrix();
209 | matrix.postRotate(angle);
210 | Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
211 | bitmap.getWidth(), bitmap.getHeight(), matrix, true);
212 | return resizedBitmap;
213 | }
214 |
215 | private static byte[] bitmap2Bytes(Bitmap bm) {
216 | try {
217 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
218 | bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
219 | byte[] bytes = baos.toByteArray();
220 | baos.close();
221 | return bytes;
222 | } catch (IOException e) {
223 | e.printStackTrace();
224 | }
225 | return null;
226 | }
227 |
228 | public static final Bitmap grey(Bitmap bitmap) {
229 | int width = bitmap.getWidth();
230 | int height = bitmap.getHeight();
231 | Bitmap greyBitmap = Bitmap.createBitmap(width, height,
232 | Config.ARGB_8888);
233 | Canvas canvas = new Canvas(greyBitmap);
234 | Paint paint = new Paint();
235 | ColorMatrix colorMatrix = new ColorMatrix();
236 | colorMatrix.setSaturation(0);
237 | ColorMatrixColorFilter colorMatrixFilter = new ColorMatrixColorFilter(
238 | colorMatrix);
239 | paint.setColorFilter(colorMatrixFilter);
240 | canvas.drawBitmap(bitmap, 0, 0, paint);
241 | return greyBitmap;
242 | }
243 |
244 | public static Bitmap circular(Bitmap bitmap) {
245 | Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
246 | bitmap.getHeight(), Config.ARGB_8888);
247 | Canvas canvas = new Canvas(output);
248 | final Paint paint = new Paint();
249 | // 保证是方形,并且从中心画
250 | int width = bitmap.getWidth();
251 | int height = bitmap.getHeight();
252 | int w;
253 | int deltaX = 0;
254 | int deltaY = 0;
255 | if (width <= height) {
256 | w = width;
257 | deltaY = height - w;
258 | } else {
259 | w = height;
260 | deltaX = width - w;
261 | }
262 | final Rect rect = new Rect(deltaX, deltaY, w, w);
263 | final RectF rectF = new RectF(rect);
264 | paint.setAntiAlias(true);
265 | canvas.drawARGB(0, 0, 0, 0);
266 | // 圆形,所有只用一个
267 | int radius = (int) (Math.sqrt(w * w * 2.0d) / 2);
268 | canvas.drawRoundRect(rectF, radius, radius, paint);
269 | paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
270 | canvas.drawBitmap(bitmap, rect, rect, paint);
271 | return output;
272 | }
273 |
274 | public static final Bitmap alpha(Bitmap bitmap, int alpha) {
275 | float[] matrixItems = new float[]{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
276 | 1, 0, 0, 0, 0, 0, alpha / 255f, 0, 0, 0, 0, 0, 1};
277 | int width = bitmap.getWidth();
278 | int height = bitmap.getHeight();
279 | Bitmap alphaBitmap = Bitmap.createBitmap(width, height,
280 | Config.ARGB_8888);
281 | Canvas canvas = new Canvas(alphaBitmap);
282 | Paint paint = new Paint();
283 | ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
284 | ColorMatrixColorFilter colorMatrixFilter = new ColorMatrixColorFilter(
285 | colorMatrix);
286 | paint.setColorFilter(colorMatrixFilter);
287 | canvas.drawBitmap(bitmap, 0, 0, paint);
288 | return alphaBitmap;
289 | }
290 |
291 | /**
292 | * 对Bitmap做半透明玻璃玻璃效果
293 | *
294 | * @author Huyf Email:my519820363@gmail.com
295 | */
296 | public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {
297 |
298 | // Stack Blur v1.0 from
299 | // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
300 | //
301 | // Java Author: Mario Klingemann
302 | // http://incubator.quasimondo.com
303 | // created Feburary 29, 2004
304 | // Android port : Yahel Bouaziz
305 | // http://www.kayenko.com
306 | // ported april 5th, 2012
307 |
308 | // This is a compromise between Gaussian Blur and Box blur
309 | // It creates much better looking blurs than Box Blur, but is
310 | // 7x faster than my Gaussian Blur implementation.
311 | //
312 | // I called it Stack Blur because this describes best how this
313 | // filter works internally: it creates a kind of moving stack
314 | // of colors whilst scanning through the image. Thereby it
315 | // just has to add one new block of color to the right side
316 | // of the stack and remove the leftmost color. The remaining
317 | // colors on the topmost layer of the stack are either added on
318 | // or reduced by one, depending on if they are on the right or
319 | // on the left side of the stack.
320 | //
321 | // If you are using this algorithm in your code please add
322 | // the following line:
323 | //
324 | // Stack Blur Algorithm by Mario Klingemann
325 | Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
326 |
327 | if (radius < 1) {
328 | return (null);
329 | }
330 |
331 | int w = bitmap.getWidth();
332 | int h = bitmap.getHeight();
333 |
334 | int[] pix = new int[w * h];
335 | Log.e("pix", w + " " + h + " " + pix.length);
336 | bitmap.getPixels(pix, 0, w, 0, 0, w, h);
337 |
338 | int wm = w - 1;
339 | int hm = h - 1;
340 | int wh = w * h;
341 | int div = radius + radius + 1;
342 |
343 | int r[] = new int[wh];
344 | int g[] = new int[wh];
345 | int b[] = new int[wh];
346 | int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
347 | int vmin[] = new int[Math.max(w, h)];
348 |
349 | int divsum = (div + 1) >> 1;
350 | divsum *= divsum;
351 | int dv[] = new int[256 * divsum];
352 | for (i = 0; i < 256 * divsum; i++) {
353 | dv[i] = (i / divsum);
354 | }
355 |
356 | yw = yi = 0;
357 |
358 | int[][] stack = new int[div][3];
359 | int stackpointer;
360 | int stackstart;
361 | int[] sir;
362 | int rbs;
363 | int r1 = radius + 1;
364 | int routsum, goutsum, boutsum;
365 | int rinsum, ginsum, binsum;
366 |
367 | for (y = 0; y < h; y++) {
368 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
369 | for (i = -radius; i <= radius; i++) {
370 | p = pix[yi + Math.min(wm, Math.max(i, 0))];
371 | sir = stack[i + radius];
372 | sir[0] = (p & 0xff0000) >> 16;
373 | sir[1] = (p & 0x00ff00) >> 8;
374 | sir[2] = (p & 0x0000ff);
375 | rbs = r1 - Math.abs(i);
376 | rsum += sir[0] * rbs;
377 | gsum += sir[1] * rbs;
378 | bsum += sir[2] * rbs;
379 | if (i > 0) {
380 | rinsum += sir[0];
381 | ginsum += sir[1];
382 | binsum += sir[2];
383 | } else {
384 | routsum += sir[0];
385 | goutsum += sir[1];
386 | boutsum += sir[2];
387 | }
388 | }
389 | stackpointer = radius;
390 |
391 | for (x = 0; x < w; x++) {
392 |
393 | r[yi] = dv[rsum];
394 | g[yi] = dv[gsum];
395 | b[yi] = dv[bsum];
396 |
397 | rsum -= routsum;
398 | gsum -= goutsum;
399 | bsum -= boutsum;
400 |
401 | stackstart = stackpointer - radius + div;
402 | sir = stack[stackstart % div];
403 |
404 | routsum -= sir[0];
405 | goutsum -= sir[1];
406 | boutsum -= sir[2];
407 |
408 | if (y == 0) {
409 | vmin[x] = Math.min(x + radius + 1, wm);
410 | }
411 | p = pix[yw + vmin[x]];
412 |
413 | sir[0] = (p & 0xff0000) >> 16;
414 | sir[1] = (p & 0x00ff00) >> 8;
415 | sir[2] = (p & 0x0000ff);
416 |
417 | rinsum += sir[0];
418 | ginsum += sir[1];
419 | binsum += sir[2];
420 |
421 | rsum += rinsum;
422 | gsum += ginsum;
423 | bsum += binsum;
424 |
425 | stackpointer = (stackpointer + 1) % div;
426 | sir = stack[(stackpointer) % div];
427 |
428 | routsum += sir[0];
429 | goutsum += sir[1];
430 | boutsum += sir[2];
431 |
432 | rinsum -= sir[0];
433 | ginsum -= sir[1];
434 | binsum -= sir[2];
435 |
436 | yi++;
437 | }
438 | yw += w;
439 | }
440 | for (x = 0; x < w; x++) {
441 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
442 | yp = -radius * w;
443 | for (i = -radius; i <= radius; i++) {
444 | yi = Math.max(0, yp) + x;
445 |
446 | sir = stack[i + radius];
447 |
448 | sir[0] = r[yi];
449 | sir[1] = g[yi];
450 | sir[2] = b[yi];
451 |
452 | rbs = r1 - Math.abs(i);
453 |
454 | rsum += r[yi] * rbs;
455 | gsum += g[yi] * rbs;
456 | bsum += b[yi] * rbs;
457 |
458 | if (i > 0) {
459 | rinsum += sir[0];
460 | ginsum += sir[1];
461 | binsum += sir[2];
462 | } else {
463 | routsum += sir[0];
464 | goutsum += sir[1];
465 | boutsum += sir[2];
466 | }
467 |
468 | if (i < hm) {
469 | yp += w;
470 | }
471 | }
472 | yi = x;
473 | stackpointer = radius;
474 | for (y = 0; y < h; y++) {
475 | // Preserve alpha channel: ( 0xff000000 & pix[yi] )
476 | pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16)
477 | | (dv[gsum] << 8) | dv[bsum];
478 |
479 | rsum -= routsum;
480 | gsum -= goutsum;
481 | bsum -= boutsum;
482 |
483 | stackstart = stackpointer - radius + div;
484 | sir = stack[stackstart % div];
485 |
486 | routsum -= sir[0];
487 | goutsum -= sir[1];
488 | boutsum -= sir[2];
489 |
490 | if (x == 0) {
491 | vmin[y] = Math.min(y + r1, hm) * w;
492 | }
493 | p = x + vmin[y];
494 |
495 | sir[0] = r[p];
496 | sir[1] = g[p];
497 | sir[2] = b[p];
498 |
499 | rinsum += sir[0];
500 | ginsum += sir[1];
501 | binsum += sir[2];
502 |
503 | rsum += rinsum;
504 | gsum += ginsum;
505 | bsum += binsum;
506 |
507 | stackpointer = (stackpointer + 1) % div;
508 | sir = stack[stackpointer];
509 |
510 | routsum += sir[0];
511 | goutsum += sir[1];
512 | boutsum += sir[2];
513 |
514 | rinsum -= sir[0];
515 | ginsum -= sir[1];
516 | binsum -= sir[2];
517 |
518 | yi += w;
519 | }
520 | }
521 |
522 | Log.e("pix", w + " " + h + " " + pix.length);
523 | bitmap.setPixels(pix, 0, w, 0, 0, w, h);
524 | return (bitmap);
525 | }
526 |
527 |
528 | /**
529 | * 质量压缩
530 | * @param image
531 | * @return
532 | */
533 | private static Bitmap compressImage(Bitmap image) {
534 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
535 | int options = 80;
536 | image.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
537 | while ( baos.toByteArray().length / 1024 > 150) { //循环判断如果压缩后图片是否大于80kb,大于继续压缩
538 | baos.reset();//重置baos即清空baos
539 | options -= 10;//每次都减少10
540 | Log.i("test", "压缩了一次");
541 | image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
542 | }
543 | ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
544 | Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
545 | return bitmap;
546 | }
547 |
548 |
549 | /**
550 | * 获取压缩图片
551 | * @param srcPath
552 | * @return
553 | */
554 | public static File getCompressImage(String srcPath) {
555 | Options newOpts = new Options();
556 | //开始读入图片,此时把options.inJustDecodeBounds 设回true了
557 | newOpts.inJustDecodeBounds = true;
558 | Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空
559 | newOpts.inPreferredConfig = Config.RGB_565;
560 | newOpts.inJustDecodeBounds = false;
561 | int w = newOpts.outWidth;
562 | int h = newOpts.outHeight;
563 | //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
564 | float hh = 800f;//这里设置高度为800f
565 | float ww = 480f;//这里设置宽度为480f
566 | //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
567 | int be = 1;//be=1表示不缩放
568 | if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
569 | be = (int) (newOpts.outWidth / ww);
570 | } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
571 | be = (int) (newOpts.outHeight / hh);
572 | }
573 | if (be <= 0)
574 | be = 1;
575 | newOpts.inSampleSize = be;//设置缩放比例
576 | //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
577 | bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
578 |
579 | return saveBitmap2file(compressImage(bitmap));//压缩好比例大小后再进行质量压缩
580 | }
581 |
582 | /**
583 | * bitmap转file
584 | * @param bmp
585 | * @return
586 | */
587 | public static File saveBitmap2file(Bitmap bmp){
588 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
589 | bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
590 | byte[] byteArray = stream.toByteArray();
591 |
592 | File imageFile = null;
593 | try {
594 | imageFile = File.createTempFile("tempImage" + System.currentTimeMillis(), ".png");
595 | } catch (IOException e) {
596 | e.printStackTrace();
597 | }
598 |
599 | FileOutputStream fstream = null;
600 | try {
601 | fstream = new FileOutputStream(imageFile);
602 | BufferedOutputStream bStream = new BufferedOutputStream(fstream);
603 | bStream.write(byteArray);
604 | if (bStream != null) {
605 | bStream.close();
606 | }
607 | } catch (IOException e) {
608 | e.printStackTrace();
609 | }
610 | return imageFile;
611 |
612 | }
613 |
614 | /**
615 | * 获取压缩图片
616 | * @param image
617 | * @return
618 | */
619 | public static Bitmap getCompressImage(Bitmap image) {
620 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
621 | image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
622 | if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
623 | baos.reset();//重置baos即清空baos
624 | image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
625 | }
626 | ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
627 | Options newOpts = new Options();
628 | //开始读入图片,此时把options.inJustDecodeBounds 设回true了
629 | newOpts.inJustDecodeBounds = true;
630 | Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
631 | newOpts.inJustDecodeBounds = false;
632 | int w = newOpts.outWidth;
633 | int h = newOpts.outHeight;
634 | //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
635 | float hh = 800f;//这里设置高度为800f
636 | float ww = 480f;//这里设置宽度为480f
637 | //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
638 | int be = 1;//be=1表示不缩放
639 | if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
640 | be = (int) (newOpts.outWidth / ww);
641 | } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
642 | be = (int) (newOpts.outHeight / hh);
643 | }
644 | if (be <= 0)
645 | be = 1;
646 | newOpts.inSampleSize = be;//设置缩放比例
647 | //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
648 | isBm = new ByteArrayInputStream(baos.toByteArray());
649 | bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
650 | return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
651 | }
652 |
653 |
654 | }
655 |
--------------------------------------------------------------------------------