Android 图片滤镜工具——高斯模糊
===================高斯模糊=========================
创建一个 ImageFilter 类(滤镜工具),代码如下:
- import android.graphics.Bitmap;
- public class ImageFilter {
- /**
- * 高斯模糊滤镜
- * @param sentBitmap 需要处理的Bitmap对象
- * @param radius 高斯模糊半径
- * @param canReuseInBitmap 处理结果应用到Bitmap本身
- * @return
- */
- public static Bitmap doBlur(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);
- }
- }
ImageFilter.java
调用 ImageFilter 的 doBlur 静态方法,即可对图片进行高斯模糊。
doBlur 接受三个参数(图片源 Bitmap,模糊半径 Integer,处理原图 Boolean)
由于图片处理需要时间,所以必须进行异步处理(放在子线程中运行),最终将结果返回UI线程。
提升性能:可以将图片压缩后在进行高斯模糊。
===================实例测试=======================
XML:( layout/activity_image.xml )
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/image_view"
- android:layout_width="300dp"
- android:layout_height="300dp"
- android:layout_centerInParent="true" />
- <ImageView
- android:layout_width="100dp"
- android:layout_height="100dp"
- android:layout_centerInParent="true"
- android:src="@drawable/woider" />
- </RelativeLayout>
Activity:( ImageActivity.java )
- public class ImageActivity extends Activity {
- private ImageView imageView;
- private Bitmap bitmap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_image);
- imageView = (ImageView) findViewById(R.id.image_view);
- //从资源中获取Bitmap
- bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.woider);
- //异步处理
- new Thread(new Runnable() {
- @Override
- public void run() {
- //高斯模糊处理图片
- bitmap = ImageFilter.doBlur(bitmap, 30, false);
- //处理完成后返回主线程
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- imageView.setImageBitmap(bitmap);
- }
- });
- }
- }).start();
- }
- }
=====================运行截图======================
Android 图片滤镜工具——高斯模糊的更多相关文章
- android全功能音乐播放器、基于MVP-Clean + Weex + RxJava2 + Retrofit + Dagger2 + MTRVA的综合应用、图片滤镜处理等源码
Android仿微信朋友圈查看图片下拽返回. Android图片滤镜处理,相机滤镜处理效果源码 Android自定义View源码:一个水平的进度条 基于MVP-Clean + Weex + RxJav ...
- [Android]-图片JNI(C++\Java)高斯模糊的实现与比較
版权声明:本文作者:Qiujuer https://github.com/qiujuer; 转载请注明出处,盗版必究! !! https://blog.csdn.net/qiujuer/article ...
- android mvp高速开发框架介绍(dileber使用之图片下载工具)
这几天忙着工作- 今天抽时间又把框架的bug处理了一下--并且把volley的源代码改动了一下 android mvp框架:dileber(https://github.com/dileber/dil ...
- 【Android LibGDX游戏引擎开发教程】第06期:图形图像的绘制(下)图片整合工具的使用
在上一篇文章中,我们提到了图片必须是2的n次方的问题.但是随着Libgdx的不断完善和发展,使用一些工具就 可以很好的解决了这样一个问题,但是它的功能又不仅仅只限于此,那么下面就来让我们看看Textu ...
- Android图像滤镜框架GPUImage从配置到应用
GPUImage简介 GPUImage 是iOS下一个开源的基于GPU的图像处理库,提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜.GPUImage for Android是它在Andr ...
- Android图片缓存之Lru算法
前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...
- Android 照相 滤镜
android-image-filter 19种相片滤镜,使用也简单,all filters in file BitmapFilter.java : Bitmap newBitmap = Bitmap ...
- Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...
- Xamarin Mono For Android 4.6.07004 完整离线安装破解版(C#开发Android、IOS工具)
Xamarin是由Miguel de Icaza成立的一家新的独立公司,目的是给Mono一个继续奋斗的机会.Mono for Android (原名:MonoDroid)可以让开发人员使用 Mic ...
随机推荐
- 【别人的老师VS你的老师 】同样是老师,差别怎么这么大呢!?
- node基础11:接受参数
1.接收参数 在Node中接受GET/POST请求的参数不像PHP那样,在PHP中直接有全局变量$_GET,$_POST来接受url,或者请求体重的参数. 在node中接受GET参数使用url.par ...
- 搭建一套自己实用的.net架构(4)【CodeBuilder-RazorEngine】
工欲善其事必先利其器, 下面来说说代码生成器. 现在代码生成器品种繁多各式各样, 什么codesmith.T4. 动软也算.那么每款代码生成器都有自己模板解析引擎. 现在比较流行的 NVelocit ...
- Query节点操作,jQuery插入节点,jQuery删除节点,jQuery Dom操作
一.创建节点 var box = $('<div>节点</div>'); //创建一个节点,或者var box = "<div>节点</div> ...
- [CareerCup] 17.2 Tic Tac Toe 井字棋游戏
17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...
- Win10 UWP开发实现Bing翻译
微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...
- 招聘前端、Java后端开发、测试、Mysql DBA
公司介绍: http://www.lagou.com/gongsi/43095.html http://www.yamichu.com 简历发到: zhuye@yamichu.com 招聘职位: JA ...
- 无法加载父级样式或设置IIS的asp站点启用父路径
打开IIS 1.单击站点,在"IIS"区域中找到ASP图标,双击. 2.找到"启用父路径"项目,将对应的值设置为"TRUE"即可. 顶
- Win10 PC一周年更新正式版14393.447 32位/64位更新补丁KB3200970下载 Flash补丁Kb3202790下载
微软在今天凌晨推送了Win10 PC一周年更新正式版14393.447,本次更新补丁代号为KB3200970,面向Win10一周年更新正式版的PC用户. 更新日志 • 提升了多媒体音频.远程桌面以及I ...
- 解决Java接口内部类的main()方法无法打印输出的问题
问题源自<Thinking in Java>关于内部类的章节,例子如下: public interface ClassInInterface{ void howdy(); public c ...