Glide图片加载库的使用

Glide是 Google推荐的图片加载库,它可以支持来自url,Android资源,文件,Uri中的图片加载,同时还支持gif图片的加载,以及各种图片显示前的bitmap处理(例如:圆角图片,圆形图片,高斯模糊,旋转,灰度等等),缓存处理,请求优先级处理,动画处理,缩略图处理,图片大小自定义等等.可谓是非常的强大.


1.添加Glide库

需要在build.gradle中加入依赖,目前最新的版本是3.7.0,Glide库地址

 compile 'com.github.bumptech.glide:glide:3.7.0'

2.加载网络图片

/**
 * Created by mChenys on 2016/6/6.
 */
public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        String url = "http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png";
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(url).
                asBitmap(). //强制处理为bitmap
                into(targetView);//显示到目标View中
    }
}

3.加载资源图片


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        int resourceId = R.drawable.test;
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(resourceId).
                asBitmap().
                into(targetView);
    }
}

4.加载本地文件图片


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(file).
                asBitmap().
                into(targetView);
    }
}

5.从Uri中加载

/**
 * Created by mChenys on 2016/6/6.
 */
public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.drawable.test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(uri).
                asBitmap().
                into(targetView);
    }
}

6.加载gif图片


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.smail).
                asGif().//注意:这里显示的指明了要加载的是gif图片,当然即使不指明,glide也会自己判断.
                into(targetView);
    }
}

效果图:
Glide图片加载库的使用_第1张图片


7.设置默认图片和加载失败时显示的图片


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.test).
                asBitmap().
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                into(targetView);
    }
}

8.淡入显示效果


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade().//淡入显示,注意:如果设置了这个,则必须要去掉asBitmap
                into(targetView);
    }
}

另外,crossFade还可以接收一个参数来设置淡入显示效果的持续时间,crossFade(int duration);
如果你想直接显示图片,而不是淡入显示图片,则可以通过dontAnimate()方法设置.


9.调整图片像素大小


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade(1000).//淡入显示的时间,注意:如果设置了这个,则必须要去掉asBitmap
                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                into(targetView);
    }
}

10.设置CenterCrop,FitCenter

CenterCrop,FitCenter都是对目标图片进行裁剪,了解过ImageView的ScaleType属性就知道,这2种裁剪方式在ImageView上也是有的,分别对应ImageView的ImageView.ScaleType.CENTER_CROP和mageView.ScaleType.FIT_CENTER的.


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                centerCrop().//中心裁剪,缩放填充至整个ImageView
                into(targetView);
    }
}

11.缓存策略设置

内存缓存设置,通过skipMemoryCache(boolean)来设置是否需要缓存到内存,默认是会缓存到内存的.

/**
 * Created by mChenys on 2016/6/6.
 */
public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
                override(80,80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                centerCrop().//中心裁剪,缩放填充至整个ImageView
                skipMemoryCache(true).//跳过内存缓存
                into(targetView);
    }
}

磁盘缓存,磁盘缓存通过diskCacheStrategy(DiskCacheStrategy)来设置,DiskCacheStrategy一共有4种模式:

  1. DiskCacheStrategy.NONE:什么都不缓存
  2. DiskCacheStrategy.SOURCE:仅缓存原图(全分辨率的图片)
  3. DiskCacheStrategy.RESULT:仅缓存最终的图片,即修改了尺寸或者转换后的图片
  4. DiskCacheStrategy.ALL:缓存所有版本的图片,默认模式

public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        targetView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
                override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                centerCrop().//中心裁剪,缩放填充至整个ImageView
                skipMemoryCache(true).//跳过内存缓存
                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
                into(targetView);
    }
}

12.缓存设置

在GlideModule 中,我们可以设置磁盘缓存的位置,磁盘缓存的大小和内存缓存的大小,同时还可以设置图片的显示质量.

要是用GlideModule ,需要创建它的实现类,然后在manifests中申明实现类的全类路径:

  <meta-data
            android:name="com.example.mchenys.httputilsdemo.image.glide.module.SimpleGlideModule"
            android:value="GlideModule" />

GlideModule 的实现类,需要实现applyOptions方法:

/**
 * 所以你知道要创建一个额外的类去定制 Glide。
 * 下一步是要全局的去声明这个类,让 Glide 知道它应该在哪里被加载和使用。
 * Glide 会扫描 AndroidManifest.xml 为 Glide module 的 meta 声明。
 * 因此,你必须在 AndroidManifest.xml 的  标签内去声明这个SimpleGlideModule。
 * Created by mChenys on 2016/6/10.
 */
public class SimpleGlideModule implements GlideModule {
    public static DiskCache cache;

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // 在 Android 中有两个主要的方法对图片进行解码:ARGB8888 和 RGB565。前者为每个像素使用了 4 个字节,
        // 后者仅为每个像素使用了 2 个字节。ARGB8888 的优势是图像质量更高以及能存储一个 alpha 通道。
        // Picasso 使用 ARGB8888,Glide 默认使用低质量的 RGB565。
        // 对于 Glide 使用者来说:你使用 Glide module 方法去改变解码规则。
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
        //设置缓存目录
        File cacheDir = PathUtils.getDiskCacheDir(context, CacheConfig.IMG_DIR);

        cache = DiskLruCacheWrapper.get(cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);// 250 MB 
        builder.setDiskCache(new DiskCache.Factory() {
            @Override
            public DiskCache build() {
                return cache;
            }
        });
        //设置memory和Bitmap池的大小
        MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
        int defaultBitmapPoolSize = calculator.getBitmapPoolSize();

        int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
        int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);

        builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize));
        builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
    }
}

13.设置图片请求的优先级

Glide 可以用 Priority 枚举来设置图片的加载优先级,这样我们就可以针对那些需要显示的图片设置高的优先级了.
Priority 有4种级别:
Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE
例如:

 /**
     * 高优先级加载
     * @param url
     * @param imageView
     * @param listener
     */
    public static void loadImageWithHighPriority(Object url,ImageView imageView, final LoaderListener listener) {
        if (url == null) {
            if (listener != null) {
                listener.onError();
            }
        } else {
            Glide.with(imageView.getContext()).
                    load(url).
                    asBitmap().
                    priority(Priority.HIGH).//高优先级
                    dontAnimate().
                    listener(new RequestListener() {
                        @Override
                        public boolean onException(Exception e, Object model, Target target, boolean isFirstResource) {
                            if (null != listener) {
                                listener.onError();
                            }
                            return false;
                        }

                        @Override
                        public boolean onResourceReady(Bitmap resource, Object model, Target target, boolean isFromMemoryCache, boolean isFirstResource) {
                            if (null != listener) {
                                listener.onSuccess();
                            }
                            return false;
                        }
                    }).into(imageView);
        }
    }

14.设置加载缩略图

通过设置缩略图,我们可以在显示目标图片之前先展示一个第分辨率或者其他图片,当全分辨率的目标图片在后台加载完成后,
Glide会自动切换显示全像素的目标图片.

设置缩略图有2种方式:
通过thumbnail(float)指定0.0f~1.0f的原始图像大小,例如全像素的大小是500*500,如果设置为thumbnail为0.1f,即目标图片的10%,显示的缩略图大小就是50*50;


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        Glide.with(this).
                load(R.drawable.test).
                placeholder(R.drawable.bg_loading).//加载中显示的图片
                error(R.drawable.bg_error).//加载失败时显示的图片
                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
                override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                centerCrop().//中心裁剪,缩放填充至整个ImageView
                skipMemoryCache(true).//跳过内存缓存
                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
                thumbnail(0.1f).//10%的原图大小
                into(targetView);
    }
}

通过thumbnail(DrawableRequestBuilder)方式来指定缩略图,该缩略图可以使用load的所有方式(网络,文件,uri,资源)加载.


public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        //缩略图请求
        DrawableRequestBuilder thumbnailRequest = Glide
                .with(this)
                .load("http://www.qq745.com/uploads/allimg/141106/1-141106153Q5.png");

        Glide.with(this).
                load(R.drawable.test).
//                placeholder(R.drawable.bg_loading).//加载中显示的图片
//                error(R.drawable.bg_error).//加载失败时显示的图片
//                crossFade(1000).//淡入淡出,注意:如果设置了这个,则必须要去掉asBitmap
                override(80, 80).//设置最终显示的图片像素为80*80,注意:这个是像素,而不是控件的宽高
                centerCrop().//中心裁剪,缩放填充至整个ImageView
                skipMemoryCache(true).//跳过内存缓存
                diskCacheStrategy(DiskCacheStrategy.RESULT).//保存最终图片
                thumbnail(thumbnailRequest).//设置缩略图
                into(targetView);
    }
}

15.Transformations Bitmap

在显示目标图片之前,我们可以对目标图片的Bitmap进行相应的处理,例如::圆角图片,圆形图片,高斯模糊,旋转,灰度等等.
只需要实现Transformation接口即可,该接口的transform方法会返回显示图片前的Bitmap对象,在该方法中对
Bitmap的任何处理,都会影响到最终的显示结果.
当然,如果你只是想要对图片做常规的 bitmap 转换,你可以继承抽象类BitmapTransformation,它简化了Transformation接口的实现,这应该能覆盖大部分的应用场景了。

使用的时候,通过transform(Transformation… transformations)来设置.例如:

public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.test).
                asBitmap().
                transform(new BlurTransformation(this)).//高斯模糊处理
                into(targetView);
    }
}

下面贴出常用的几个Bitmap的转换处理的代码,在github上也有glide-transformations-master库.

圆图处理

public class CropCircleTransformation implements Transformation<Bitmap> {

    private BitmapPool mBitmapPool;

    public CropCircleTransformation(Context context) {
        this(Glide.get(context).getBitmapPool());
    }

    public CropCircleTransformation(BitmapPool pool) {
        this.mBitmapPool = pool;
    }

    @Override
    public Resource transform(Resource resource, int outWidth, int outHeight) {
        Bitmap source = resource.get();
        int size = Math.min(source.getWidth(), source.getHeight());

        int width = (source.getWidth() - size) / 2;
        int height = (source.getHeight() - size) / 2;

        Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        BitmapShader shader =
                new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
        if (width != 0 || height != 0) {
            // source isn't square, move viewport to center
            Matrix matrix = new Matrix();
            matrix.setTranslate(-width, -height);
            shader.setLocalMatrix(matrix);
        }
        paint.setShader(shader);
        paint.setAntiAlias(true);

        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);

        return BitmapResource.obtain(bitmap, mBitmapPool);
    }

    @Override public String getId() {
        return "CropCircleTransformation()";
    }
}

圆角处理

public class RoundedCornersTransformation implements Transformation<Bitmap> {

    private BitmapPool mBitmapPool;

    private int radius;
    private int margin;

    public RoundedCornersTransformation(Context context, int radius, int margin) {
        this(Glide.get(context).getBitmapPool(), radius, margin);
    }

    public RoundedCornersTransformation(BitmapPool pool, int radius, int margin) {
        mBitmapPool = pool;
        this.radius = radius;
        this.margin = margin;
    }

    @Override
    public Resource transform(Resource resource, int outWidth, int outHeight) {
        Bitmap source = resource.get();

        int width = source.getWidth();
        int height = source.getHeight();

        Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888);
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
        canvas.drawRoundRect(new RectF(margin, margin, width - margin, height - margin), radius, radius,
                paint);

        return BitmapResource.obtain(bitmap, mBitmapPool);
    }

    @Override public String getId() {
        return "RoundedTransformation(radius=" + radius + ", margin=" + margin + ")";
    }
}

灰度处理

public class GrayscaleTransformation implements Transformation<Bitmap> {

    private BitmapPool mBitmapPool;

    public GrayscaleTransformation(Context context) {
        this(Glide.get(context).getBitmapPool());
    }

    public GrayscaleTransformation(BitmapPool pool) {
        mBitmapPool = pool;
    }

    @Override
    public Resource transform(Resource resource, int outWidth, int outHeight) {
        Bitmap source = resource.get();

        int width = source.getWidth();
        int height = source.getHeight();

        Bitmap.Config config =
                source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888;
        Bitmap bitmap = mBitmapPool.get(width, height, config);
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(width, height, config);
        }

        Canvas canvas = new Canvas(bitmap);
        ColorMatrix saturation = new ColorMatrix();
        saturation.setSaturation(0f);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(saturation));
        canvas.drawBitmap(source, 0, 0, paint);

        return BitmapResource.obtain(bitmap, mBitmapPool);
    }

    @Override public String getId() {
        return "GrayscaleTransformation()";
    }
}

旋转处理

public class RotateTransformation extends BitmapTransformation {

    private float rotateRotationAngle = 0f;

    public RotateTransformation(Context context, float rotateRotationAngle) {
        super(context);

        this.rotateRotationAngle = rotateRotationAngle;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Matrix matrix = new Matrix();

        matrix.postRotate(rotateRotationAngle);

        return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
    }

    @Override
    public String getId() {
        return "rotate" + rotateRotationAngle;
    }
}

高斯模糊处理

public class BlurTransformation implements Transformation {

    private static int MAX_RADIUS = 25;
    private static int DEFAULT_DOWN_SAMPLING = 1;

    private Context mContext;
    private BitmapPool mBitmapPool;

    private int mRadius;
    private int mSampling;

    public BlurTransformation(Context context) {
        this(context, Glide.get(context).getBitmapPool(), MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
    }

    public BlurTransformation(Context context, BitmapPool pool) {
        this(context, pool, MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
    }

    public BlurTransformation(Context context, BitmapPool pool, int radius) {
        this(context, pool, radius, DEFAULT_DOWN_SAMPLING);
    }

    public BlurTransformation(Context context, int radius) {
        this(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);
    }

    public BlurTransformation(Context context, BitmapPool pool, int radius, int sampling) {
        mContext = context;
        mBitmapPool = pool;
        mRadius = radius;
        mSampling = sampling;
    }

    public BlurTransformation(Context context, int radius, int sampling) {
        mContext = context;
        mBitmapPool = Glide.get(context).getBitmapPool();
        mRadius = radius;
        mSampling = sampling;
    }

    @Override
    public Resource transform(Resource resource, int outWidth, int outHeight) {
        Bitmap source = resource.get();

        int width = source.getWidth();
        int height = source.getHeight();
        int scaledWidth = width / mSampling;
        int scaledHeight = height / mSampling;

        Bitmap bitmap = mBitmapPool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        canvas.scale(1 / (float) mSampling, 1 / (float) mSampling);
        Paint paint = new Paint();
        paint.setFlags(Paint.FILTER_BITMAP_FLAG);
        canvas.drawBitmap(source, 0, 0, paint);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            try {
                bitmap = RSBlur.blur(mContext, bitmap, mRadius);
            } catch (RSRuntimeException e) {
                bitmap = FastBlur.blur(bitmap, mRadius, true);
            }
        } else {
            bitmap = FastBlur.blur(bitmap, mRadius, true);
        }

        return BitmapResource.obtain(bitmap, mBitmapPool);
    }

    @Override public String getId() {
        return "BlurTransformation(radius=" + mRadius + ", sampling=" + mSampling + ")";
    }
}

网上提供的FastBlur,可兼容低版本的高斯模糊处理

public class FastBlur {

    public static Bitmap blur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {

        Bitmap bitmap;
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }

        if (radius < 1) {
            return (null);
        }

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);

        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;

        int r[] = new int[wh];
        int g[] = new int[wh];
        int b[] = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int vmin[] = new int[Math.max(w, h)];

        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int dv[] = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; i++) {
            dv[i] = (i / divsum);
        }

        yw = yi = 0;

        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;

        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;

            for (x = 0; x < w; x++) {

                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];

                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;

                sir = stack[i + radius];

                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];

                rbs = r1 - Math.abs(i);

                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;

                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }

                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;

                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];

                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];

                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];

                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];

                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];

                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;

                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];

                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];

                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];

                yi += w;
            }
        }

        bitmap.setPixels(pix, 0, w, 0, 0, w, h);

        return (bitmap);
    }
}

RenderScript处理高斯模糊

android4.3之后可使用,需要在build.gradle中配置:

defaultConfig {

        //BlurTransformation
        renderscriptTargetApi 23
        renderscriptSupportModeEnabled true
}
public class RSBlur {

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static Bitmap blur(Context context, Bitmap blurredBitmap, int radius) throws RSRuntimeException {
        try {
            RenderScript rs = RenderScript.create(context);
            Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_NONE,
                    Allocation.USAGE_SCRIPT);
            Allocation output = Allocation.createTyped(rs, input.getType());
            ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

            blur.setInput(input);
            blur.setRadius(radius);
            blur.forEach(output);
            output.copyTo(blurredBitmap);
            rs.destroy();
        } catch (RSRuntimeException e) {
            blurredBitmap = FastBlur.blur(blurredBitmap, radius, true);
        }
        return blurredBitmap;
    }
}

16.动画处理

通过animate()方法可以设置xml文件定义的4种补间动画(alpha、scale、translate、rotate)
例如:

res\anim\left_in.xml



<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromXDelta="-50%p"
        android:toXDelta="0"/>
    <alpha
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromAlpha="0.0"
        android:toAlpha="1.0"/>
set>

使用方式:

public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(R.drawable.test).
                asBitmap().
                animate(R.anim.left_in).//加载xml文件定义的动画
                into(targetView);
    }
}

处理此外,还可以通过animate指定属性动画:

public class TestGlideActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);

        ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {
            @Override
            public void animate(View view) {
                //设置属性动画
                ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationX", -500f, 0f);
                ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
                ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f);
                ObjectAnimator moveTop = ObjectAnimator.ofFloat(view, "translationY", 0f, -2000, 0f);
                AnimatorSet animSet = new AnimatorSet();
                //先左进,然后旋转伴随淡入效果,最后移动向上
                animSet.play(rotate).with(fadeInOut).after(moveIn).before(moveTop);
                animSet.setDuration(5000);
                animSet.start();
            }
        };
        Glide.with(this).
                load(R.drawable.test).
                asBitmap().
                animate(animationObject).//加载属性动画
                into(targetView);
    }
}

你可能感兴趣的:(Android)