Android高斯模糊在java层面上的两种实现方式
来源:互联网 发布:js给div添加class 编辑:程序博客网 时间:2024/06/08 19:43
第一种是依赖于support-v8的实现如下
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 */ @Override protected 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 bitmap Bitmap 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 Ligboy RenderScript 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. */ @Override public String getId() { StringBuilder sb = new StringBuilder(ID); sb.append('-').append(mRadius).append('-').append(mColor); return sb.toString(); }}
然后在build.gradle上的defaultConfig上配置如下两排代码
defaultConfig {
renderscriptTargetApi 20
renderscriptSupportModeEnabled true
}
在activity里面用glide加载网络图片并模糊
Glide.with(Context).load(url).asBitmap().transform(new BlurTransformation(Context, 25)).into(ivbg);
这是一种方法。
第二种
package com.wbkj.artmss.Weight;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.renderscript.Allocation;import android.renderscript.Element;import android.renderscript.RenderScript;import android.renderscript.ScriptIntrinsicBlur;import android.support.annotation.FloatRange;import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;import com.bumptech.glide.request.target.Target;public class FastBlur 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 FastBlur build() { return new FastBlur(mContext, mRadius, mColor); } } /** * @param context Context * @param radius The blur's radius. * @param color The color filter for blurring. */ public FastBlur(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 FastBlur(Context context, @FloatRange(from = 0.0f) float radius) { this(context, radius, Color.TRANSPARENT); } public FastBlur(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 */ @Override protected 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 bitmap Bitmap 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 Ligboy RenderScript 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. */ @Override public String getId() { StringBuilder sb = new StringBuilder(ID); sb .append('-').append(mRadius) .append('-').append(mColor); return sb.toString(); }}第二种方法只要sdk版本大于17就可行用法也是一样
Glide.with(this).load(url).asBitmap().transform(new FastBlur(this, 25)).into(ivbg);
minSdkVersion 17
效果如图
0 0
- Android高斯模糊在java层面上的两种实现方式
- Android实现图片的高斯模糊(两种方式)
- Android 实现高斯模糊的几种方式
- android 图片的高斯模糊实现
- Android开发 高斯模糊的实现
- Android实现图片的高斯模糊
- android高斯模糊的简单实现
- Mybatis模糊查询的两种实现方式
- Android实现高斯模糊
- android 高斯模糊实现
- Android实现高斯模糊
- 高斯模糊-虚化的实现方式
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- Android 图片模糊、高斯模糊、毛玻璃的三种实现方法
- JavaScript-九九乘法表
- 数据库中的第一、二、三范式
- Windows下VPN操作指引
- libreoffice API 开发(一):libreoffice SDK 安装配置
- 一些常见html5语义化标签
- Android高斯模糊在java层面上的两种实现方式
- pthread(POSIX Thread)
- DWR3实现从服务器发送消息到网页
- Java集合CurrentHashMap
- BZOJ 1575 [Usaco2009 Jan]气象牛Baric
- 简单KMP
- 纸上谈兵-Dota2
- 微信小程序例子——使用audio组件播放音乐
- [笔记]C++中 对const类型指针的强制类型转换操作