如何使用java从像素值创建灰度图像

时间:2015-03-26 14:41:15

标签: java image bufferedimage grayscale

我的要求是,我需要将彩色图像转换为灰度图像并获取灰度图像的像素值到数组并对该数组执行一些加密算法并再次使用此更改的像素数组,我需要转换返回/创建灰度图像并显示它。 这是我的疑惑。

  1. 使用彩色图像我已经获得了三个不同阵列中的RGB像素值。据我所知,可以通过red+green+blue/3=gray获得灰度像素。这里红色,蓝色,绿色,灰色是二维阵列。这是获得灰度像素值的正确方法吗?

    gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
    
  2. 如果这是正确的,那么我可以轻松地对该阵列执行算法。真正的问题出现在这里。如何使用该像素阵列转换/创建灰度图像。显示如何使用像素值创建灰度图像的示例将非常有用。谢谢。

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

3 个答案:

答案 0 :(得分:1)

不是通过自己操纵像素将图像转换为灰度,而是建议创建一个TYPE_BYTE_GRAY的新BufferedImage。然后你可以直接操作像素。

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
    }
}

如果出于某种原因想要从字节数组创建一个全新的图像,只需创建一个新图像并将像素复制到其字节数组中。

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

答案 1 :(得分:0)

有多种方法可以将颜色转换为灰度,您的方式是最简单和最正确的。

您可以使用此功能将阵列重新转换为图片 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);

虽然数据是一个长度为1D的IntegerArray(希望我没有混淆索引)

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]);
    }
}

其中从colorcode(int,int,int)创建正确的Integer的方法在: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.
}

问候 Reineke

答案 2 :(得分: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;
    }
}

你当然可以使用不同的bufferedimage类型,但我不想为此处理除了int之外的任何事情。但是,此代码段应该执行我想要的 。