2011-08-01 26 views
0

我试图从RGB转换成GrayScale图像。使用Java从图像中读取像素

执行此任务的方法如下:

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

是我的问题是,在从我的方法中获得的RGB值总是比预期值大。根据第一种方法,如果我打印outputArray的数据,我会得到:
r,g,b = 128,128,128。如果我打印输出数组,最终= 127 --->正确:D

但是,当我调用第二种方法时,我得到了RGB值187,这是不正确的。

有什么建议吗?

谢谢!

+0

为什么不创建另一个灰度级的BufferedImage,将原始图像绘制到其中,然后从灰度级bufferedimage中获取像素值 – MeBigFatGuy

回答

0

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

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

    // output 
    200 

您需要使用明确的base16 toString()方法。

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

    // output 
    c8 
1

看看javax.swing.GrayFilter,它使用RBGImageFilter类来完成同样的事情,具有非常相似的应用。它可能会让你的生活变得更简单。