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

如何使用java从像素值创建灰度图像,java,image,bufferedimage,grayscale,Java,Image,Bufferedimage,Grayscale,我的要求是,我需要将彩色图像转换为灰度图像,并将灰度图像的像素值获取到一个数组,并在该数组上执行一些加密算法,然后再次使用此更改的像素数组,我需要转换回/创建灰度图像并显示它。 这是我的疑问 使用彩色图像,我获得了三种不同阵列中的RGB像素值。据我所知,灰度像素可以通过执行red+green+blue/3=gray来获得。这里红色、蓝色、绿色和灰色是二维阵列。这是获得灰度像素值的正确方法吗 gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3; 如果这是正确的,那

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

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

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

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

    对于(int x=0;x有多种方法可以将颜色转换为灰度,您的方法是最简单和正确的

    您可以使用以下命令将阵列恢复为图片

    而数据是一个长度为1D的整数数组(希望我没有混淆索引)

    int[]数据=新的int[高度*宽度];
    
    对于(int i=0;i,我建议您创建一个新的缓冲区图像,类型为\ u BYTE \ u GRAY,您可以直接操作像素,而不是通过自己操作像素将图像转换为灰度

    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
        }
    }
    
    公共静态BuffereImage convertToGray(BuffereImage双色)
    {
    BuffereImage biGray=新的BuffereImage(biColor.getWidth(),biColor.getHeight(),BuffereImage.TYPE_BYTE_GRAY);
    biGray.getGraphics().drawImage(双色,0,0,null);
    返回biGray;
    }
    公共静态无效像素(BuffereImage biGray)
    {
    字节[]图像数据=((数据缓冲字节)biGray.getRaster().getDataBuffer()).getData();
    对于(int i=0;i
    如果出于某种原因,您希望从字节数组创建一个全新的图像,只需创建一个新图像并将像素复制到其字节数组中即可

    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;
    }
    
    public static buffereImage createImageFromArray(字节[]imageData,整数宽度,整数高度)
    {
    BuffereImage newImage=新的BuffereImage(宽度、高度、BuffereImage.TYPE_BYTE_GRAY);
    字节[]新数据=((DataBufferByte)newImage.getRaster().getDataBuffer()).getData();
    对于(int i=0;i
    公共类灰度测试{
    公共无效转换(int[]r、int[]g、int[]b、int-imageWidth、int-imageHeight){
    int[]灰度值=converToGrayscale(r,g,b);
    int[]encryptedValues=加密值(灰度值);
    BuffereImage imageFromGrayScale=创建图像(灰度值、图像宽度、图像高度);
    BuffereImage imageFromEncryptedValues=createImage(encryptedValues、imageWidth、imageHeight);
    }
    私有BuffereImage createImage(int[]值、int imageWidth、int imageHeight){
    BuffereImage=新的BuffereImage(128,128,BuffereImage.TYPE_INT_ARGB);
    int[]光栅=((DataBufferInt)image.getRaster().getDataBuffer()).getData();
    System.arraycopy(值,0,光栅,0,光栅.长度);
    返回图像;
    }
    私有int[]加密值(int[]灰度值){
    //运行加密
    //我只是返回输入
    返回灰度值;
    }
    私有int[]converToGrayscale(int[]r,int[]g,int[]b){
    int sz=r.长度;
    int[]灰度=新int[sz];
    对于(int i=0;i

    当然,您可以使用不同的BuffereImage类型,但我不想为此处理Int以外的任何东西。但是,此代码段应该执行我认为您需要执行的操作。

    请参阅java.awt.Image.ColorModelColor模型用于正确获取RGB像素值?我的要求是使用像素数组创建灰度图像本教程。不直接使用数组,但如果你有一个BuffereImage,它会为你做。你有你正在尝试做的代码样本吗?关于我的第一个问题,灰度像素值可以像我在上面代码中提到的那样获得吗?如果是,那么我想知道灰度缓冲图像是如何获得的可以使用灰色[x][y]数组创建您在评论中提到的链接用于将彩色图像转换为灰度图像,据我所知,它与像素阵列或使用像素值创建缓冲图像无关。给出的示例用于获取灰度图像的像素值,您能告诉我如何使用像素值创建灰度图像吗(即,从imageData字节数组到灰度图像。)当我试图显示imageData数组时,它在数组中显示负值,如-1。我认为字节值与int值不同,并再次尝试使用相同的字节值创建图像,但它不起作用。因此,我觉得我尝试获取的任何字节值都是错误的值。byte[]newData=((DataBufferByte)newImage.getRaster().getDataBuffer()).getData();此行给出了错误的字节。您可能会得到一些负值。是否尝试保存图像以查看其外观?例如,ImageIO.write(图像,“JPEG”,新文件ImageOutputStream(新文件(“image.jpg”));图像本身没有保存..我认为这只是因为字节数组。Hai,您提供的将数组返回到图片的链接用于彩色图像(RGB数组在那里).我想从单个阵列中获取灰度图像唯一的区别是,在灰度中,红色/蓝色/绿色部分都是相同的。我写道,您获取灰度的算法是正确的??浅黄色
    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.
    }
    
    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;
    }
    
    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;
        }
    }