亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android中實現毛玻璃效果的3種方法

2020-04-11 11:36:07
字體:
來源:轉載
供稿:網友

最近在做一款叫嘰嘰的App(男銀懂的),其中有一個功能需要對圖片處理實現毛玻璃的特效

進過一番預研,找到了3中實現方案,其中各有優缺點:

1、如果系統的api在16以上,可以使用系統提供的方法直接處理圖片

復制代碼 代碼如下:

if (VERSION.SDK_INT > 16) {
            Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);

            final RenderScript rs = RenderScript.create(context);
            final Allocation input = Allocation.createFromBitmap(rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE,
                    Allocation.USAGE_SCRIPT);
            final Allocation output = Allocation.createTyped(rs, input.getType());
            final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
            script.setRadius(radius /* e.g. 3.f */);
            script.setInput(input);
            script.forEach(output);
            output.copyTo(bitmap);
            return bitmap;
        }

2、 如果Api條件不滿足,可以使用如下方法

復制代碼 代碼如下:

@SuppressLint("NewApi")
    public static Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {

       
        Bitmap 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];
//        Log.e("pix", w + " " + h + " " + pix.length);
        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 temp = 256 * divsum;
        int dv[] = new int[temp];
        for (i = 0; i < temp; 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;
            }
        }

//        Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        return (bitmap);
    }

3、以上方法都存在一個問題,性能較低,下面提供一個C實現

復制代碼 代碼如下:

static int* StackBlur(int* pix, int w, int h, int radius) {
    int wm = w - 1;
    int hm = h - 1;
    int wh = w * h;
    int div = radius + radius + 1;

    int *r = (int *)malloc(wh * sizeof(int));
    int *g = (int *)malloc(wh * sizeof(int));
    int *b = (int *)malloc(wh * sizeof(int));
    int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;

    int *vmin = (int *)malloc(MAX(w,h) * sizeof(int));

    int divsum = (div + 1) >> 1;
    divsum *= divsum;
    int *dv = (int *)malloc(256 * divsum * sizeof(int));
    for (i = 0; i < 256 * divsum; i++) {
        dv[i] = (i / divsum);
    }

    yw = yi = 0;

    int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int));
    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 + (MIN(wm, MAX(i, 0)))];
            sir = stack[i + radius];
            sir[0] = (p & 0xff0000) >> 16;
            sir[1] = (p & 0x00ff00) >> 8;
            sir[2] = (p & 0x0000ff);

            rbs = r1 - 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] = 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 = MAX(0, yp) + x;

            sir = stack[i + radius];

            sir[0] = r[yi];
            sir[1] = g[yi];
            sir[2] = b[yi];

            rbs = r1 - 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] = 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;
        }
    }

    free(r);
    free(g);
    free(b);
    free(vmin);
    free(dv);
    free(stack);
    return(pix);
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97超级碰在线看视频免费在线看| 91色在线视频| 国产综合久久久久| 久久久久久久久久久亚洲| 亚洲国产成人久久综合| 亚洲欧美日韩中文在线制服| 萌白酱国产一区二区| 欧美成人在线免费视频| 国产精品扒开腿做爽爽爽男男| 欧美性xxxx在线播放| 欧美日韩性生活视频| 亚洲一区二区黄| 日韩激情视频在线播放| 亚洲国产精品成人va在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 色婷婷av一区二区三区在线观看| 在线免费看av不卡| 欧美做爰性生交视频| 久久久噜噜噜久久久| 黄色一区二区在线观看| 91高清视频在线免费观看| 久久亚洲精品小早川怜子66| 国产精品最新在线观看| 亚洲欧美日韩国产精品| 少妇高潮久久久久久潘金莲| 成人国产精品久久久久久亚洲| 欧美成人一二三| 色综合伊人色综合网| 欧美亚州一区二区三区| 亚洲a在线播放| 精品久久久久人成| 91产国在线观看动作片喷水| 亚洲第一区中文字幕| 欧美性生活大片免费观看网址| 国产色综合天天综合网| 欧美日韩激情小视频| 在线日韩日本国产亚洲| 国产视频欧美视频| 伊人伊成久久人综合网小说| 久久久久久久久久久国产| 国产精品热视频| 精品综合久久久久久97| 国产乱人伦真实精品视频| 国产精品久久激情| 欧美激情a∨在线视频播放| 成人亚洲综合色就1024| 日韩精品中文字幕在线观看| 日韩天堂在线视频| 色爱av美腿丝袜综合粉嫩av| 日韩网站免费观看| 欧美视频在线观看免费网址| 在线看日韩av| 欧美日韩另类在线| 91社影院在线观看| 欧美日韩国产第一页| 日韩精品在线第一页| 亚洲免费人成在线视频观看| 亚洲国产欧美一区二区三区久久| 色噜噜狠狠狠综合曰曰曰88av| 最近2019中文字幕第三页视频| 国产亚洲福利一区| 精品性高朝久久久久久久| 日本久久久久久| www.国产精品一二区| 欧美午夜激情视频| 97久久伊人激情网| 国产成人福利网站| 亚洲国产欧美一区二区丝袜黑人| 色悠久久久久综合先锋影音下载| 久久久免费观看视频| 欧美日韩国产综合新一区| 亚洲高清一二三区| 日韩精品免费在线观看| 亚洲欧美国产高清va在线播| 欧日韩不卡在线视频| 在线观看久久久久久| 亚洲伊人一本大道中文字幕| 国产脚交av在线一区二区| 日韩精品免费综合视频在线播放| 欧美精品在线免费| 欧美高清videos高潮hd| 国产成人亚洲综合| 日韩美女在线观看| 最新亚洲国产精品| 国产97在线视频| 欧美日韩在线视频首页| 欧美性猛交xxxx久久久| 欧美一区二区三区图| 亚洲天堂av综合网| 日本午夜精品理论片a级appf发布| 亚洲精品国产美女| 综合国产在线视频| 国产91久久婷婷一区二区| 久久影院免费观看| 综合136福利视频在线| 久久亚洲精品小早川怜子66| 国产精品色视频| 亚洲成人激情图| 国产日韩欧美在线看| 中文字幕日韩在线视频| 亚洲国产精品va在看黑人| 精品少妇v888av| 国产97在线视频| 97视频免费在线观看| 久久久久亚洲精品成人网小说| 91av成人在线| 亚洲天堂av综合网| 欧美日韩电影在线观看| 黑人巨大精品欧美一区二区| 欧美日韩精品在线观看| 国产va免费精品高清在线观看| 久久夜精品va视频免费观看| 亚洲欧美日韩久久久久久| 亚洲欧美国产制服动漫| 97香蕉超级碰碰久久免费的优势| 色狠狠av一区二区三区香蕉蜜桃| 日韩av一区二区在线| 国产精品免费小视频| 日韩有码在线电影| 国产日韩欧美日韩大片| 91手机视频在线观看| 成人精品在线视频| 久久人体大胆视频| 成人免费淫片aa视频免费| 亚洲午夜激情免费视频| 毛片精品免费在线观看| 国产精品美女免费视频| 精品色蜜蜜精品视频在线观看| 午夜精品一区二区三区在线播放| 国产一区二区三区高清在线观看| 欧洲一区二区视频| 色哟哟亚洲精品一区二区| 日韩精品在线观看视频| 色偷偷9999www| 欧美视频中文在线看| 成人国内精品久久久久一区| 亚洲天堂成人在线| 精品成人乱色一区二区| 91精品久久久久久久久久入口| 91精品国产综合久久香蕉最新版| 亚洲欧美中文在线视频| 欧美成人午夜激情在线| 九九热精品视频在线播放| 成人做爰www免费看视频网站| 精品日韩视频在线观看| 91精品国产乱码久久久久久久久| 菠萝蜜影院一区二区免费| 91精品国产自产在线老师啪| 日韩电影免费在线观看中文字幕| 日韩av综合网| 成人网在线观看| 日韩大陆毛片av| 91久久久久久久久| 一区二区日韩精品| 美女av一区二区三区| 亚洲国模精品私拍| 精品人伦一区二区三区蜜桃免费| 中文字幕在线观看日韩| 国产丝袜一区二区三区免费视频| 精品视频久久久| 成人黄色激情网| 国产精品第一视频| 亚洲国产成人久久综合一区| 欧美成人午夜视频|