package at.favre.lib.dali.blur.algorithms; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import at.favre.lib.dali.blur.IBlur; /** * http://stackoverflow.com/questions/8218438 * by saarraz1 */ public class BoxBlur implements IBlur { @Override public Bitmap blur(int radius, Bitmap bmp) { if((radius & 1) == 0 ) throw new IllegalArgumentException("Range must be odd."); Bitmap blurred = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(blurred); int w = bmp.getWidth(); int h = bmp.getHeight(); int[] pixels = new int[bmp.getWidth() * bmp.getHeight()]; bmp.getPixels(pixels, 0, w, 0, 0, w, h); boxBlurHorizontal(pixels, w, h, radius / 2); boxBlurVertical(pixels, w, h, radius / 2); c.drawBitmap(pixels, 0, w, 0.0F, 0.0F, w, h, true, null); return blurred; } private static void boxBlurHorizontal(int[] pixels, int w, int h, int halfRange) { int index = 0; int[] newColors = new int[w]; for (int y = 0; y < h; y++) { int hits = 0; long r = 0; long g = 0; long b = 0; for (int x = -halfRange; x < w; x++) { int oldPixel = x - halfRange - 1; if (oldPixel >= 0) { int color = pixels[index + oldPixel]; if (color != 0) { r -= Color.red(color); g -= Color.green(color); b -= Color.blue(color); } hits--; } int newPixel = x + halfRange; if (newPixel < w) { int color = pixels[index + newPixel]; if (color != 0) { r += Color.red(color); g += Color.green(color); b += Color.blue(color); } hits++; } if (x >= 0) { newColors[x] = Color.argb(0xFF, (int) (r / hits), (int) (g / hits), (int) (b / hits)); } } System.arraycopy(newColors, 0, pixels, index + 0, w); index += w; } } private static void boxBlurVertical(int[] pixels, int w, int h, int halfRange) { int[] newColors = new int[h]; int oldPixelOffset = -(halfRange + 1) * w; int newPixelOffset = (halfRange) * w; for (int x = 0; x < w; x++) { int hits = 0; long r = 0; long g = 0; long b = 0; int index = -halfRange * w + x; for (int y = -halfRange; y < h; y++) { int oldPixel = y - halfRange - 1; if (oldPixel >= 0) { int color = pixels[index + oldPixelOffset]; if (color != 0) { r -= Color.red(color); g -= Color.green(color); b -= Color.blue(color); } hits--; } int newPixel = y + halfRange; if (newPixel < h) { int color = pixels[index + newPixelOffset]; if (color != 0) { r += Color.red(color); g += Color.green(color); b += Color.blue(color); } hits++; } if (y >= 0) { newColors[y] = Color.argb(0xFF, (int) (r / hits), (int) (g / hits), (int) (b / hits)); } index += w; } for (int y = 0; y < h; y++) { pixels[y * w + x] = newColors[y]; } } } }