zoukankan      html  css  js  c++  java
  • Android UI效果实现——滑动模糊渐变效果实现

    前言:

    大家应该都看到过iOS7解锁屏幕的滑动模糊渐变效果,好了,现在可以把手纸收起来了,今天黄老师就给大家讲一下如何在Android平台上

    实现类似的滑动模糊渐变效果,其实方式远比你想像的简单。

    目标效果展示:

    第一部分:几个前提

    说到模糊效果,我们先要了解几个前提

    1、原图,指需要被模糊的一张位图

    2、模糊,通常是采用指将一个位图的每个像素RGB值都取周围像素的RGB值的平均值,这样就可以产生模糊效果,一般通过高斯函数来实现,

    至于Java中的实现方式黄老师就不给大家细讲了,我也不是搞图形算法的,在这方面了解的不比大家多,百度一下能找到一堆高斯模糊转换的实现。

    3、模糊半径,指每个像素点周围模糊的半径,半径越大,模糊程度约高,模糊效果越明显,同时,模糊计算耗费时间越长。

    4、模糊处理非常费时,一半在100ms~5000ms内,就黄老师我本人找的网上的算法实测,一般android通过java实现的高斯模糊算法转换一张手机

    屏幕分辨率为480x800的位图需要2s左右,所以如果要在滑动的过程中实时不断重新计算模糊效果会非常差,所以如果要实现iOS7那样的滑动动态模糊

    渐变效果,用这样的方式是不可行的,实际上iOS也不是这么做的,因为iOS的硬件也没达到能实时计算的程度。

    那么究竟应该如何去实现模糊渐变呢,其实非常简单,我们接着讲。

    第二部分:动态模糊渐变的合理实现方式

    其实,我的方式非常简单,首先你需要明确一个最大的模糊效果的模糊半径值,我们给它取个名字叫maxRadius,然后使用maxRadius和原图传入高斯模糊算法

    中计算出最大模糊效果的位图maxBlurBitmap。

    然后,在ui组件中,假设我的原图是用一个ImageView显示在界面上的,然后你所需要做的是,再创建一个ImageView置于原图ImageView之上,然后将图片源

    设置为maxBlurBitmap,如下图:

    接着,我们只需要简单的调整maxBlurBitmap的透明度,即可实现模糊渐变效果了,是否很简单呢?

    第三部分,提供一个最简单的Java高斯模糊实现,我网上找来的,方便偷懒不愿自己找的同学

      1 /**
      2  * 位图处理类
      3  * @author HalfmanG2
      4  */
      5 public class BitmapUtil {
      6 
      7     /**
      8      * 创建一个虚化的位图
      9      * @param sentBitmap 原位图
     10      * @param radius 虚化半径
     11      * @return 虚化后的位图
     12      */
     13     public static Bitmap createBlurBitmap(Bitmap sentBitmap, int radius) {
     14         Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
     15         if (radius < 1) {
     16             return (null);
     17         }
     18         int w = bitmap.getWidth();
     19         int h = bitmap.getHeight();
     20         int[] pix = new int[w * h];
     21         bitmap.getPixels(pix, 0, w, 0, 0, w, h);
     22         int wm = w - 1;
     23         int hm = h - 1;
     24         int wh = w * h;
     25         int div = radius + radius + 1;
     26         int r[] = new int[wh];
     27         int g[] = new int[wh];
     28         int b[] = new int[wh];
     29         int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
     30         int vmin[] = new int[Math.max(w, h)];
     31         int divsum = (div + 1) >> 1;
     32         divsum *= divsum;
     33         int dv[] = new int[256 * divsum];
     34         for (i = 0; i < 256 * divsum; i++) {
     35             dv[i] = (i / divsum);
     36         }
     37         yw = yi = 0;
     38         int[][] stack = new int[div][3];
     39         int stackpointer;
     40         int stackstart;
     41         int[] sir;
     42         int rbs;
     43         int r1 = radius + 1;
     44         int routsum, goutsum, boutsum;
     45         int rinsum, ginsum, binsum;
     46         for (y = 0; y < h; y++) {
     47             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
     48             for (i = -radius; i <= radius; i++) {
     49                 p = pix[yi + Math.min(wm, Math.max(i, 0))];
     50                 sir = stack[i + radius];
     51                 sir[0] = (p & 0xff0000) >> 16;
     52                 sir[1] = (p & 0x00ff00) >> 8;
     53                 sir[2] = (p & 0x0000ff);
     54                 rbs = r1 - Math.abs(i);
     55                 rsum += sir[0] * rbs;
     56                 gsum += sir[1] * rbs;
     57                 bsum += sir[2] * rbs;
     58                 if (i > 0) {
     59                     rinsum += sir[0];
     60                     ginsum += sir[1];
     61                     binsum += sir[2];
     62                 } else {
     63                     routsum += sir[0];
     64                     goutsum += sir[1];
     65                     boutsum += sir[2];
     66                 }
     67             }
     68             stackpointer = radius;
     69             for (x = 0; x < w; x++) {
     70                 r[yi] = dv[rsum];
     71                 g[yi] = dv[gsum];
     72                 b[yi] = dv[bsum];
     73                 rsum -= routsum;
     74                 gsum -= goutsum;
     75                 bsum -= boutsum;
     76                 stackstart = stackpointer - radius + div;
     77                 sir = stack[stackstart % div];
     78                 routsum -= sir[0];
     79                 goutsum -= sir[1];
     80                 boutsum -= sir[2];
     81                 if (y == 0) {
     82                     vmin[x] = Math.min(x + radius + 1, wm);
     83                 }
     84                 p = pix[yw + vmin[x]];
     85                 sir[0] = (p & 0xff0000) >> 16;
     86                 sir[1] = (p & 0x00ff00) >> 8;
     87                 sir[2] = (p & 0x0000ff);
     88                 rinsum += sir[0];
     89                 ginsum += sir[1];
     90                 binsum += sir[2];
     91                 rsum += rinsum;
     92                 gsum += ginsum;
     93                 bsum += binsum;
     94                 stackpointer = (stackpointer + 1) % div;
     95                 sir = stack[(stackpointer) % div];
     96                 routsum += sir[0];
     97                 goutsum += sir[1];
     98                 boutsum += sir[2];
     99                 rinsum -= sir[0];
    100                 ginsum -= sir[1];
    101                 binsum -= sir[2];
    102                 yi++;
    103             }
    104             yw += w;
    105         }
    106         for (x = 0; x < w; x++) {
    107             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
    108             yp = -radius * w;
    109             for (i = -radius; i <= radius; i++) {
    110                 yi = Math.max(0, yp) + x;
    111                 sir = stack[i + radius];
    112                 sir[0] = r[yi];
    113                 sir[1] = g[yi];
    114                 sir[2] = b[yi];
    115                 rbs = r1 - Math.abs(i);
    116                 rsum += r[yi] * rbs;
    117                 gsum += g[yi] * rbs;
    118                 bsum += b[yi] * rbs;
    119                 if (i > 0) {
    120                     rinsum += sir[0];
    121                     ginsum += sir[1];
    122                     binsum += sir[2];
    123                 } else {
    124                     routsum += sir[0];
    125                     goutsum += sir[1];
    126                     boutsum += sir[2];
    127                 }
    128                 if (i < hm) {
    129                     yp += w;
    130                 }
    131             }
    132             yi = x;
    133             stackpointer = radius;
    134             for (y = 0; y < h; y++) {
    135                 pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum];
    136                 rsum -= routsum;
    137                 gsum -= goutsum;
    138                 bsum -= boutsum;
    139                 stackstart = stackpointer - radius + div;
    140                 sir = stack[stackstart % div];
    141                 routsum -= sir[0];
    142                 goutsum -= sir[1];
    143                 boutsum -= sir[2];
    144                 if (x == 0) {
    145                     vmin[y] = Math.min(y + r1, hm) * w;
    146                 }
    147                 p = x + vmin[y];
    148                 sir[0] = r[p];
    149                 sir[1] = g[p];
    150                 sir[2] = b[p];
    151                 rinsum += sir[0];
    152                 ginsum += sir[1];
    153                 binsum += sir[2];
    154                 rsum += rinsum;
    155                 gsum += ginsum;
    156                 bsum += binsum;
    157                 stackpointer = (stackpointer + 1) % div;
    158                 sir = stack[stackpointer];
    159                 routsum += sir[0];
    160                 goutsum += sir[1];
    161                 boutsum += sir[2];
    162                 rinsum -= sir[0];
    163                 ginsum -= sir[1];
    164                 binsum -= sir[2];
    165                 yi += w;
    166             }
    167         }
    168         bitmap.setPixels(pix, 0, w, 0, 0, w, h);
    169         return (bitmap);
    170     }
    171 }

    最后,别废话了,赶紧自己去实现一个看看效果吧!顺便提一下,有更快的模糊算法(最好使用C实现)实现记得联系我:

    QQ:811868948

    E-Mail:halfmanhuang@gmail.com

  • 相关阅读:
    《DSP using MATLAB》Problem 6.17
    一些老物件
    《DSP using MATLAB》Problem 6.16
    《DSP using MATLAB》Problem 6.15
    《DSP using MATLAB》Problem 6.14
    《DSP using MATLAB》Problem 6.13
    《DSP using MATLAB》Problem 6.12
    《DSP using MATLAB》Problem 6.11
    P1414 又是毕业季II
    Trie树
  • 原文地址:https://www.cnblogs.com/halfmanhuang/p/3837261.html
Copyright © 2011-2022 走看看