简体   繁体   English

使用Java从图像读取像素

[英]Reading pixels from images using Java

I'm trying to convert from RGB to GrayScale Image. 我正在尝试从RGB转换为GrayScale Image。

The method that does this task is the following: 执行此任务的方法如下:

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

I have a method that saves the pixels value in a file: 我有一种将像素值保存在文件中的方法:

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

The problem that I have is that, the RGB value I get from my method, is always bigger than the expected one. 我遇到的问题是,我从方法中获得的RGB值始终大于预期值。

I created an image and I filled it with color 128, 128, 128. According to the first method, if I print the outputArray's data, I get: 我创建了一个图像,并用颜色128、128、128填充了它。根据第一种方法,如果我打印outputArray的数据,则会得到:
r, g, b = 128, 128, 128. Final = 127 ---> correct :D r,g,b = 128、128、128。最终= 127 --->正确:D

However, when I called the second method, I got the RGB value 187 which is incorrect. 但是,当我调用第二种方法时,我得到了不正确的RGB值187。

Any suggestion? 有什么建议吗?

Thanks!!! 谢谢!!!

Take a look at javax.swing.GrayFilter , it uses the RBGImageFilter class to accomplish the same thing and has very similar implementation. 看一看javax.swing.GrayFilter ,它使用RBGImageFilter类来完成相同的事情,并且具有非常相似的实现。 It may make your life simpler. 它可以使您的生活更简单。

I'm not an expert at these things but aren't RGB values stored as hex (base16)? 我不是这些方面的专家,但是RGB值不是存储为十六进制(base16)吗? If so, theproblem lies in your assumption that the operation & 0xff will cause your int to be stored/handled as base16. 如果是这样,问题出在您的假设上,即操作& 0xff将导致您的int被存储/处理为base16。 It is just a notation and default int usage in strings will always be base10. 这只是一种表示法,字符串中的默认int用法始终为base10。

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

    // output
    200

You need to use an explicit base16 toString() method. 您需要使用显式的base16 toString()方法。

    System.out.println(Integer.toHexString(200));

    // output
    c8

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM