使用Java从图像中读取像素

使用Java从图像中读取像素,java,image,Java,Image,我正在尝试从RGB转换为灰度图像 执行此任务的方法如下所示: public BufferedImage rgbToGrayscale(BufferedImage in) { int width = in.getWidth(); int height = in.getHeight(); BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);

我正在尝试从RGB转换为灰度图像

执行此任务的方法如下所示:

public BufferedImage rgbToGrayscale(BufferedImage in)
{
    int width = in.getWidth();
    int height = in.getHeight();

    BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    WritableRaster raster = grayImage.getRaster();

    int [] rgbArray = new int[width * height];      
    in.getRGB(0, 0, width, height, rgbArray, 0, width);

    int [] outputArray = new int[width * height];
    int red, green, blue, gray;

    for(int i = 0; i < (height * width); i++)
    {
        red = (rgbArray[i] >> 16) & 0xff;
        green = (rgbArray[i] >> 8) & 0xff;
        blue = (rgbArray[i]) & 0xff;

        gray = (int)( (0.30 * red) + (0.59 * green) + (0.11 * blue));                        

        if(gray < 0)
            gray = 0;
        if(gray > 255)
            gray = 255;

        outputArray[i] = (gray & 0xff);           
        }
    }
    raster.setPixels(0, 0, width, height, outputArray);     

    return grayImage;       
}
public BuffereImage rgbToGrayscale(BuffereImage in)
{
int width=in.getWidth();
int height=in.getHeight();
BuffereImage grayImage=新的BuffereImage(宽度、高度、BuffereImage.TYPE_BYTE_GRAY);
WritableRaster raster=grayImage.getRaster();
int[]rgbArray=新int[宽度*高度];
in.getRGB(0,0,宽度,高度,rgbArray,0,宽度);
int[]outputArray=新int[宽度*高度];
红色、绿色、蓝色、灰色;
对于(int i=0;i<(高度*宽度);i++)
{
红色=(rgbArray[i]>>16)&0xff;
绿色=(rgbArray[i]>>8)&0xff;
蓝色=(rgbArray[i])&0xff;
灰色=(整数)((0.30*红色)+(0.59*绿色)+(0.11*蓝色));
如果(灰色<0)
灰色=0;
如果(灰色>255)
灰色=255;
输出阵列[i]=(灰色&0xff);
}
}
光栅设置像素(0,0,宽度,高度,输出阵列);
返回灰度图像;
}
我有一种将像素值保存在文件中的方法:

public void writeImageValueToFile(BufferedImage in, String fileName)
{
    int width = in.getWidth();
    int height = in.getHeight();

    try
    {
        FileWriter fstream = new FileWriter(fileName + ".txt");
        BufferedWriter out = new BufferedWriter(fstream);

        int [] grayArray = new int[width * height];     
        in.getRGB(0, 0, width, height, grayArray, 0, width);

        for(int i = 0; i < (height * width); i++)
        {                       
            out.write((grayArray[i] & 0xff) + "\n");                                
        }

        out.close();
    } catch (Exception e)
    {
        System.err.println("Error: " + e.getMessage());
    }
}
public void writeImageValueToFile(BuffereImage in,字符串文件名)
{
int width=in.getWidth();
int height=in.getHeight();
尝试
{
FileWriter fstream=新的FileWriter(文件名+“.txt”);
BufferedWriter out=新的BufferedWriter(fstream);
int[]灰度数组=新int[宽度*高度];
in.getRGB(0,0,宽度,高度,灰度数组,0,宽度);
对于(int i=0;i<(高度*宽度);i++)
{                       
out.write((灰度数组[i]&0xff)+“\n”);
}
out.close();
}捕获(例外e)
{
System.err.println(“错误:+e.getMessage());
}
}
我的问题是,我从我的方法中得到的RGB值总是比预期值大

我创建了一个图像,并用颜色128、128、128填充它。根据第一种方法,如果我打印outputArray的数据,我会得到:
r、 g,b=128128128。最终=127--->正确:D

然而,当我调用第二个方法时,我得到了不正确的RGB值187

有什么建议吗


谢谢

我不是这些方面的专家,但RGB值不是存储为十六进制(base16)吗?如果是这样,问题在于您假设操作
&0xff
将导致您的
int
存储/处理为base16。它只是一个符号,字符串中的默认
int
用法将始终是base10

    int a = 200;
    a = a & 0xff;
    System.out.println(a);

    // output
    200
您需要使用显式的base16 toString()方法


看看
javax.swing.GrayFilter
,它使用
RBGImageFilter
类来完成同样的事情,并且具有非常相似的实现。这可能会使您的生活更简单。

为什么不创建另一个灰度缓冲区图像,将原始图像绘制到其中,然后从灰度缓冲区图像中获取像素值
    System.out.println(Integer.toHexString(200));

    // output
    c8