[关闭]
@Tyhj 2017-02-24T13:04:26.000000Z 字数 5268 阅读 1026

背景模糊

Android


本文固定链接:https://www.zybuluo.com/Tyhj/note/666366
图片模糊,试过很多工具什么的,还是这个类比较好,直接用就好了

使用方法:

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