问题
I have been trying to implement a box blur algorithm in android. The code seems to be fine but when trying to apply it, some areas in the blurred image have big yellow and white smudges all over the blurred photo. Can anyone help me find out what i'm doing wrong? Thanks:
Here is what i have:
public static Bitmap boxBlur(Bitmap bmp, int range) {
assert (range & 1) == 0 : "Range must be odd.";
Bitmap blurred = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),
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, range / 2);
boxBlurVertical(pixels, w, h, range / 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, (byte) (r / hits),
(byte) (g / hits), (byte) (b / hits));
}
}
for (int x = 0; x < w; x++) {
pixels[index + x] = newColors[x];
}
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, (byte) (r / hits),
(byte) (g / hits), (byte) (b / hits));
}
index += w;
}
for (int y = 0; y < h; y++) {
pixels[y * w + x] = newColors[y];
}
}
}
回答1:
Found the problem!
The line:newColors[x] = Color.argb(0xFF, (byte) (r / hits), (byte) (g / hits), (byte) (b / hits));
I converted the averages to bytes, where they should have been ints.
Changed it to:
newColors[x] = Color.argb(0xFF, (int) (r / hits), (int) (g / hits), (int) (b / hits));
来源:https://stackoverflow.com/questions/8218438/android-box-blur-algorithm