Example usage for android.graphics Bitmap setPixels

List of usage examples for android.graphics Bitmap setPixels

Introduction

In this page you can find the example usage for android.graphics Bitmap setPixels.

Prototype

public void setPixels(@ColorInt int[] pixels, int offset, int stride, int x, int y, int width, int height) 

Source Link

Document

Replace pixels in the bitmap with the colors in the array.

Usage

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ?/*from  ww w .  j  a  v a  2 s  . c o m*/
 * 
 * @param bitmap
 *            
 * @return ??
 */
public static Bitmap nostalgic(Bitmap bitmap) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
    int pixColor = 0;
    int pixR = 0;
    int pixG = 0;
    int pixB = 0;
    int newR = 0;
    int newG = 0;
    int newB = 0;
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    for (int i = 0; i < height; i++) {
        for (int k = 0; k < width; k++) {
            pixColor = pixels[width * i + k];
            pixR = Color.red(pixColor);
            pixG = Color.green(pixColor);
            pixB = Color.blue(pixColor);
            newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
            newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
            newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
            int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG,
                    newB > 255 ? 255 : newB);
            pixels[width * i + k] = newColor;
        }
    }
    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ?/*ww  w  .  j a  v a2 s . com*/
 * 
 * @param bitmap
 *            
 * @return ??
 */
public static Bitmap film(Bitmap bitmap) {
    // RGBA
    final int MAX_VALUE = 255;
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;

    int pixColor = 0;

    int newR = 0;
    int newG = 0;
    int newB = 0;

    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    int pos = 0;
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            pos = i * width + k;
            pixColor = pixels[pos];

            pixR = Color.red(pixColor);
            pixG = Color.green(pixColor);
            pixB = Color.blue(pixColor);

            newR = MAX_VALUE - pixR;
            newG = MAX_VALUE - pixG;
            newB = MAX_VALUE - pixB;

            newR = Math.min(MAX_VALUE, Math.max(0, newR));
            newG = Math.min(MAX_VALUE, Math.max(0, newG));
            newB = Math.min(MAX_VALUE, Math.max(0, newB));

            pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
        }
    }

    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ?/*from   www. jav a  2s  . c  o m*/
 * 
 * @param bitmap
 *            
 * @return ??
 */
public static Bitmap emboss(Bitmap bitmap) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;

    int pixColor = 0;

    int newR = 0;
    int newG = 0;
    int newB = 0;

    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    int pos = 0;
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            pos = i * width + k;
            pixColor = pixels[pos];

            pixR = Color.red(pixColor);
            pixG = Color.green(pixColor);
            pixB = Color.blue(pixColor);

            pixColor = pixels[pos + 1];
            newR = Color.red(pixColor) - pixR + 127;
            newG = Color.green(pixColor) - pixG + 127;
            newB = Color.blue(pixColor) - pixB + 127;

            newR = Math.min(255, Math.max(0, newR));
            newG = Math.min(255, Math.max(0, newG));
            newB = Math.min(255, Math.max(0, newB));

            pixels[pos] = Color.argb(255, newR, newG, newB);
        }
    }

    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:com.hotstar.player.adplayer.player.PlayerFragment.java

/**
 * Initialize the player fragment by setting up views, media player and
 * feature managers/*from w  w w.  j  a v a  2 s.  c om*/
 * 
 * @param intent
 *            the intent that contains the video item
 */
private void initialize(Intent intent) {
    videoItem = (VideoItem) intent.getExtras().getSerializable("CONTENT_INFO");
    AdVideoApplication.logger.i(LOG_TAG + "#initialize",
            "Initializing the media player with item [" + videoItem.getTitle() + "].");

    playerClickableAdFragment = (PlayerClickableAdFragment) getActivity().getSupportFragmentManager()
            .findFragmentById(R.id.playerClickInfo);
    playerFrame = (FrameLayout) playerFragmentView.findViewById(R.id.playerFrame);

    ViewGroup controlBarView = (ViewGroup) playerFragmentView.findViewById(R.id.ControlBarItem);
    controlBar = new PlayerControlBar(getActivity(), controlBarView);

    // ViewGroup controlTopBarView = (ViewGroup) playerFragmentView.findViewById(R.id.ControlTopBarItem);
    // controlTopBar = new PlayerControlTopBar(getActivity(), controlTopBarView);

    ViewGroup controlAdBarView = (ViewGroup) playerFragmentView.findViewById(R.id.AdControlBarItem);
    controlAdBar = new PlayerAdControlBar(getActivity(), controlAdBarView);

    spinner = (ProgressBar) playerFragmentView.findViewById(R.id.pbBufferingSpinner);

    overlayAdImageView = (ImageView) playerFragmentView.findViewById(R.id.overlayAdImageView);
    overlayAdGifView = (GifImageView) playerFragmentView.findViewById(R.id.overlayAdGifView);
    overlayAdGifView.setOnFrameAvailable(new GifImageView.OnFrameAvailable() {
        @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
        @Override
        public Bitmap onFrameAvailable(Bitmap bitmap) {
            return bitmap;
        }
    });

    java.io.InputStream is;
    is = mActivity.getResources().openRawResource(R.drawable.vpaid_ad_icon);

    vpaidAdIconGifView = (GifImageView) playerFragmentView.findViewById(R.id.vpaidAdIconGifView);
    vpaidAdIconGifView.setBytes(BytesManager.getBytes(is));
    vpaidAdIconGifView.setOnFrameAvailable(new GifImageView.OnFrameAvailable() {
        @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
        @Override
        public Bitmap onFrameAvailable(Bitmap src) {
            if (src == null)
                return src;

            int width = src.getWidth();
            int height = src.getHeight();
            Bitmap b = src.copy(Bitmap.Config.ARGB_8888, true);
            b.setHasAlpha(true);

            int[] pixels = new int[width * height];
            src.getPixels(pixels, 0, width, 0, 0, width, height);

            for (int i = 0; i < width * height; i++) {
                if ((pixels[i] == WHITE_COLOR) || (pixels[i] == BLACK_COLOR)) {
                    pixels[i] = 0;
                }
            }

            b.setPixels(pixels, 0, width, 0, 0, width, height);
            return b;
        }
    });
    vpaidAdIconGifView.setVisibility(View.INVISIBLE);
    vpaidAdIconGifView.setOnClickListener(vPaidADIconClickListener);

    thumbnailPlayImageView = (ImageView) playerFragmentView.findViewById(R.id.thumbnailPlayImageView);
    thumbnailPlayImageView.setVisibility(View.INVISIBLE);
    thumbnailImageView = (ImageView) playerFragmentView.findViewById(R.id.thumbnailImageView);
    thumbnailImageView.setVisibility(View.INVISIBLE);
    thumbnailImageView.setOnClickListener(thumbnailViewClickListener);
    OverlayAdResourceManager.getInstance().preloadImage(videoItem.getThumbnail().getLargeThumbnailUrl());

    //      audioProfile = (TextView) playerFragmentView.findViewById(R.id.audioTextView);
    //      audioProfile.setText(R.string.qosAudioProfile);
    //      audioProfile.setVisibility(View.INVISIBLE);
    //
    //      _ccButton = (ImageButton) playerFragmentView.findViewById(R.id.sbPlayerControlCC);
    //      _rewindButton = (ImageButton) playerFragmentView.findViewById(R.id.playerRewind);
    ((CustomFrameLayout) playerFrame).addOnSizeChangeListener(new OnSizeChangeListener() {

        @Override
        public void onSizeChanged() {
            // Scale player, since container size has changed.
            handler.post(new Runnable() {

                @Override
                public void run() {
                    setPlayerViewSize(savedMovieWidth, savedMovieHeight);
                }
            });
        }
    });

    createPlayer();
    setupViews();
    createManagers();
    prepareMedia();
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ??/*from   w w w  .j  ava  2s . c o m*/
 * 
 * @param delta
 *            ??(0,24)
 * @return
 */
public static Bitmap adjustTone(Bitmap src, int delta) {
    if (delta >= 24 || delta <= 0) {
        return null;
    }
    // 
    int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
    int width = src.getWidth();
    int height = src.getHeight();
    Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;
    int pixColor = 0;
    int newR = 0;
    int newG = 0;
    int newB = 0;
    int idx = 0;
    int[] pixels = new int[width * height];

    src.getPixels(pixels, 0, width, 0, 0, width, height);
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            idx = 0;
            for (int m = -1; m <= 1; m++) {
                for (int n = -1; n <= 1; n++) {
                    pixColor = pixels[(i + m) * width + k + n];
                    pixR = Color.red(pixColor);
                    pixG = Color.green(pixColor);
                    pixB = Color.blue(pixColor);

                    newR += (pixR * gauss[idx]);
                    newG += (pixG * gauss[idx]);
                    newB += (pixB * gauss[idx]);
                    idx++;
                }
            }
            newR /= delta;
            newG /= delta;
            newB /= delta;
            newR = Math.min(255, Math.max(0, newR));
            newG = Math.min(255, Math.max(0, newG));
            newB = Math.min(255, Math.max(0, newB));
            pixels[i * width + k] = Color.argb(255, newR, newG, newB);
            newR = 0;
            newG = 0;
            newB = 0;
        }
    }
    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return bitmap;
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ??//from   www . j  a va 2s  . com
 * 
 * @param bitmap
 *            
 * @return ???
 */
public static Bitmap sharpen(Bitmap bitmap) {
    // 
    int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;

    int pixColor = 0;

    int newR = 0;
    int newG = 0;
    int newB = 0;

    int idx = 0;
    float alpha = 0.3F;
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            idx = 0;
            for (int m = -1; m <= 1; m++) {
                for (int n = -1; n <= 1; n++) {
                    pixColor = pixels[(i + n) * width + k + m];
                    pixR = Color.red(pixColor);
                    pixG = Color.green(pixColor);
                    pixB = Color.blue(pixColor);

                    newR = newR + (int) (pixR * laplacian[idx] * alpha);
                    newG = newG + (int) (pixG * laplacian[idx] * alpha);
                    newB = newB + (int) (pixB * laplacian[idx] * alpha);
                    idx++;
                }
            }

            newR = Math.min(255, Math.max(0, newR));
            newG = Math.min(255, Math.max(0, newG));
            newB = Math.min(255, Math.max(0, newB));

            pixels[i * width + k] = Color.argb(255, newR, newG, newB);
            newR = 0;
            newG = 0;
            newB = 0;
        }
    }

    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ?/*from ww  w  .j a v  a  2 s  .c  o  m*/
 * 
 * @param bitmap
 *            
 * @return ??
 */
public static Bitmap soften(Bitmap bitmap) {
    // 
    int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;

    int pixColor = 0;

    int newR = 0;
    int newG = 0;
    int newB = 0;

    int delta = 16; // ?

    int idx = 0;
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            idx = 0;
            for (int m = -1; m <= 1; m++) {
                for (int n = -1; n <= 1; n++) {
                    pixColor = pixels[(i + m) * width + k + n];
                    pixR = Color.red(pixColor);
                    pixG = Color.green(pixColor);
                    pixB = Color.blue(pixColor);

                    newR = newR + pixR * gauss[idx];
                    newG = newG + pixG * gauss[idx];
                    newB = newB + pixB * gauss[idx];
                    idx++;
                }
            }

            newR /= delta;
            newG /= delta;
            newB /= delta;

            newR = Math.min(255, Math.max(0, newR));
            newG = Math.min(255, Math.max(0, newG));
            newB = Math.min(255, Math.max(0, newB));

            pixels[i * width + k] = Color.argb(255, newR, newG, newB);

            newR = 0;
            newG = 0;
            newB = 0;
        }
    }

    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:com.yk.notification.util.BitmapUtil.java

/**
 * ?/*from   w w w . ja  v  a  2 s  .co m*/
 * 
 * @param bitmap
 *            
 * @param centerX
 *            ?X?
 * @param centerY
 *            ?Y?
 * @return ??
 */
public static Bitmap sunshine(Bitmap bitmap, int centerX, int centerY) {
    final int width = bitmap.getWidth();
    final int height = bitmap.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    int pixR = 0;
    int pixG = 0;
    int pixB = 0;

    int pixColor = 0;

    int newR = 0;
    int newG = 0;
    int newB = 0;
    int radius = Math.min(centerX, centerY);

    final float strength = 150F; //  100~150
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    int pos = 0;
    for (int i = 1, length = height - 1; i < length; i++) {
        for (int k = 1, len = width - 1; k < len; k++) {
            pos = i * width + k;
            pixColor = pixels[pos];

            pixR = Color.red(pixColor);
            pixG = Color.green(pixColor);
            pixB = Color.blue(pixColor);

            newR = pixR;
            newG = pixG;
            newB = pixB;

            // ????
            int distance = (int) (Math.pow((centerY - i), 2) + Math.pow(centerX - k, 2));
            if (distance < radius * radius) {
                // ??
                int result = (int) (strength * (1.0 - Math.sqrt(distance) / radius));
                newR = pixR + result;
                newG = pixG + result;
                newB = pixB + result;
            }

            newR = Math.min(255, Math.max(0, newR));
            newG = Math.min(255, Math.max(0, newG));
            newB = Math.min(255, Math.max(0, newB));

            pixels[pos] = Color.argb(255, newR, newG, newB);
        }
    }

    newBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
    return newBitmap;
}

From source file:Main.java

/**
 * http://stackoverflow.com/questions/2067955/fast-bitmap-blur-for-android-sdk
 * http://incubator.quasimondo.com//*from w ww .j  a  va  2  s.c o m*/
 *
 * @param sentBitmap
 * @param scale
 * @param radius
 * @return
 */
public static Bitmap fastBlur(Bitmap sentBitmap, float scale, int radius) {
    int width = Math.round(sentBitmap.getWidth() * scale);
    int height = Math.round(sentBitmap.getHeight() * scale);
    sentBitmap = Bitmap.createScaledBitmap(sentBitmap, width, height, false);

    Bitmap img = sentBitmap.copy(sentBitmap.getConfig(), true);

    if (radius < 1) {
        return null;
    }
    int w = img.getWidth();
    int h = img.getHeight();

    int[] pix = new int[w * h];
    img.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 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);

            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++) {
            pix[yi] = 0xff000000 | (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;
        }
    }

    img.setPixels(pix, 0, w, 0, 0, w, h);

    return img;
}

From source file:Main.java

public static Bitmap createBlurBmpWithCommonCompute(Bitmap srcBmp, int radius) {
    // Stack Blur v1.0 from
    // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
    ////from   www  . j  a va2s . c  om
    // Java Author: Mario Klingemann <mario at quasimondo.com>
    // http://incubator.quasimondo.com
    // created Feburary 29, 2004
    // Android port : Yahel Bouaziz <yahel at kayenko.com>
    // http://www.kayenko.com
    // ported april 5th, 2012

    // This is a compromise between Gaussian Blur and Box blur
    // It creates much better looking blurs than Box Blur, but is
    // 7x faster than my Gaussian Blur implementation.
    //
    // I called it Stack Blur because this describes best how this
    // filter works internally: it creates a kind of moving stack
    // of colors whilst scanning through the image. Thereby it
    // just has to add one new block of color to the right side
    // of the stack and remove the leftmost color. The remaining
    // colors on the topmost layer of the stack are either added on
    // or reduced by one, depending on if they are on the right or
    // on the left side of the stack.
    //
    // If you are using this algorithm in your code please add
    // the following line:
    //
    // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>

    if (radius < 1)
        return null;

    Bitmap bitmap = srcBmp.copy(srcBmp.getConfig(), true);

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

    int[] pix = new int[w * h];
    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 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);

            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;
        }
    }
    bitmap.setPixels(pix, 0, w, 0, 0, w, h);

    return bitmap;
}