转自:https://ligboy.org/?p=380

对于不需要看废话的请直接Show me the code

对于模糊处理,一般的解决方案有四种:

  1. Java实现的算法处理;
  2. NDK实现的算法处理;
  3. RenderScript处理;
  4. openGL处理;

这四种方案的性能考虑的话,一般来讲应该是: 1 < 3 < 2  < 4 (2、3的性能非常接近),不过当属RenderScript方式最为简便(很显然嘛,平台无关性)。

RenderScript是Android自SDK17提供的一套平台无关计算密集脚本,它使用C99语法脚本,可以实现高性能的计算,而其包含大量内联函数,其中就包括了我们今天用到的:ScriptIntrinsicBlur,这是一个高斯模糊处理内联函数,一般系统用来进行阴影的计算处理。

上面有提到RenderScript是自SDK17引入的,但是Android 团队为我们提供了RenderScript support library,而起在Gradle-base的项目中的引入也极其简单,仅需要在module build.gradle设置以下11、12两行即可:

android {compileSdkVersion 23buildToolsVersion "23.0.2"defaultConfig {applicationId "org.ligboy.backsound"minSdkVersion 15targetSdkVersion 23versionCode 1versionName "1.0"renderscriptTargetApi 20renderscriptSupportModeEnabled true}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

接下来简单说说 ScriptIntrinsicBlur,使用它虽然很方便,但是也是有弊端的,模糊radius不能超过25.0f,不过我们可以通过缩小原图抽样的方式变相的进行扩大半径。

Glide是一个优秀的图片加载缓存处理等一系列功能的框架,它优雅而且使用渐变,扩展也很容易,Glide就提供了自定义Transformation的方式进行扩展图片的处理

到了这里就是通过自定义Transformation的方式,详细的这里就不赘述了,感兴趣可以查看Glide官方文档:Transformation。需要特别提到的是,每个Transformation都有一个String getId()的回调,该ID用于在对处理后的图片进行缓存时的文件命名,这样当下次相同图片使用相同Transformation时,则无需任何实际处理,直接读取缓存文件,所以我们实现时的ID需要同时关联所有的调整参数,参数改变的ID也应该相应改变。下面就是我自定义的BlurTransformation

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.annotation.FloatRange;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptIntrinsicBlur;import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.bumptech.glide.request.target.Target;/*** Georgia Blur Transformation* <p>* @author Ligboy.Liu ligboy@gmail.com.*/
public class BlurTransformation extends BitmapTransformation {private static final String ID = "org.ligboy.glide.BlurTransformation";public static final float DEFAULT_RADIUS = 25.0f;public static final float MAX_RADIUS = 25.0f;private static final float DEFAULT_SAMPLING = 1.0f;private Context mContext;private float mSampling = DEFAULT_SAMPLING;private float mRadius;private int mColor;public static class Builder {private Context mContext;private float mRadius = DEFAULT_RADIUS;private int mColor = Color.TRANSPARENT;public Builder(Context mContext) {this.mContext = mContext;}public float getRadius() {return mRadius;}public Builder setRadius(float radius) {mRadius = radius;return this;}public int getColor() {return mColor;}public Builder setColor(int color) {mColor = color;return this;}public BlurTransformation build() {return new BlurTransformation(mContext, mRadius, mColor);}}/**** @param context Context* @param radius The blur's radius.* @param color The color filter for blurring.*/public BlurTransformation(Context context, @FloatRange(from = 0.0f) float radius, int color) {super(context);mContext = context;if (radius > MAX_RADIUS) {mSampling = radius / 25.0f;mRadius = MAX_RADIUS;} else {mRadius = radius;}mColor = color;}/**** @param context Context* @param radius The blur's radius.*/public BlurTransformation(Context context, @FloatRange(from = 0.0f) float radius) {this(context, radius, Color.TRANSPARENT);}public BlurTransformation(Context context) {this(context, DEFAULT_RADIUS);}/*** Transforms the given {@link Bitmap} based on the given dimensions and returns the transformed* result.* <p/>* <p>* The provided Bitmap, toTransform, should not be recycled or returned to the pool. Glide will automatically* recycle and/or reuse toTransform if the transformation returns a different Bitmap. Similarly implementations* should never recycle or return Bitmaps that are returned as the result of this method. Recycling or returning* the provided and/or the returned Bitmap to the pool will lead to a variety of runtime exceptions and drawing* errors. See #408 for an example. If the implementation obtains and discards intermediate Bitmaps, they may* safely be returned to the BitmapPool and/or recycled.* </p>* <p/>* <p>* outWidth and outHeight will never be {@link Target#SIZE_ORIGINAL}, this* class converts them to be the size of the Bitmap we're going to transform before calling this method.* </p>** @param pool        A {@link BitmapPool} that can be used to obtain and*                    return intermediate {@link Bitmap}s used in this transformation. For every*                    {@link Bitmap} obtained from the pool during this transformation, a*                    {@link Bitmap} must also be returned.* @param toTransform The {@link Bitmap} to transform.* @param outWidth    The ideal width of the transformed bitmap (the transformed width does not need to match exactly).* @param outHeight   The ideal height of the transformed bitmap (the transformed heightdoes not need to match*/@Overrideprotected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {boolean needScaled = mSampling == DEFAULT_SAMPLING;int originWidth = toTransform.getWidth();int originHeight = toTransform.getHeight();int width, height;if (needScaled) {width = originWidth;height = originHeight;} else {width = (int) (originWidth / mSampling);height = (int) (originHeight / mSampling);}//find a re-use bitmapBitmap bitmap = pool.get(width, height, Bitmap.Config.ARGB_8888);if (bitmap == null) {bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);}Canvas canvas = new Canvas(bitmap);if (mSampling != DEFAULT_SAMPLING) {canvas.scale(1 / mSampling, 1 / mSampling);}Paint paint = new Paint();paint.setFlags(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);PorterDuffColorFilter filter =new PorterDuffColorFilter(mColor, PorterDuff.Mode.SRC_ATOP);paint.setColorFilter(filter);canvas.drawBitmap(toTransform, 0, 0, paint);
// TIPS: Glide will take care of returning our original Bitmap to the BitmapPool for us,
// we needn't to recycle it.
//        toTransform.recycle();  <--- Just for tips. by LigboyRenderScript rs = RenderScript.create(mContext);Allocation input = Allocation.createFromBitmap(rs, bitmap, 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(mRadius);blur.forEach(output);output.copyTo(bitmap);rs.destroy();if (needScaled) {return bitmap;} else {Bitmap scaled = Bitmap.createScaledBitmap(bitmap, originWidth, originHeight, true);bitmap.recycle();return scaled;}}/*** A method to get a unique identifier for this particular transformation that can be used as part of a cache key.* The fully qualified class name for this class is appropriate if written out, but getClass().getName() is not* because the name may be changed by proguard.* <p/>* <p>* If this transformation does not affect the data that will be stored in cache, returning an empty string here* is acceptable.* </p>** @return A string that uniquely identifies this transformation.*/@Overridepublic String getId() {StringBuilder sb = new StringBuilder(ID);sb.append('-').append(mRadius).append('-').append(mColor);return sb.toString();}
}

使用起来也是非常简单:

Glide.with(MainActivity.this).load(imageFile.getUrl()).transform(new BlurTransformation(MainActivity.this, 100)).crossFade().into(mBackgroundImageView);

Gist:  https://gist.github.com/ligboy/eee784aa57f40a615179

Glide框架高斯模糊图片处理相关推荐

  1. Android框架之路——Glide加载图片(结合RecyclerView、CardView)

    Android框架之路--Glide加载图片 一.简介: 在泰国举行的谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech.这个库被广泛的运用在google的开 ...

  2. Android开发常用开源框架:图片处理

    1. 图片加载,缓存,处理 框架名称 功能描述 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库,已过时 Picasso 一个强大的图片下载与缓存的库 ...

  3. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果

     Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...

  4. Glide 框架解析

    Glide 框架解析 Glide 是我们常用的图片加载库,使用了很多图片管理的技术,以及常用的两级缓存,这篇文章重点是给他家解析一下Glide的框架设计,重点不在各种技术的詳細要点.学习优秀开源项目的 ...

  5. Android 系统(263)---Glide框架

    Glide框架 1.简介 2.Glide的基本使用 3.Glide的高级用法(仅列举几个) 3.1.RequestOptions(请求选项) 3.2.TransitionOptions(过渡选项) 3 ...

  6. 从源码分析Android的Glide库的图片加载流程及特点

    转载:http://m.aspku.com/view-141093.html 这篇文章主要介绍了从源码分析Android的Glide库的图片加载流程及特点,Glide库是Android下一款人气很高的 ...

  7. 基于ArkUI框架开发——图片模糊处理的实现

    原文:基于ArkUI框架开发--图片模糊处理的实现,点击链接查看更多技术内容. 现在市面上有很多APP,都或多或少对图片有模糊上的设计,所以,图片模糊效果到底怎么实现的呢? 首先,我们来了解下模糊效果 ...

  8. Android Glide加载图片、网络监听、设置资源监听

    Glide加载图片.加载进度监听 前言 正文 一.项目配置 二.显示网络图片 三.添加设置资源监听 四.添加设置资源监听 五.添加加载进度条 六.封装工具类 七.源码 总结 前言   在日常开发中使用 ...

  9. 小红书图片剪裁框架+微信图片选择器+超高清大图预览+图片自定义比例剪裁,支持 UI 自定义、支持跨进程回调

    YImagePicker 项目地址:yangpeixing/YImagePicker 简介: 小红书图片剪裁框架+微信图片选择器+超高清大图预览+图片自定义比例剪裁,支持 UI 自定义.支持跨进程回调 ...

最新文章

  1. DUBBO 使用问题记录
  2. aswing JTable用法
  3. css中的大于号是什么意思 有何作用
  4. 企业级 SpringCloud 教程 (五)路由网关(zuul)
  5. 微型计算机控制系统常用报警方式,微型计算机控制技术复习资料.docx
  6. 【NOIP-2017PJ】图书管理员
  7. html播放rtmp直播,video.js实现浏览器播放rtmp协议直播流的问题
  8. 亚马逊平板刷机Linux系统,亚马逊平板刷机步骤盘点【图解】
  9. Linux第二章:5.Xshell安装教程、使用Xshell6进行Linux远程登录
  10. web开发表情包---微信表情
  11. vs2017无法打开文件atls.lib问题
  12. HTML信件-一种奇特的实现方式
  13. 二项式定理与杨辉三角
  14. 大力哥谈 DALI - DALI 调光电源怎么用
  15. python代码解释4个作用域_Python中作用域的深入讲解
  16. 在PS中多种类抠图的教程(第一课)后附PS软件可下载
  17. IntelliJ Idea SpringBoot 数据库增删改查实例
  18. 如何在idea里git提交代码时,能有emoji表情图片?emoji表情大全给大家奉上
  19. linux设备驱动子系统,Linux设备驱动子系统终极弹 - USB
  20. 逻辑斯谛(Logistic)回归

热门文章

  1. CuteFTP 问题及 ftp 模式详解
  2. HCIE-Cloud Computing v2.0 lab机考全讲解
  3. 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
  4. 无线网络设置的dns服务器,DNS怎么设置才能上网
  5. Pytho读取Xml文件
  6. css代码文字破碎js特效
  7. 第三章、vb6的ByVal与ByRef详解
  8. 如何将lvm卷移动到另一台服务器中
  9. 基于FPGA实现的DDS双通道信号发生器
  10. 多重背包的二进制拆分法