zoukankan      html  css  js  c++  java
  • 图片高斯模糊效果

    为实现一些玻璃蒙版的效果,需要用到高斯算法对图片进行模糊处理,基础算法代码如下

      1 public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {
      2 
      3         if (VERSION.SDK_INT > 20) {
      4             Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
      5 
      6             final RenderScript rs = RenderScript.create(context);
      7             final Allocation input = Allocation.createFromBitmap(rs, sentBitmap,
      8                     Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
      9             final Allocation output = Allocation.createTyped(rs, input.getType());
     10             final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
     11             script.setRadius(radius /* e.g. 3.f */);
     12             script.setInput(input);
     13             script.forEach(output);
     14             output.copyTo(bitmap);
     15             return bitmap;
     16         }
     17 
     18         Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
     19 
     20         if (radius < 1) {
     21             return (null);
     22         }
     23 
     24         int w = bitmap.getWidth();
     25         int h = bitmap.getHeight();
     26 
     27         int[] pix = new int[w * h];
     28         Log.e("pix", w + " " + h + " " + pix.length);
     29         bitmap.getPixels(pix, 0, w, 0, 0, w, h);
     30 
     31         int wm = w - 1;
     32         int hm = h - 1;
     33         int wh = w * h;
     34         int div = radius + radius + 1;
     35 
     36         int r[] = new int[wh];
     37         int g[] = new int[wh];
     38         int b[] = new int[wh];
     39         int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
     40         int vmin[] = new int[Math.max(w, h)];
     41 
     42         int divsum = (div + 1) >> 1;
     43         divsum *= divsum;
     44         int dv[] = new int[256 * divsum];
     45         for (i = 0; i < 256 * divsum; i++) {
     46             dv[i] = (i / divsum);
     47         }
     48 
     49         yw = yi = 0;
     50 
     51         int[][] stack = new int[div][3];
     52         int stackpointer;
     53         int stackstart;
     54         int[] sir;
     55         int rbs;
     56         int r1 = radius + 1;
     57         int routsum, goutsum, boutsum;
     58         int rinsum, ginsum, binsum;
     59 
     60         for (y = 0; y < h; y++) {
     61             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
     62             for (i = -radius; i <= radius; i++) {
     63                 p = pix[yi + Math.min(wm, Math.max(i, 0))];
     64                 sir = stack[i + radius];
     65                 sir[0] = (p & 0xff0000) >> 16;
     66                 sir[1] = (p & 0x00ff00) >> 8;
     67                 sir[2] = (p & 0x0000ff);
     68                 rbs = r1 - Math.abs(i);
     69                 rsum += sir[0] * rbs;
     70                 gsum += sir[1] * rbs;
     71                 bsum += sir[2] * rbs;
     72                 if (i > 0) {
     73                     rinsum += sir[0];
     74                     ginsum += sir[1];
     75                     binsum += sir[2];
     76                 } else {
     77                     routsum += sir[0];
     78                     goutsum += sir[1];
     79                     boutsum += sir[2];
     80                 }
     81             }
     82             stackpointer = radius;
     83 
     84             for (x = 0; x < w; x++) {
     85 
     86                 r[yi] = dv[rsum];
     87                 g[yi] = dv[gsum];
     88                 b[yi] = dv[bsum];
     89 
     90                 rsum -= routsum;
     91                 gsum -= goutsum;
     92                 bsum -= boutsum;
     93 
     94                 stackstart = stackpointer - radius + div;
     95                 sir = stack[stackstart % div];
     96 
     97                 routsum -= sir[0];
     98                 goutsum -= sir[1];
     99                 boutsum -= sir[2];
    100 
    101                 if (y == 0) {
    102                     vmin[x] = Math.min(x + radius + 1, wm);
    103                 }
    104                 p = pix[yw + vmin[x]];
    105 
    106                 sir[0] = (p & 0xff0000) >> 16;
    107                 sir[1] = (p & 0x00ff00) >> 8;
    108                 sir[2] = (p & 0x0000ff);
    109 
    110                 rinsum += sir[0];
    111                 ginsum += sir[1];
    112                 binsum += sir[2];
    113 
    114                 rsum += rinsum;
    115                 gsum += ginsum;
    116                 bsum += binsum;
    117 
    118                 stackpointer = (stackpointer + 1) % div;
    119                 sir = stack[(stackpointer) % div];
    120 
    121                 routsum += sir[0];
    122                 goutsum += sir[1];
    123                 boutsum += sir[2];
    124 
    125                 rinsum -= sir[0];
    126                 ginsum -= sir[1];
    127                 binsum -= sir[2];
    128 
    129                 yi++;
    130             }
    131             yw += w;
    132         }
    133         for (x = 0; x < w; x++) {
    134             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
    135             yp = -radius * w;
    136             for (i = -radius; i <= radius; i++) {
    137                 yi = Math.max(0, yp) + x;
    138 
    139                 sir = stack[i + radius];
    140 
    141                 sir[0] = r[yi];
    142                 sir[1] = g[yi];
    143                 sir[2] = b[yi];
    144 
    145                 rbs = r1 - Math.abs(i);
    146 
    147                 rsum += r[yi] * rbs;
    148                 gsum += g[yi] * rbs;
    149                 bsum += b[yi] * rbs;
    150 
    151                 if (i > 0) {
    152                     rinsum += sir[0];
    153                     ginsum += sir[1];
    154                     binsum += sir[2];
    155                 } else {
    156                     routsum += sir[0];
    157                     goutsum += sir[1];
    158                     boutsum += sir[2];
    159                 }
    160 
    161                 if (i < hm) {
    162                     yp += w;
    163                 }
    164             }
    165             yi = x;
    166             stackpointer = radius;
    167             for (y = 0; y < h; y++) {
    168                 // Preserve alpha channel: ( 0xff000000 & pix[yi] )
    169                 pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
    170 
    171                 rsum -= routsum;
    172                 gsum -= goutsum;
    173                 bsum -= boutsum;
    174 
    175                 stackstart = stackpointer - radius + div;
    176                 sir = stack[stackstart % div];
    177 
    178                 routsum -= sir[0];
    179                 goutsum -= sir[1];
    180                 boutsum -= sir[2];
    181 
    182                 if (x == 0) {
    183                     vmin[y] = Math.min(y + r1, hm) * w;
    184                 }
    185                 p = x + vmin[y];
    186 
    187                 sir[0] = r[p];
    188                 sir[1] = g[p];
    189                 sir[2] = b[p];
    190 
    191                 rinsum += sir[0];
    192                 ginsum += sir[1];
    193                 binsum += sir[2];
    194 
    195                 rsum += rinsum;
    196                 gsum += ginsum;
    197                 bsum += binsum;
    198 
    199                 stackpointer = (stackpointer + 1) % div;
    200                 sir = stack[stackpointer];
    201 
    202                 routsum += sir[0];
    203                 goutsum += sir[1];
    204                 boutsum += sir[2];
    205 
    206                 rinsum -= sir[0];
    207                 ginsum -= sir[1];
    208                 binsum -= sir[2];
    209 
    210                 yi += w;
    211             }
    212         }
    213 
    214         Log.e("pix", w + " " + h + " " + pix.length);
    215         bitmap.setPixels(pix, 0, w, 0, 0, w, h);
    216         return (bitmap);
    217     }

    但是此类实现模糊效果效率是个很大的问题,所以我们需要把原图先处理一下,再进行模糊操作。

    1 private static Bitmap small(Bitmap bitmap) {
    2         Matrix matrix = new Matrix();
    3         matrix.postScale(0.08f, 0.08f); // 长和宽放大缩小的比例
    4         Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,
    5                 true);
    6         return resizeBmp;
    7     }

    在使用模糊图的地方可以再添加一些透明蒙版来实现高亮偏暗的效果。

  • 相关阅读:
    博客园
    未释放的已删除文件
    ssh连接缓慢
    剑指 Offer 38. 字符串的排列
    剑指 Offer 37. 序列化二叉树
    剑指 Offer 50. 第一个只出现一次的字符
    剑指 Offer 36. 二叉搜索树与双向链表
    剑指 Offer 35. 复杂链表的复制
    剑指 Offer 34. 二叉树中和为某一值的路径
    剑指 Offer 33. 二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/nick-zhang/p/3733645.html
Copyright © 2011-2022 走看看