Question

Im trying to blur an image depending on a user input. If it is 1 then the blur image will average a 3X3 square and put it into the middle one.

P P P       All the pixels will be averaged and put into S.
P S P
P P P

I think I have come up with a correct solution that takes into the edges but the image is turning completely black. Can anyone find a problem with this code or is it another problem?

int range = blur_slider.getValue();

for (int x = 0; x < source.getWidth(); x++) {
    for (int y = 0; y < source.getHeight(); y++) {
        double red_sum = 0.0;
        double green_sum = 0.0;
        double blue_sum = 0.0;
        // finds the min x and y values and makes sure there are no out of bounds exceptions

        int x_range_min = x - range;
        if (x_range_min < 0) {
            x_range_min = 0;
        }

        int x_range_max = x + range;
        if (x_range_max >= new_frame.getWidth()) {
            x_range_max = new_frame.getWidth() - 1;
        }

        int y_range_min = y - range;
        if (y_range_min < 0) {
            y_range_min = 0;
        }

        int y_range_max = y + range;
        if (y_range_max >= new_frame.getHeight()) {
            y_range_max = new_frame.getHeight() - 1;
        }
        // averages the pixels within the min and max values and puts it into the pixel at the center. copy new frame is the frame that has previous
        // work done on it, it is used so that new blur pixels that are set do not affect later pixels. new_frame is the main frame that will be set.

        for (int k = x_range_min; k < x_range_max; k++) {
            for (int j = y_range_min; j < y_range_max; j++) {
                Pixel p = copy_new_frame.getPixel(x, y);
                red_sum += p.getRed();
                green_sum += p.getGreen();
                blue_sum += p.getBlue();
            }
        }
        double num_pixels = x_range_max * y_range_max;
        ColorPixel tempPixel = new ColorPixel(red_sum / num_pixels, green_sum / num_pixels, blue_sum / num_pixels);
        new_frame.setPixel(x, y, tempPixel);
    }

}
frame_view.setFrame(new_frame);
Was it helpful?

Solution

Yes. The number of pixels is not

double num_pixels = x_range_max * y_range_max;

You didn't subtract the minimum of the range so you're assuming far too many pixels and dividing by a value that's too large.

Corrected:

double num_pixels = (x_range_max - x_range_min) * (y_range_max - y_range_min);

@andy identified another problem in the code that is probably not causing black pixels but will cause you to just take the middle pixel instead of the average of the pixels in a square.

There is yet another problem in your code that causes it to take an area that's smaller than you intended.

You should change your for loops to:

for (int k = x_range_min; k <= x_range_max; k++) {
    for (int j = y_range_min; j <= y_range_max; j++) {

And your calculation for the number of pixels to:

double num_pixels = (x_range_max - x_range_min + 1) * (y_range_max - y_range_min + 1);

With your current implementation, you're missing the right and bottom-most pixels. I.e. you're doing this (after you have applied @andy's fixed - before that you're just taking 'S'):

P P
P S

OTHER TIPS

I think this one

Pixel p = copy_new_frame.getPixel(x,y);

should be

Pixel p = copy_new_frame.getPixel(k,j);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top