java圖片灰度化原理與實現
24位彩色圖與8位灰度圖
首先要先介紹一下24位彩色圖像,在一個24位彩色圖像中,每個像素由三個字節表示,通常表示為RGB。通常,許多24位彩色圖像存儲為32位圖像,每個像素多余的字節存儲為一個alpha值,表現有特殊影響的信息[1]。在RGB模型中,如果R=G=B時,則彩色表示一種灰度顏色,其中R=G=B的值叫灰度值,因此,灰度圖像每個像素只需一個字節存放灰度值(又稱強度值、亮度值),灰度范圍為0-255[2]。這樣就得到一幅圖片的灰度圖。
幾種灰度化的方法
分量法:使用RGB三個分量中的一個作為灰度圖的灰度值。</span>最值法:使用RGB三個分量中最大值或最小值作為灰度圖的灰度值。
均值法:使用RGB三個分量的平均值作為灰度圖的灰度值。
加權法:由于人眼顏色敏感度不同,按下一定的權值對RGB三分量進行加權平均能得到較合理的灰度圖像。一般情況按照:Y = 0.30R + 0.59G + 0.11B。</span>
[注]加權法實際上是取一幅圖片的亮度值(人眼對綠色的敏感最高,對藍色敏感最低 )作為灰度值來計算,用到了YUV模型。在[3]中會發現作者使用了Y = 0.21 r + 0.71 g + 0.07 b(百度百科:Y = 0.30 r + 0.59 g + 0.11 b)來計算灰度值。實際上,這種差別應該與是否使用伽馬校正有關[1]。
強制設置灰度化的方法(效果相對就差)
/**
- 圖片灰化(效果不行,不建議。據說:搜索“Java實現灰度化”,十有八九都是一種方法)
- @param bufferedImage 待處理圖片
- @return
@throws Exception */ public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();BufferedImage grayBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); for (int x = 0; x < width; x++) {
for(int y = 0 ; y < height; y++) { grayBufferedImage.setRGB(x, y, bufferedImage.getRGB(x, j)); }
}
}</pre>加權法灰度化(效果較好)
/**
- 圖片灰化(參考:http://www.codeceo.com/article/java-image-gray.html)
- @param bufferedImage 待處理圖片
- @return
@throws Exception */ public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight();
BufferedImage grayBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { // 計算灰度值 final int color = bufferedImage.getRGB(x, y); final int r = (color >> 16) & 0xff; final int g = (color >> 8) & 0xff; final int b = color & 0xff; int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b); int newPixel = colorToRGB(255, gray, gray, gray); grayBufferedImage.setRGB(x, y, newPixel); }
}
return grayBufferedImage;
}
/**
- 顏色分量轉換為RGB值
- @param alpha
- @param red
- @param green
- @param blue
@return */ private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0; newPixel += alpha; newPixel = newPixel << 8; newPixel += red; newPixel = newPixel << 8; newPixel += green; newPixel = newPixel << 8; newPixel += blue;
return newPixel;
}</pre>
參考
[1] 《多媒體技術教程》Ze-Nian Li,Mark S.Drew著,機械工業出版社。
[2] 百度百科:灰度值
[3] Java color image to grayscale conversion algorithm(s)