Android Bitmap Blur fastblur(Bitmap sentBitmap, int radius)

Here you can find the source of fastblur(Bitmap sentBitmap, int radius)

Description

Fastblur in bitmap.

Parameter

Parameter Description
sentBitmap the sent bitmap
radius the radius

Return

the bitmap

Declaration

public static Bitmap fastblur(Bitmap sentBitmap, int radius) 

Method Source Code

//package com.java2s;

import java.io.BufferedOutputStream;

import java.io.IOException;
import java.io.InputStream;

import android.graphics.Bitmap;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;

public class Main {
    /**//from   w w  w.  j a v a2 s  .  co  m
     * Fastblur in bitmap.
     * 
     * @param sentBitmap
     *            the sent bitmap
     * @param radius
     *            the radius
     * @return the bitmap
     * @author siddhesh
     */
    public static Bitmap fastblur(Bitmap sentBitmap, int radius) {
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        Bitmap origBitmap = sentBitmap.copy(sentBitmap.getConfig(), true);

        if (radius < 1) {
            return (null);
        }

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int[] pix = new int[w * h];
        int[] opix = new int[w * h];
        //      Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);
        origBitmap.getPixels(opix, 0, w, 0, 0, w, h);

        final int width = sentBitmap.getWidth();
        final int height = sentBitmap.getHeight();

        final float xc = width / 2;
        final float yc = height / 2;
        final float a1 = width / 6;
        final float b1 = height / 2;

        final double a1Square = Math.pow(a1, 2);
        final double b1Square = Math.pow(b1, 2);

        final double area = Math.PI * a1 * b1; // / area of Ellipse to calculate
        // no of pixels this ellipse can
        // hold //

        int[] intArrEllipsePosition = new int[(int) area];
        int[] intArrEllipseData = new int[(int) area];
        int[] overlayBmp = new int[width * height];

        for (int i = 0; i < overlayBmp.length; i++) {
            overlayBmp[i] = -1;
        }

        // Log.d(TAG, overlayBmp+"");

        sentBitmap.getPixels(overlayBmp, 0, width, 0, 0, width, height);

        int noOfPixelsInEllipse = 0;
        int currPosition = 0;
        for (int currY = 0; currY < height; currY++) {
            for (int currX = 0; currX < width; currX++) {

                double computeEllipseEqn = (Math.pow(currX - xc, 2) / a1Square)
                        + (Math.pow(currY - yc, 2) / b1Square); // /////
                // computation
                // to check if
                // current (x,y)
                // pixel lies in
                // or on ellipse
                // region///

                if (computeEllipseEqn <= 1) {

                    currPosition = (currY * width) + currX + 1; // // mapping
                    // between
                    // current x,y
                    // pixel wrt
                    // pixel array
                    // ///
                    intArrEllipsePosition[noOfPixelsInEllipse] = currPosition;

                    if (computeEllipseEqn > 0.90) {
                        // Log.d("PIX ", "" + computeEllipseEqn);
                        intArrEllipseData[noOfPixelsInEllipse] = Color
                                .argb(0x26, Color.red(pix[currPosition]),
                                        Color.green(pix[currPosition]),
                                        Color.blue(pix[currPosition]));// pix[currPosition];
                    } else if (computeEllipseEqn > 0.70
                            && computeEllipseEqn < 0.90) {
                        // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        intArrEllipseData[noOfPixelsInEllipse] = Color
                                .argb(0x10, Color.red(pix[currPosition]),
                                        Color.green(pix[currPosition]),
                                        Color.blue(pix[currPosition]));// pix[currPosition];
                    } else if (computeEllipseEqn > 0.65
                            && computeEllipseEqn < 0.70) {
                        // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        intArrEllipseData[noOfPixelsInEllipse] = Color
                                .argb(0x10, Color.red(pix[currPosition]),
                                        Color.green(pix[currPosition]),
                                        Color.blue(pix[currPosition]));// pix[currPosition];
                    } else if (computeEllipseEqn > 0.63
                            && computeEllipseEqn < 0.65) {
                        // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        intArrEllipseData[noOfPixelsInEllipse] = Color
                                .argb(0x01, Color.red(pix[currPosition]),
                                        Color.green(pix[currPosition]),
                                        Color.blue(pix[currPosition]));// pix[currPosition];
                    } else {
                        intArrEllipseData[noOfPixelsInEllipse] = pix[currPosition];
                    }

                    // intArrEllipseData[noOfPixelsInEllipse] =
                    // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x00,
                    // Color.red(pix[currPosition]),
                    // Color.green(pix[currPosition]),
                    // Color.blue(pix[currPosition]));
                    noOfPixelsInEllipse++;
                }

            }
        }

        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 dv[] = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; 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);
                    //
                    // sir[0] = p>>16;
                    // sir[1] = p>>8;
                    // sir[2] = p;

                    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);

        for (int k = 0; k < width * height; k++) {
            // Log.d(TAG, "PIXEL FOUND "+overlayBmp[k]);

            overlayBmp[k] = Color.argb(0x000000,
                    Color.red(pix[currPosition]),
                    Color.green(pix[currPosition]),
                    Color.blue(pix[currPosition]));

        }

        // /// update pixels in blurred array with the pixels picked from
        // original pixels intersecting the ellipse region ///
        for (int tmpEllipsePixel = 0; tmpEllipsePixel < noOfPixelsInEllipse; tmpEllipsePixel++) {
            // pix[intArrEllipsePosition[tmpEllipsePixel]] =
            // intArrEllipseData[tmpEllipsePixel];
            overlayBmp[intArrEllipsePosition[tmpEllipsePixel]] = intArrEllipseData[tmpEllipsePixel];
        }

        // Log.d(TAG, overlayBmp+"");

        // pix[intArrEllipsePosition[tmpEllipsePixel]] =
        // intArrEllipseData[tmpEllipsePixel];
        //
        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        //
        Bitmap canvasOverlay = Bitmap.createBitmap(origBitmap.getWidth(),
                origBitmap.getHeight(), origBitmap.getConfig());
        canvasOverlay.setPixels(overlayBmp, 0, w, 0, 0, w, h);
        // canvasOverlay.setHasMipMap(true);

        //
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(canvasOverlay, new Matrix(), null);

        return (bitmap);
    }

    /**
     * Fastblur.
     *
     * @param sentBitmap the sent bitmap
     * @return the bitmap
     */
    public static Bitmap fastblur(Bitmap sentBitmap) {
        int[] radius = new int[] { 1, 2, 3, 6 };
        int[] ellipseWidth = new int[] { 6, 4, 3, 2 };
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        //      Bitmap origBitmap = sentBitmap.copy(sentBitmap.getConfig(), true);

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        int[] pix = new int[w * h];
        final int width = sentBitmap.getWidth();
        final int height = sentBitmap.getHeight();

        final float xc = width / 2;
        final float yc = height / 2;
        //      int[] opix = new int[w * h];
        //      Log.e("pix", w + " " + h + " " + pix.length);
        for (int index = 0; index < 2; index++) {
            if (radius[index] < 1) {
                return (null);
            }
            bitmap.getPixels(pix, 0, w, 0, 0, w, h);
            //      origBitmap.getPixels(opix, 0, w, 0, 0, w, h);

            final float a1 = width / ellipseWidth[index];
            final float b1 = height / 2;

            final double a1Square = Math.pow(a1, 2);
            final double b1Square = Math.pow(b1, 2);

            final double area = Math.PI * a1 * b1; // / area of Ellipse to calculate
            // no of pixels this ellipse can
            // hold //

            int[] intArrEllipsePosition = new int[(int) area];
            int[] intArrEllipseData = new int[(int) area];

            int noOfPixelsInEllipse = 0;
            int currPosition = 0;
            for (int currY = 0; currY < height; currY++) {
                for (int currX = 0; currX < width; currX++) {

                    double computeEllipseEqn = (Math.pow(currX - xc, 2) / a1Square)
                            + (Math.pow(currY - yc, 2) / b1Square); // /////
                    // computation
                    // to check if
                    // current (x,y)
                    // pixel lies in
                    // or on ellipse
                    // region///

                    if (computeEllipseEqn <= 1) {

                        currPosition = (currY * width) + currX + 1; // // mapping
                        // between
                        // current x,y
                        // pixel wrt
                        // pixel array
                        // ///
                        intArrEllipsePosition[noOfPixelsInEllipse] = currPosition;

                        // if (computeEllipseEqn > 0.90) {
                        // // Log.d("PIX ", "" + computeEllipseEqn);
                        // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x26,
                        // Color.red(pix[currPosition]),
                        // Color.green(pix[currPosition]),
                        // Color.blue(pix[currPosition]));// pix[currPosition];
                        // }
                        // else if (computeEllipseEqn > 0.70 && computeEllipseEqn <
                        // 0.90) {
                        // // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x10,
                        // Color.red(pix[currPosition]),
                        // Color.green(pix[currPosition]),
                        // Color.blue(pix[currPosition]));// pix[currPosition];
                        // }
                        // else if (computeEllipseEqn > 0.65 && computeEllipseEqn <
                        // 0.70) {
                        // // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x10,
                        // Color.red(pix[currPosition]),
                        // Color.green(pix[currPosition]),
                        // Color.blue(pix[currPosition]));// pix[currPosition];
                        // }
                        // else if (computeEllipseEqn > 0.63 && computeEllipseEqn <
                        // 0.65) {
                        // // Log.d("PIX 0.70", "" + computeEllipseEqn);
                        // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x01,
                        // Color.red(pix[currPosition]),
                        // Color.green(pix[currPosition]),
                        // Color.blue(pix[currPosition]));// pix[currPosition];
                        // }
                        // else
                        // {
                        intArrEllipseData[noOfPixelsInEllipse] = pix[currPosition];
                        // }

                        // intArrEllipseData[noOfPixelsInEllipse] =
                        // intArrEllipseData[noOfPixelsInEllipse] = Color.argb(0x00,
                        // Color.red(pix[currPosition]),
                        // Color.green(pix[currPosition]),
                        // Color.blue(pix[currPosition]));
                        noOfPixelsInEllipse++;
                    }

                }
            }

            int wm = w - 1;
            int hm = h - 1;
            int wh = w * h;
            int div = radius[index] + radius[index] + 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 dv[] = new int[256 * divsum];
            for (i = 0; i < 256 * divsum; 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[index] + 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[index]; i <= radius[index]; i++) {
                    p = pix[yi + Math.min(wm, Math.max(i, 0))];
                    sir = stack[i + radius[index]];
                    sir[0] = (p & 0xff0000) >> 16;
                    sir[1] = (p & 0x00ff00) >> 8;
                    sir[2] = (p & 0x0000ff);
                    // sir[0] = p>>16;
                    // sir[1] = p>>8;
                    // sir[2] = p;
                    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];
                    }
                    // radius = radius + 1;
                }
                stackpointer = radius[index];

                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[index] + div;
                        sir = stack[stackstart % div];

                        routsum -= sir[0];
                        goutsum -= sir[1];
                        boutsum -= sir[2];

                        if (y == 0) {
                            vmin[x] = Math.min(x + radius[index] + 1, wm);
                        }
                        p = pix[yw + vmin[x]];

                        sir[0] = (p & 0xff0000) >> 16;
                        sir[1] = (p & 0x00ff00) >> 8;
                        sir[2] = (p & 0x0000ff);
                        //
                        // sir[0] = p>>16;
                        // sir[1] = p>>8;
                        // sir[2] = p;

                        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[index] * w;
                for (i = -radius[index]; i <= radius[index]; i++) {
                    yi = Math.max(0, yp) + x;

                    sir = stack[i + radius[index]];

                    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[index];
                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[index] + 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;

                    }
                }
            }

            for (int tmpEllipsePixel = 0; tmpEllipsePixel < noOfPixelsInEllipse; tmpEllipsePixel++) {
                pix[intArrEllipsePosition[tmpEllipsePixel]] = intArrEllipseData[tmpEllipsePixel];
                // overlayBmp[intArrEllipsePosition[tmpEllipsePixel]] =
                // intArrEllipseData[tmpEllipsePixel];
            }

            bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        }
        return (bitmap);
    }

    /**
     * Copy.
     *
     * @param in the in
     * @param out the out
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private static void copy(InputStream in, BufferedOutputStream out)
            throws IOException {
        int byte_;
        while ((byte_ = in.read()) != -1)
            out.write(byte_);
    }
}

Related

  1. blur(Bitmap bitmap)
  2. blur(int[] in, int[] out, int width, int height, int radius)
  3. createBlurredBitmap(final Bitmap sentBitmap)
  4. fastblur(Bitmap sentBitmap)
  5. blur(Context context, Bitmap sentBitmap)
  6. blur(Context context, Bitmap sentBitmap, int radius)
  7. fastBlurFromView(Context context, View v, int radius)
  8. fastBlur(Context context, Bitmap renderedBmp, int radius)