2

My requirement is that, I need to convert a color image into gray scale image and obtain pixels values of gray scale image to an array and perform some encryption algorithm on that array and again using this changed pixel array, I need to convert back/create a gray scale image and display it. Here are my doubts.

  1. Using the color image I have obtained the RGB pixel values in three different arrays. As per my knowledge, gray scale pixels can be obtained by doing red+green+blue/3=gray. Here red, blue, green, gray are 2-D arrays. Is this right way to obtain gray scale pixel values?

    gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
    
  2. If this is correct, then I can easily perform algorithm on that array. The real problem arises here. How to convert back/create a gray scale image using that pixel array. An example to show how a gray scale image can be created using pixel values will be really helpful. Thank you.

    for(int x = 0;x<=height;x++) {
        for(int y = 0;y<=width;y++) {
            gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
            System.out.print(gray[x][y]+"\t");
        }
         System.out.println(" ");
    }
    
8
  • See java.awt.Image.ColorModel Commented Mar 26, 2015 at 14:46
  • Color model is used to get RGB pixel values right? My requirement is to create a gray scale image using array of pixels Commented Mar 26, 2015 at 14:52
  • Check out this tutorial. java2s.com/Tutorial/Java/0261__2D-Graphics/… Doesn't use the array directly, but if you have a BufferedImage it will do it for you. Do you have code sample of what you're trying to do? Commented Mar 26, 2015 at 14:53
  • well regarding my first question can gray scale pixel values can be obtained like the way I have mentioned in the code above? If yes, then I want to know how a gray scale buffered image can be created using the array gray[x][y] Commented Mar 26, 2015 at 15:03
  • The link you have mentioned in the comment is used to convert color image to gray scale image, it is no where related to pixel arrays or creating buffered image using pixel values, as per my knowledge. Commented Mar 26, 2015 at 15:08

3 Answers 3

1

Instead of converting the image to grayscale by manipulating the pixels yourself I'd suggest creating a new BufferedImage of TYPE_BYTE_GRAY. Then you can manipulate the pixels directly.

public static BufferedImage convertToGray(BufferedImage biColor)
{
    BufferedImage biGray = new BufferedImage(biColor.getWidth(), biColor.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
    biGray.getGraphics().drawImage(biColor, 0, 0, null);
    return biGray;
}

public static void manipulatePixels(BufferedImage biGray)
{
    byte [] imageData = ((DataBufferByte)biGray.getRaster().getDataBuffer()).getData();

    for (int i = 0; i < imageData.length; i++)
    {
        // do manipulation/encryption here - or on the entire array at once
    }
}

If for some reason you want to create a brand new image from the byte array, just create a new image and copy the pixels into its byte array.

public static BufferedImage createImageFromArray(byte[] imageData, int width, int height)
{
    BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    byte [] newData = ((DataBufferByte) newImage.getRaster().getDataBuffer()).getData();

    for (int i = 0; i < imageData.length; i++)
    {
        newData[i] = imageData[i];
    }
    return newImage;
}
Sign up to request clarification or add additional context in comments.

5 Comments

The example given is for grabbing pixel values of gray scale image, can you tell me how can I create a gray scale image using the pixel values (i.e.., imageData byte array to gray scale image.)
when I tried to display the imageData array, it is showing negative values like -1 in the array. I thought that byte values are different from int values and again tried to create an image using the same byte values but it is not working.
so I felt like what ever byte values I tried to obtain are wrong values. byte [] newData = ((DataBufferByte) newImage.getRaster().getDataBuffer()).getData(); This line is giving wrong bytes.
It is expected that you would get some negative values. Have you tried saving the image to see what it looks like? i.e. ImageIO.write(image, "JPEG", new FileImageOutputStream(new File("image.jpg")));
Image itself is not saving.. I think because of that byte array only.
0
public class GrayScaleTest {

    public void convert(int[] r, int[] g, int[] b, int imageWidth, int imageHeight) {
        int[] grayScaleValues = converToGrayscale(r,g,b);
        int[] encryptedValues = encryptValues(grayScaleValues);

        BufferedImage imageFromGrayScale = createImage(grayScaleValues, imageWidth, imageHeight);
        BufferedImage imageFromEncryptedValues = createImage(encryptedValues, imageWidth, imageHeight);
    }

    private BufferedImage createImage(int[] values, int imageWidth, int imageHeight) {
        BufferedImage image = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
        int[] raster = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(values,0,raster,0,raster.length);
        return image;
    }

    private int[] encryptValues(int[] grayScaleValues) {
        // run your encryption
        // I just return input
        return grayScaleValues;
    }

    private int[] converToGrayscale(int[] r, int[] g, int[] b) {
        int sz = r.length;
        int[] grayscale = new int[sz];
        for(int i = 0; i < sz; i++) {
            grayscale[i] = (r[i] + g[i] + b[i]) / 3;
        }
        return grayscale;
    }
}

You can of course use a different bufferedimage type, but I didnt want to have to deal with anything other than ints for this. But this code snippet should do what I think you want done.

3 Comments

BufferedImage.TYPE_INT_ARGB is for gray scale image or RGB image?
raster variable can take only 1-D array, but my arrays(r[][], g[][],b[][],gray[][]) are 2-D arrays. should i copy (gray[][]--->2-D array to 1-D array and then perform the task?
Yes, it would be easiar to copy to 1D array for readability. The other solution is converting the x,y indexes of your 2-D arrays to a 1-D index, pixel pr. pixel. Inside the convertToGrayscale method, you can find the index in each color array with int index = (imageWidth * y) + x; The BufferedImage.TYPE_INT_ARGB is just for ease and habit, so that you can always work with ints no matter what. If the image size is an issue, choose a byte sized image instead.
0

there are multiple ways to transform a color to a greyscale, your way is the simpliest and correct.

you can Turn your array back into a picture by using this http://www.java2s.com/Tutorial/Java/0261__2D-Graphics/CreateBufferredImagewithcolorsbasedonintegerarray.htm

BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, width, height, data, 0, width);

while data is a 1D IntegerArray with the length (hope I didnt mix up the indices)

int[] data=new int[height*width];
for (int i=0;i<height;i++){
    for (int k=0;k<width;k++){
        //EDIT: The gray[][] array, is the one you already got.
        data[i*width+k]=getIntFromColor(gray[i][k],gray[i][k],gray[i][k]);
    }
}

where the method of creating the correct Integer from your colorcode (int, int, int) is given in: how to convert rgb color to int in java

public int getIntFromColor(int Red, int Green, int Blue){
    Red = (Red << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff
    Green = (Green << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff
    Blue = Blue & 0x000000FF; //Mask out anything not blue.

    return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together.
}

Greetings Reineke

2 Comments

Hai, the link you have given to turn your array back to picture is for color image(RGB arrays are there). I want to obtain gray scale image from the single array
the only difference is, that in grayscale the red/blue/green parts are all the same. and i wrote, that your algorithm to obtain the grayscale is correct??

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.