问题
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.
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;
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