图片处理

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

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

https://github.com/bumptech/glide
compile ‘com.github.bumptech.glide:glide:3.7.0’

2.加载网络图片

/**
 * Created by mChenys on 2016/6/6.
 */
public class TestGlideActivity extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        intresourceId = R.drawable.test;
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        Glide.with(this).
                load(resourceId).
                asBitmap().
                into(targetView);
    }
}

4.加载本地文件图片

public class TestGlideActivity extendsActivity {
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        File file =newFile(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 extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(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);
    }
}

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

public class TestGlideActivity extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
        @Override
        protectedvoidonCreate(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种模式:
DiskCacheStrategy.NONE:什么都不缓存
DiskCacheStrategy.SOURCE:仅缓存原图(全分辨率的图片)
DiskCacheStrategy.RESULT:仅缓存最终的图片,即修改了尺寸或者转换后的图片
DiskCacheStrategy.ALL:缓存所有版本的图片,默认模式
    public class TestGlideActivity extendsActivity {
        @Override
        protectedvoidonCreate(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 的 &lt;application&gt; 标签内去声明这个SimpleGlideModule。
 * Created by mChenys on 2016/6/10.
 */
public class SimpleGlideModule implementsGlideModule {
    publicstaticDiskCache cache;

    @Override
    publicvoidapplyOptions(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(newDiskCache.Factory() {
            @Override
            publicDiskCache build() {
                returncache;
            }
        });
        //设置memory和Bitmap池的大小
        MemorySizeCalculator calculator =newMemorySizeCalculator(context);
        intdefaultMemoryCacheSize = calculator.getMemoryCacheSize();
        intdefaultBitmapPoolSize = calculator.getBitmapPoolSize();

        intcustomMemoryCacheSize = (int) (1.2* defaultMemoryCacheSize);
        intcustomBitmapPoolSize = (int) (1.2* defaultBitmapPoolSize);

        builder.setMemoryCache(newLruResourceCache(customMemoryCacheSize));
        builder.setBitmapPool(newLruBitmapPool(customBitmapPoolSize));
    }

    @Override
    publicvoidregisterComponents(Context context, Glide glide) {
    }
}

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

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

/**
    * 高优先级加载
    * @param url
    * @param imageView
    * @param listener
    */
   publicstaticvoid loadImageWithHighPriority(Object url,ImageView imageView,finalLoaderListener listener) {
       if(url ==null) {
           if(listener !=null) {
               listener.onError();
           }
       }else{
           Glide.with(imageView.getContext()).
                   load(url).
                   asBitmap().
                   priority(Priority.HIGH).//高优先级
                   dontAnimate().
                   listener(newRequestListener&lt;Object, Bitmap&gt;() {
                       @Override
                       publicbooleanonException(Exception e, Object model, Target&lt;Bitmap&gt; target,booleanisFirstResource) {
                           if(null!= listener) {
                               listener.onError();
                           }
                           returnfalse;
                       }

                       @Override
                       publicbooleanonResourceReady(Bitmap resource, Object model, Target&lt;Bitmap&gt; target,booleanisFromMemoryCache,booleanisFirstResource) {
                           if(null!= listener) {
                               listener.onSuccess();
                           }
                           returnfalse;
                       }
                   }).into(imageView);
       }
   }

14.设置加载缩略图

通过设置缩略图,我们可以在显示目标图片之前先展示一个第分辨率或者其他图片,当全分辨率的目标图片在后台加载完成后,
Glide会自动切换显示全像素的目标图片.
设置缩略图有2种方式:
通过thumbnail(float)指定0.0f~1.0f的原始图像大小,例如全像素的大小是500*500,如果设置为thumbnail为0.1f,即目标图片的10%,显示的缩略图大小就是50*50;

public class TestGlideActivity extendsActivity {
    @Override
    protectedvoidonCreate(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 extendsActivity {
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ImageView targetView = (ImageView) findViewById(R.id.iv_target);
        //缩略图请求
        DrawableRequestBuilder&lt;String&gt; 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 extendsActivity {
    @Override
    protectedvoidonCreate(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(newBlurTransformation(this)).//高斯模糊处理
                into(targetView);
    }
}

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

圆图处理

public class CropCircleTransformation implementsTransformation&lt;Bitmap&gt; {

    privateBitmapPool mBitmapPool;

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

    publicCropCircleTransformation(BitmapPool pool) {
        this.mBitmapPool = pool;
    }

    @Override
    publicResource&lt;Bitmap&gt; transform(Resource&lt;Bitmap&gt; resource,intoutWidth, int outHeight) {
        Bitmap source = resource.get();
        intsize = Math.min(source.getWidth(), source.getHeight());

        intwidth = (source.getWidth() - size) /2;
        intheight = (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 =newCanvas(bitmap);
        Paint paint =newPaint();
        BitmapShader shader =
                newBitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
        if(width !=0 || height != 0) {
            // source isn't square, move viewport to center
            Matrix matrix =newMatrix();
            matrix.setTranslate(-width, -height);
            shader.setLocalMatrix(matrix);
        }
        paint.setShader(shader);
        paint.setAntiAlias(true);

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

        returnBitmapResource.obtain(bitmap, mBitmapPool);
    }

    @OverridepublicString getId() {
        return"CropCircleTransformation()";
    }
}

圆角处理

    public class RoundedCornersTransformation implementsTransformation&lt;Bitmap&gt; {

        privateBitmapPool mBitmapPool;

        privateintradius;
        privateintmargin;

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

        publicRoundedCornersTransformation(BitmapPool pool,intradius, int margin) {
            mBitmapPool = pool;
            this.radius = radius;
            this.margin = margin;
        }

        @Override
        publicResource&lt;Bitmap&gt; transform(Resource&lt;Bitmap&gt; resource,intoutWidth, int outHeight) {
            Bitmap source = resource.get();

            intwidth = source.getWidth();
            intheight = 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 =newCanvas(bitmap);
            Paint paint =newPaint();
            paint.setAntiAlias(true);
            paint.setShader(newBitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
            canvas.drawRoundRect(newRectF(margin, margin, width - margin, height - margin), radius, radius,
                    paint);

            returnBitmapResource.obtain(bitmap, mBitmapPool);
        }

        @OverridepublicString getId() {
            return"RoundedTransformation(radius="+ radius + ", margin="+ margin + ")";
        }
    }

灰度处理

    public class GrayscaleTransformation implementsTransformation&lt;Bitmap&gt; {

        privateBitmapPool mBitmapPool;

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

        publicGrayscaleTransformation(BitmapPool pool) {
            mBitmapPool = pool;
        }

        @Override
        publicResource&lt;Bitmap&gt; transform(Resource&lt;Bitmap&gt; resource,intoutWidth, int outHeight) {
            Bitmap source = resource.get();

            intwidth = source.getWidth();
            intheight = 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 =newCanvas(bitmap);
            ColorMatrix saturation =newColorMatrix();
            saturation.setSaturation(0f);
            Paint paint =newPaint();
            paint.setColorFilter(newColorMatrixColorFilter(saturation));
            canvas.drawBitmap(source,0,0, paint);

            returnBitmapResource.obtain(bitmap, mBitmapPool);
        }

        @OverridepublicString getId() {
            return"GrayscaleTransformation()";
        }
    }

旋转处理

    public class RotateTransformation extendsBitmapTransformation {

        privatefloatrotateRotationAngle = 0f;

        publicRotateTransformation(Context context,floatrotateRotationAngle) {
            super(context);

            this.rotateRotationAngle = rotateRotationAngle;
        }

        @Override
        protectedBitmap transform(BitmapPool pool, Bitmap toTransform,int outWidth, intoutHeight) {
            Matrix matrix =newMatrix();

            matrix.postRotate(rotateRotationAngle);

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

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

高斯模糊处理

    public class BlurTransformation implementsTransformation<Bitmap> {

        privatestaticint MAX_RADIUS = 25;
        privatestaticint DEFAULT_DOWN_SAMPLING =1;

        privateContext mContext;
        privateBitmapPool mBitmapPool;

        privateintmRadius;
        privateintmSampling;

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

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

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

        publicBlurTransformation(Context context,intradius) {
            this(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);
        }

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

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

        @Override
        publicResource&lt;Bitmap&gt; transform(Resource&lt;Bitmap&gt; resource,intoutWidth, int outHeight) {
            Bitmap source = resource.get();

            intwidth = source.getWidth();
            intheight = source.getHeight();
            intscaledWidth = width / mSampling;
            intscaledHeight = 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 =newCanvas(bitmap);
            canvas.scale(1/ (float) mSampling,1 / (float) mSampling);
            Paint paint =newPaint();
            paint.setFlags(Paint.FILTER_BITMAP_FLAG);
            canvas.drawBitmap(source,0,0, paint);

            if(Build.VERSION.SDK_INT &gt;= 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);
            }

            returnBitmapResource.obtain(bitmap, mBitmapPool);
        }

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

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

    public static Bitmap blur(Bitmap sentBitmap,intradius, booleancanReuseInBitmap)     {

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

        if(radius &lt;1) {
            return(null);
        }

        intw = bitmap.getWidth();
        inth = bitmap.getHeight();

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

        intwm = w -1;
        inthm = h -1;
        intwh = w * h;
        intdiv = radius + radius +1;

        intr[] =new int[wh];
        intg[] =new int[wh];
        intb[] =new int[wh];
        intrsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        intvmin[] =new int[Math.max(w, h)];

        intdivsum = (div +1) &gt;&gt;1;
        divsum *= divsum;
        intdv[] =new int[256* divsum];
        for(i =0; i &lt;256* divsum; i++) {
            dv[i] = (i / divsum);
        }

        yw = yi =0;

        int[][] stack =newint[div][3];
        intstackpointer;
        intstackstart;
        int[] sir;
        intrbs;
        intr1 = radius +1;
        introutsum, goutsum, boutsum;
        intrinsum, ginsum, binsum;

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

            if(i &lt; hm) {
                yp += w;
            }
        }
        yi = x;
        stackpointer = radius;
        for(y =0; y &lt; h; y++) {
            // Preserve alpha channel: ( 0xff000000 &amp; pix[yi] )
            pix[yi] = (0xff000000&amp; pix[yi]) | (dv[rsum] &lt;&lt;16) | (dv[gsum] &lt;&lt;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)
    publicstaticBitmap blur(Context context, Bitmap blurredBitmap,intradius) 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);
        }
        returnblurredBitmap;
    }
}

16.动画处理

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值