Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This is specifically for Android so you'll see the two android specific import at the top. However, I think it would apply to java in general. Anyway, here's the code (borrowed from: http://xjaphx.wordpress.com/2011/06/22/image-processing-convolution-matrix/). I'm curious to get feedback on this. What can be faster or more efficient?

import android.graphics.Bitmap;
import android.graphics.Color;

public class ConvolutionMatrix {
    public static final int SIZE = 3;

    public double[][] Matrix;
    public double Factor = 1;
    public double Offset = 1;

    public ConvolutionMatrix() {
        Matrix = new double[SIZE][SIZE];
    }

    public void setAll(double value) {
        for (int x = 0; x < SIZE; x++) {
            for (int y = 0; y < SIZE; y++) {
                Matrix[x][y] = value;
            }
        }
    }

    public void applyConfig(double[][] config) {
        Matrix = config;
    }

    public Bitmap computeConvolution3x3(Bitmap src) {
        int width = src.getWidth();
        int height = src.getHeight();
        Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());

        int A, R, G, B;
        int sumR, sumG, sumB;
        int[][] pixels = new int[SIZE][SIZE];

        for (int y = 0; y < height - 2; ++y) {
            for (int x = 0; x < width - 2; ++x) {
                // get pixel matrix
                for (int i = 0; i < SIZE; ++i) {
                    for (int j = 0; j < SIZE; ++j) {
                        pixels[i][j] = src.getPixel(x + i, y + j);
                    }
                }

                // get alpha of center pixel
                A = Color.alpha(pixels[1][1]);

                // init color sums
                sumR = sumG = sumB = 0;

                // get sum of RGB matrix
                for (int i = 0; i < SIZE; ++i) {
                    for (int j = 0; j < SIZE; ++j) {
                        sumR += (Color.red(pixels[i][j]) * Matrix[i][j]);
                        sumG += (Color.green(pixels[i][j]) * Matrix[i][j]);
                        sumB += (Color.blue(pixels[i][j]) * Matrix[i][j]);
                    }
                }

                // get final red
                R = (int)(sumR/Factor + Offset);
                if (R < 0) R = 0;
                else if (R > 255) R = 255;

                // get final green
                G = (int)(sumG/Factor + Offset);
                if (G < 0) G = 0;
                else if (G > 255) G = 255;

                // get final blue
                B = (int)(sumB/Factor + Offset);
                if (B < 0) B = 0;
                else if (B > 255) B = 255;

                result.setPixel(x+1, y+1, Color.argb(A, R, G, B));
            }
        }

        return result;
    }
}
share|improve this question
    
4x times faster: stackoverflow.com/a/10255061/604421 (includes a "trick" to avoid issues with borders) –  h_rules Sep 22 '13 at 21:05
add comment

1 Answer

Just a quick note about this:

B = (int)(sumB/Factor + Offset);
if (B < 0) B = 0;
else if (B > 255) B = 255;

I'd extract out this logic to a separate method:

private int getFinalColor(final int sum, final double factor, final double offset) {
    final int color = (int)(sum / factor + offset);
    return minMaxByte(color);
}

private int minMaxByte(final int value) {
    return minMax(value, 0, 255);
}

private int minMax(final int value, final int min, final int max) {
    if (value < min) {
        return min;
    }
    if (value > max)  {
        return max;
    }
    return value;
}

It could remove some duplication.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.