how to create a gray scale image from pixel values using java

感情迁移 提交于 2019-12-24 03:06:08

问题


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(" ");
    }
    

回答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;
}



回答2:


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:


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



来源:https://stackoverflow.com/questions/29281358/how-to-create-a-gray-scale-image-from-pixel-values-using-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!