2014-04-13 36 views
0

我正試圖解決讀取圖像的問題。我需要排除像素中的藍色通道,以便產生RG圖像。對陣列中的像素數據進行平均處理

這是我到目前爲止沒有工作的D;

我需要創建一個新的BufferedImage並將每個平均像素(沒有藍色通道)應用於它嗎?我不知道該怎麼做。

+0

因此,您需要拍攝2mX2n像素的圖像並將其轉換爲mXn圖像,並且每個像素(最終)都是原始像素的平均像素數減去藍色成分(即,藍色部分將始終爲零)? – Jared

+0

是的,基本上就是這樣!但我似乎無法弄清楚如何去做。 :S – user3526114

+0

評論:平均RGB值會使圖像質量稍微惡化。 RGB值與亮度沒有線性關係(已應用伽馬曲線)。結果比應該更暗。但是做正確的事情涉及到很慢。看看你是否感興趣:http://www.4p8.com/eric.brasseur/gamma.html –

回答

2

對於初學者來說,你的代碼第二到最後一行改變這一點,看看是否有幫助:

image.setRGB(i, j, (redData[i][j] << 16) | (greenData[i][j] << 8)); 

但有了這個,你將結束,其大小一樣的圖像原來,除了你放棄了藍色通道,並且你在其他通道上的平均值(類似於模糊),但只在每個2×2塊的左上角。

如果你想真正創建的四分之一大小的圖像,你確實需要創建一個新的BufferedImage與寬度和高度的一半,然後將上述行更改爲:

newImage.setRGB(i/2, j/2, (redData[i][j] << 16) | (greenData[i][j] << 8)); 

這裏是一個你的代碼的更新版本應該這樣做(未經測試):

public static BufferedImage isolateBlueChannelAndResize(BufferedImage image) { 
    int imageWidth = image.getWidth(); 
    int imageHeight = image.getHeight(); 
    // Round down for odd-sized images to prevent indexing outside image 
    if ((imageWidth & 1) > 0) imageWidth --; 
    if ((imageHeight & 1) > 0) imageHeight--; 

    BufferedImage newImage = new BufferedImage(imageWidth/2, imageHeight/2, image.getType()); 

    for (int i = 0; i < imageWidth; i += 2) { 
     for (int j = 0; j < imageHeight; j += 2) { 
      int r1 = (image.getRGB(i , j ) >> 16) & 0xff; 
      int r2 = (image.getRGB(i+1, j ) >> 16) & 0xff; 
      int r3 = (image.getRGB(i , j+1) >> 16) & 0xff; 
      int r4 = (image.getRGB(i+1, j+1) >> 16) & 0xff; 
      int red = (r1 + r2 + r3 + r4 + 3)/4; // +3 rounds up (equivalent to ceil()) 

      int g1 = (image.getRGB(i , j ) >> 8) & 0xff; 
      int g2 = (image.getRGB(i+1, j ) >> 8) & 0xff; 
      int g3 = (image.getRGB(i , j+1) >> 8) & 0xff; 
      int g4 = (image.getRGB(i+1, j+1) >> 8) & 0xff; 
      int green = (g1 + g2 + g3 + g4 + 3)/4; // +3 rounds up (equivalent to ceil()) 

      newImage.setRGB(i/2, j/2, (red << 16) | (green << 8)); 
     } 
    } 

    return newImage; 
} 
+0

感謝讓我嘗試實現它; D – user3526114

+0

我創建了一個新的圖像使用: 'BufferedImage newImage = new BufferedImage(imageWidth/2,imageHeight/2,image.getType());' 並使用您的以上設置像素line: 'newImage.setRGB(i/2,j/2,(redData [i] [j] << 16)|(greenData [i] [j] << 8));'但是它輸出原始圖像,相同的大小和一切都沒有預期的黃色色調 – user3526114

+1

你是否改變了說'return image;'到'return newImage;'的行? ;) –

0

我真的覺得更簡單的方法是使用Color類:

import java.awt.Color; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 

public class AverageOutBlue { 
    public static final float AVG_FACTOR = 1f/(4f * 255f); 

    public static BufferedImage processImage(final BufferedImage src) { 
     final int w = src.getWidth(); 
     final int h = src.getHeight(); 

     final BufferedImage out = new BufferedImage(w/2, h/2, src.getType()); 

     for (int i = 0; i < w; i += 2) 
      for (int j = 0; j < h; j += 2) { 
       final Color color = avgColor(src, i, j); 
       out.setRGB(i/2, j/2, color.getRGB()); 
      } 

     return out; 
    } 

    private static Color avgColor(final BufferedImage src, final int i, 
     final int j) { 

     final Color c1 = new Color(src.getRGB(i, j)); 
     final Color c2 = new Color(src.getRGB(i + 1, j)); 
     final Color c3 = new Color(src.getRGB(i + 1, j)); 
     final Color c4 = new Color(src.getRGB(i + 1, j + 1)); 

     final float r = (c1.getRed() + c2.getRed() + c3.getRed() + c4.getRed()) 
          * AVG_FACTOR; 
     final float g = (c1.getGreen() + c2.getGreen() + c3.getGreen() + 
          c4.getGreen()) * AVG_FACTOR; 

     return new Color(r, g, 0f); 
    } 
} 
+0

如果您不想使用Color類,那麼您可以像上面嘗試的那樣對具有「int」RGB值的像素求平均值(使用移位和蒙版),然後返回一個整數而不是「Color」目的。 – Jared

相關問題