2013-04-29 78 views
0

數組我想做到以下幾點:轉換的24位PNG圖像GLubytes

  1. 從24位PNG圖像讀取RGB顏色值
  2. 平均RGB值,並將其儲存成一列Glubytes。

我提供了我希望執行這兩個步驟的功能。 我的函數返回一個Glubytes數組,但是所有元素的值都是0. 所以即時猜測即時讀取圖像數據不正確。

我在閱讀圖片時出錯了什麼? (也許我的格式不正確)。

這裏是我的功能:

+ (GLubyte *) LoadPhotoAveragedIndexPNG:(UIImage *)image numPixelComponents: (int)numComponents 
{ 
// Load an image and return byte array. 
CGImageRef textureImage = image.CGImage; 
if (textureImage == nil) 
{ 
    NSLog(@"LoadPhotoIndexPNG: Failed to load texture image"); 
    return nil; 
} 

NSInteger texWidth = CGImageGetWidth(textureImage); 
NSInteger texHeight = CGImageGetHeight(textureImage); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

GLubyte *indexedData = (GLubyte *)malloc(texWidth * texHeight); 
GLubyte *rawData = (GLubyte *)malloc(texWidth * texHeight * numComponents); 

CGContextRef textureContext = CGBitmapContextCreate(
                rawData, 
                texWidth, 
                texHeight, 
                8, 
                texWidth * numComponents, 
                colorSpace, 
                kCGImageAlphaPremultipliedLast); 
CGColorSpaceRelease(colorSpace); 
CGContextDrawImage(textureContext, 
        CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), 
        textureImage); 
CGContextRelease(textureContext); 

int rawDataLength = texWidth * texHeight * numComponents; 
for (int i = 0, j = 0; i < rawDataLength; i += numComponents) 
{ 
    GLubyte b = rawData[i]; 
    GLubyte g = rawData[i + 1]; 
    GLubyte r = rawData[i + 2]; 
    indexedData[j++] = (r + g + b)/3; 
} 

return indexedData; 
} 

下面是測試圖像IM加載(PNG格式RGB色彩空間): enter image description here

+0

希望這個鏈接幫助http://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage- cocoa-touch-or-cgimage-core-graphics – Ram 2013-04-29 09:52:24

回答

1

一些記錄,請檢查參數bgr在最後的for循環中生成正常值。如果你犯了一個錯誤,那麼indexedData[j++] = (r + g + b)/3;這3個參數的大小是1字節,你不能像這樣總結它們。使用更大的整數,對它們進行類型轉換,並將結果轉換回數組。 (你最有可能得到溢出)

+0

嗯。關於溢出非常好的一點。我會試着看看這是否有效。 – AlvinfromDiaspar 2013-04-30 09:16:13

+0

嗨,我改變了它,所以即時類型轉換爲int,然後是3,然後將它轉換爲一個字節。但現在我得到所有平均像素的值85。不知道發生了什麼事。 – AlvinfromDiaspar 2013-05-01 10:34:33

+0

也許這是巧合,但255/3 = 85.奇怪的是,我的測試圖像中的大部分像素都是黑色! – AlvinfromDiaspar 2013-05-01 10:35:41

1
從原來的問題

除了這裏(甚至相關)

for (int i = 0, j = 0; i < rawDataLength; i += numComponents) 
{ 
    GLubyte b = rawData[i]; 
    GLubyte g = rawData[i + 1]; 
    GLubyte r = rawData[i + 2]; 
    indexedData[j++] = (r + g + b)/3; 
} 

(r + g + b) 

這個表達式將被執行的表達中是一個重大的問題GLubyte大小的整數操作。如果r + g + b的總和大於GLubyte可以容納的類型,它將溢出。無論何時通過中間變量處理數據(良好風格!)選擇足夠大的變量類型以保持您可能遇到的最大值。另一種方法是鑄造表達式,如

indexedData[j++] = ((uint16_t)r + (uint16_t)g + (uint16_t)b)/3; 

但是這很麻煩閱讀。此外,如果您正在處理已知大小的整數,請使用stdint.h中的類型。你知道,你需要每個通道8位。你也可以在增量子句中使用逗號運算符

uint8_t *indexedData = (GLubyte *)malloc(texWidth * texHeight); 

/* ... */ 

for (int i = 0, j = 0; i < rawDataLength; i += numComponents, j++) 
{ 
    uint16_t b = rawData[i]; 
    uint16_t g = rawData[i + 1]; 
    uint16_t r = rawData[i + 2]; 
    indexedData[j] = (r + g + b)/3; 
}