简体   繁体   中英

How to change the contrast and brightness of colored an image stored as a 2 dimensional pixel-array

I have an image stored as a 2 dimensional array of pixel values. I want to change the contrast and brightness of the image and then store the altered pixelarray as an image, and then display both the original image and the altered image in a JFrame. So the basic steps of my problem is:

  1. Convert the image to a 2 dimensional pixelarray (so I can change the pixel values)
  2. Change the contrast and brightness of the image
  3. Convert the altered pixelarray to an image (preferably BufferedImage)
  4. display the original image and the altered image in a JFrame

I can do step 4 no problem, and I think I am doing step 1 right as well. However, what I can´t get to work is step 2 and 3. I have tried different approaches but always end up with a very distorted image. Just converting the image to a pixelarray and then back to an image again (without changing the pixel values) gives a very distorted image when it should not. Please see the picture down below. 在此处输入图片说明

This is an school assignment, so we have to implement this function (changing the contrast and brightness) on our own, otherwise I would have used some built in function as suggested in this similar question .

Anyone who can assist? Thanks in advance for help!

MY CODE

I´ve put every step (except step 4) in a seperate method to try to make it easier to read and undertand.

image --> 2 dimensional pixelarray

/**
 * converts an image to a 2 dimensional pixel-array
 */
public static int[][] imageToPixelArray() throws IOException {
    File file = new File(filename);
    imageOriginal = ImageIO.read(file);
    Raster raster = imageOriginal.getData();
    int width = raster.getWidth();
    int height = raster.getHeight();
    pixels = new int[width][height];

    sampleModel = raster.getSampleModel();
    int color = 3;

    for(int i = 0; i < width; i++) {
        for(int j = 0; j < height; j++) {
            for(int c = 0; c < color; c++) {
                pixels[i][j] = raster.getSample(i, j, c);
            }
        }
    }
    return pixels;
}

changing the pixel values

public static int[][] compute(int[][] pixels) {
    contrast = 20;
    brightness = 20;
    for(int i = 0;  i < pixels.length; i++) {
        for(int j = 0; j < pixels[i].length; j++) {
            pixels[i][j] = pixels[i][j] * contrast + brightness;
        }
    }
    return pixels;
}

2 dimensional pixelarray --> image

/**
 * converts a 2 dimensional pixel-array to an image
 */
public static BufferedImage pixelArrayToImage(int[][] pixels) {
    int width = pixels.length;
    int height = pixels[0].length;
    WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));

    for(int i = 0; i < width; i++) {
        for(int j = 0; j < height; j++) {
            raster.setSample(i, j, 0, pixels[i][j]);
        }
    }

    imageAltered = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    imageAltered.setData(raster);
    return imageAltered;
}

Your entire code doesn't make sense. I won't say anything about syntax as my Java is quite rusty and I won't give you a solution as this will hurt your learning experience. But I'll point a few things out.

for(int i = 0; i < width; i++) {
  for(int j = 0; j < height; j++) {
     for(int c = 0; c < color; c++) {
        pixels[i][j] = raster.getSample(i, j, c);
     }
  }
}

Why do you assign three different values in a row to to the same integer pixels[i][j] ? You either another array to store three values per pixel or find some other way to encode the rgb information.

public static int[][] compute(int[][] pixels) {
    contrast = 20;
    brightness = 20;
    for(int i = 0;  i < pixels.length; i++) {
        for(int j = 0; j < pixels[i].length; j++) {
            pixels[i][j] = pixels[i][j] * contrast + brightness;
        }
    }
    return pixels;
}

How did you come up with pixels[i][j] = pixels[i][j] * contrast + brightness; ? This doesn't change contrast, you just make the image brighter. Contrast is not a global factor. I think you need to get some basic knowledge about digital images, their structure and values as well as a minimum of image processing terminology.

If you reduce an rgb image to a single channel you throw away information that you cannot get back. Unfortunately you don't really describe what you want to achieve so i cannot give you a lot of advice. But your code is nonsense.

I managed to solve my problem (and shortening my code in the process)! My code changes the brightness and contrast by generating a random value given by a interval.

Here´s the code if someone else ever has the same problem :)

/**
 * alter the image´s contrast and brightness
 * @throws IOException
 */
public void alterImage() throws IOException {
    imageAltered = new BufferedImage(imageOriginal.getWidth(), imageOriginal.getHeight(), BufferedImage.TYPE_INT_RGB);
    brightness = rand.nextInt(150 + 200 + 1) - 200; //values from 150 to 200
    contrast = 1.5 + (5.0 - 1.5) * rand.nextDouble(); //values from 1.5 to 5.0

    for(int i = 0; i < imageOriginal.getWidth(); i++) {
        for(int j = 0; j < imageOriginal.getHeight(); j++) {
            Color c = new Color(imageOriginal.getRGB(i, j));
            int red = (int) contrast * c.getRed() + brightness;
            int green = (int) contrast * c.getGreen() + brightness;
            int blue = (int) contrast * c.getBlue() + brightness;

            if(red > 255) { // the values of the color components must be between 0-255
                red = 255;
            } else if(red < 0) {
                red = 0;
            }
            if(green > 255) {
                green = 255;
            } else if(green < 0) {
                green = 0;
            }
            if(blue > 255) {
                blue = 255;
            } else if(blue < 0) {
                blue = 0;
            }
            imageAltered.setRGB(i, j, new Color(red, green, blue).getRGB());
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM