以下为将bitmap图像处理为毛玻璃效果的图像的工具类:

  1. public class FastBlurUtil {
  2.  
  3. public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
  4.  
  5. // Stack Blur v1.0 from
  6. // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
  7. //
  8. // Java Author: Mario Klingemann <mario at quasimondo.com>
  9. // http://incubator.quasimondo.com
  10. // created Feburary 29, 2004
  11. // Android port : Yahel Bouaziz <yahel at kayenko.com>
  12. // http://www.kayenko.com
  13. // ported april 5th, 2012
  14.  
  15. // This is a compromise between Gaussian Blur and Box blur
  16. // It creates much better looking blurs than Box Blur, but is
  17. // 7x faster than my Gaussian Blur implementation.
  18. //
  19. // I called it Stack Blur because this describes best how this
  20. // filter works internally: it creates a kind of moving stack
  21. // of colors whilst scanning through the image. Thereby it
  22. // just has to add one new block of color to the right side
  23. // of the stack and remove the leftmost color. The remaining
  24. // colors on the topmost layer of the stack are either added on
  25. // or reduced by one, depending on if they are on the right or
  26. // on the left side of the stack.
  27. //
  28. // If you are using this algorithm in your code please add
  29. // the following line:
  30. //
  31. // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
  32.  
  33. Bitmap bitmap;
  34. if (canReuseInBitmap) {
  35. bitmap = sentBitmap;
  36. } else {
  37. bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
  38. }
  39.  
  40. if (radius < 1) {
  41. return (null);
  42. }
  43.  
  44. int w = bitmap.getWidth();
  45. int h = bitmap.getHeight();
  46.  
  47. int[] pix = new int[w * h];
  48. bitmap.getPixels(pix, 0, w, 0, 0, w, h);
  49.  
  50. int wm = w - 1;
  51. int hm = h - 1;
  52. int wh = w * h;
  53. int div = radius + radius + 1;
  54.  
  55. int r[] = new int[wh];
  56. int g[] = new int[wh];
  57. int b[] = new int[wh];
  58. int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
  59. int vmin[] = new int[Math.max(w, h)];
  60.  
  61. int divsum = (div + 1) >> 1;
  62. divsum *= divsum;
  63. int dv[] = new int[256 * divsum];
  64. for (i = 0; i < 256 * divsum; i++) {
  65. dv[i] = (i / divsum);
  66. }
  67.  
  68. yw = yi = 0;
  69.  
  70. int[][] stack = new int[div][3];
  71. int stackpointer;
  72. int stackstart;
  73. int[] sir;
  74. int rbs;
  75. int r1 = radius + 1;
  76. int routsum, goutsum, boutsum;
  77. int rinsum, ginsum, binsum;
  78.  
  79. for (y = 0; y < h; y++) {
  80. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  81. for (i = -radius; i <= radius; i++) {
  82. p = pix[yi + Math.min(wm, Math.max(i, 0))];
  83. sir = stack[i + radius];
  84. sir[0] = (p & 0xff0000) >> 16;
  85. sir[1] = (p & 0x00ff00) >> 8;
  86. sir[2] = (p & 0x0000ff);
  87. rbs = r1 - Math.abs(i);
  88. rsum += sir[0] * rbs;
  89. gsum += sir[1] * rbs;
  90. bsum += sir[2] * rbs;
  91. if (i > 0) {
  92. rinsum += sir[0];
  93. ginsum += sir[1];
  94. binsum += sir[2];
  95. } else {
  96. routsum += sir[0];
  97. goutsum += sir[1];
  98. boutsum += sir[2];
  99. }
  100. }
  101. stackpointer = radius;
  102.  
  103. for (x = 0; x < w; x++) {
  104.  
  105. r[yi] = dv[rsum];
  106. g[yi] = dv[gsum];
  107. b[yi] = dv[bsum];
  108.  
  109. rsum -= routsum;
  110. gsum -= goutsum;
  111. bsum -= boutsum;
  112.  
  113. stackstart = stackpointer - radius + div;
  114. sir = stack[stackstart % div];
  115.  
  116. routsum -= sir[0];
  117. goutsum -= sir[1];
  118. boutsum -= sir[2];
  119.  
  120. if (y == 0) {
  121. vmin[x] = Math.min(x + radius + 1, wm);
  122. }
  123. p = pix[yw + vmin[x]];
  124.  
  125. sir[0] = (p & 0xff0000) >> 16;
  126. sir[1] = (p & 0x00ff00) >> 8;
  127. sir[2] = (p & 0x0000ff);
  128.  
  129. rinsum += sir[0];
  130. ginsum += sir[1];
  131. binsum += sir[2];
  132.  
  133. rsum += rinsum;
  134. gsum += ginsum;
  135. bsum += binsum;
  136.  
  137. stackpointer = (stackpointer + 1) % div;
  138. sir = stack[(stackpointer) % div];
  139.  
  140. routsum += sir[0];
  141. goutsum += sir[1];
  142. boutsum += sir[2];
  143.  
  144. rinsum -= sir[0];
  145. ginsum -= sir[1];
  146. binsum -= sir[2];
  147.  
  148. yi++;
  149. }
  150. yw += w;
  151. }
  152. for (x = 0; x < w; x++) {
  153. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  154. yp = -radius * w;
  155. for (i = -radius; i <= radius; i++) {
  156. yi = Math.max(0, yp) + x;
  157.  
  158. sir = stack[i + radius];
  159.  
  160. sir[0] = r[yi];
  161. sir[1] = g[yi];
  162. sir[2] = b[yi];
  163.  
  164. rbs = r1 - Math.abs(i);
  165.  
  166. rsum += r[yi] * rbs;
  167. gsum += g[yi] * rbs;
  168. bsum += b[yi] * rbs;
  169.  
  170. if (i > 0) {
  171. rinsum += sir[0];
  172. ginsum += sir[1];
  173. binsum += sir[2];
  174. } else {
  175. routsum += sir[0];
  176. goutsum += sir[1];
  177. boutsum += sir[2];
  178. }
  179.  
  180. if (i < hm) {
  181. yp += w;
  182. }
  183. }
  184. yi = x;
  185. stackpointer = radius;
  186. for (y = 0; y < h; y++) {
  187. // Preserve alpha channel: ( 0xff000000 & pix[yi] )
  188. pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
  189.  
  190. rsum -= routsum;
  191. gsum -= goutsum;
  192. bsum -= boutsum;
  193.  
  194. stackstart = stackpointer - radius + div;
  195. sir = stack[stackstart % div];
  196.  
  197. routsum -= sir[0];
  198. goutsum -= sir[1];
  199. boutsum -= sir[2];
  200.  
  201. if (x == 0) {
  202. vmin[y] = Math.min(y + r1, hm) * w;
  203. }
  204. p = x + vmin[y];
  205.  
  206. sir[0] = r[p];
  207. sir[1] = g[p];
  208. sir[2] = b[p];
  209.  
  210. rinsum += sir[0];
  211. ginsum += sir[1];
  212. binsum += sir[2];
  213.  
  214. rsum += rinsum;
  215. gsum += ginsum;
  216. bsum += binsum;
  217.  
  218. stackpointer = (stackpointer + 1) % div;
  219. sir = stack[stackpointer];
  220.  
  221. routsum += sir[0];
  222. goutsum += sir[1];
  223. boutsum += sir[2];
  224.  
  225. rinsum -= sir[0];
  226. ginsum -= sir[1];
  227. binsum -= sir[2];
  228.  
  229. yi += w;
  230. }
  231. }
  232.  
  233. bitmap.setPixels(pix, 0, w, 0, 0, w, h);
  234.  
  235. return (bitmap);
  236. }
  237.  
  238. }

  可以看出,使用方法非常简单,传入待续话的bitmap、虚化程序(一般为8),和是否重用flag。

  然后,对于大图,往往会出现OOM异常的报错,那是因为当虚化开始时,虚拟机开始不断进行内存回收,包括所有软引用的回收。然后,仍然出现了内存溢出。那就意味着我们只能对小图进行虚化,这样才能防止内存溢出。但我并不想换其他图,那么,我们应该把这张图先进性缩放。

缩放方法:

  1. public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)

  第四个输入输入的参数filter,是指缩放边缘效果,filter为true则会得到一个边缘平滑的bitmap,反之,则会得到一个边缘锯齿、pixelrelated的bitmap。这里,我们对图片进行虚化,无所谓边缘效果,所以filter=false。

  那么,怎么组合运行虚化代码实现大图虚化呢?以下为具体实现代码:

  1. int scaleRatio = 10;
  2. int blurRadius = 8;
  3. Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
  4. originBitmap.getWidth() / scaleRatio,
  5. originBitmap.getHeight() / scaleRatio,
  6. false);
  7. Bitmap blurBitmap = FastBlur.doBlur(scaledBitmap, blurRadius, true);
  8. imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
  9. imageView.setImageBitmap(blurBitmap);

  如果图片的虚化效果较弱或者并不是很明显,提供增强虚化效果的方法:

1、增大scaleRatio的数值(增大缩放比),使用更小的bitmap去虚化,这样可以得到更好的虚化效果,而且有利于减小内存消耗。

2、增大blurRadius的数值,这样可以提高续话层度,不过会导致cpu更加intensive。

参考资料:实现虚化bitmap代码地址

Android毛玻璃处理代码(Blur)的更多相关文章

  1. wpf 实现实时毛玻璃(live blur)效果

    原文:wpf 实现实时毛玻璃(live blur)效果 I2OS7发布后,就被它的时实模糊吸引了,就想着能不能将这个效果引入到我们的产品上.拿来当mask肯定会很爽,其实在之前也做过类似的,但是不是实 ...

  2. 转--Android实用的代码片段 常用代码总结

    这篇文章主要介绍了Android实用的代码片段 常用代码总结,需要的朋友可以参考下     1:查看是否有存储卡插入 复制代码 代码如下: String status=Environment.getE ...

  3. Android 上的代码阅读器 CoderBrowserHD 修改支持 go 语言代码

    我在Android上的代码阅读器用的是 https://github.com/zerob13/CoderBrowserHD 改造的版本,改造后的版本我放在 https://github.com/ghj ...

  4. 利用android proguard混淆代码

    利用android proguard混淆代码 2014-02-05 17:50 1207人阅读 评论(1) 收藏 举报 网上虽然有很多相关博客,不过貌似都不是最新版的..于是百度+谷歌+github上 ...

  5. 转:Android 2.3 代码混淆proguard技术介绍

    ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...

  6. 关于下拉刷新你是否真的非常理解还是只会搬砖?附 Android 实例子源代码文件下载地址380个合集

    1,推荐几篇非常有用的博文 原创写的真的非常好 主要讲解原理,整体布局三部分组成以及设置padding等等作用, 下拉的具体实现 滑动到底部具体加载以及判断手势事件,再次推荐作者的 详细讲解 建议先看 ...

  7. Android 简单的代码混淆

    Android的代码混淆是开发者需要了解的相关知识,它能够防止android应用程序的反编译.因为android程序多数是java语言开发的,而java代码很容易被反编译,所以为了使android应用 ...

  8. android studio 实现代码混淆

    =======本文章属于转载==========原文章地址:http://my.oschina.net/aibenben/blog/370985 这篇文章等是跟大家分享一在Android studio ...

  9. 《Android第一行代码》笔记

    学习Android开发差点儿相同有两年时间了.期间也做了大大小小的一些项目.近来抽出闲暇想把Android基础强化一下,之前在网上看到了郭霖郭大神的几篇博客.从中受益不少.于是花了近一周时间看完了郭神 ...

随机推荐

  1. 用gradle管理android项目出现的问题以及解决方法

    1.项目结构 最好是全部在root 项目配置 一个settings.gradle 一个build.gradle 2.多项目依赖 http://www.gradle.org/docs/current/u ...

  2. HBase总结(二十)HBase经常使用shell命令具体说明

    进入hbase shell console $HBASE_HOME/bin/hbase shell 假设有kerberos认证,须要事先使用对应的keytab进行一下认证(使用kinit命令),认证成 ...

  3. XSS分析及预防(转)

    阅读目录 XSS的种类和特点 XSS预防 总结 XSS(Cross Site Scripting),又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行.在WEB前端应用日益发展的今天,XSS漏 ...

  4. csdn肿么了,这两天写的博文都是待审核

    昨天早上8点写了一篇博文,然后点击发表,结果系统显示"待审核".于是仅仅好qq联系csdn的客服,等到9点时候,csdn的客服上线了,然后回复说是链接达到5个以上须要审核,于是回到 ...

  5. php学习之道:php中soap的使用实例以及生成WSDL文件,提供自己主动生成WSDL文件的类库——SoapDiscovery.class.php类

    1. web service普及: Webservice soap wsdl差别之个人见解 Web Service实现业务诉求:  Web Service是真正"办事"的那个,提供 ...

  6. SQL Syscolumns

    每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行.该表位于每个数据库中. 列名 数据类型 描述 name sysname 列名或过程参数的名称. id int 该列所属的表对象 I ...

  7. AOP 之 6.1 AOP基础 ——跟我学spring3(转)

    http://jinnianshilongnian.iteye.com/blog/1418596

  8. svnkit添加节点

    package com.repositoryclient.svnoptions; import org.tmatesoft.svn.core.SVNException; import org.tmat ...

  9. 7款开源Java反编译工具

    今天我们要来分享一些关于Java的反编译工具,反编译听起来是一个非常高上大的技术词汇,通俗的说,反编译是一个对目标可执行程序进行逆向分析,从而得到原始代码的过程.尤其是像.NET.Java这样的运行在 ...

  10. Java调用cmd压缩文件

    今天在做一个java调用windows的压缩命令时遇到一奇怪问题代码如下: String cmd ="C:/Program Files (x86)/WinRAR/rar.exe a c:/t ...