2011-05-20 80 views
16

我想從CGImage訪問像素數據。我希望能夠以整數的形式訪問RGB值。我覺得我幾乎有與此代碼:從CGImage獲取RGB像素數據

UIImage* theImage = [UIImage imageNamed:@"rgb.png"]; 
CGImageRef cgImageRef = CGImageRetain(theImage.CGImage); 
CFDataRef* imageData = CGDataProviderCopyData(CGImageGetDataProvider(cgImageRef)); 
NSLog(@"the data = %@", imageData); 

這則日誌:

數據= < 010002fe fffdff02 0200fe04 0003fc>

圖片包含5X1 PNG黑,白,紅色,綠色和藍色像素。

我真的不明白我在這裏看到什麼。我如何獲得一組RGB值或類似的東西,以便我可以使用它們。

感謝, 豐富

+0

的[此](可能重複http://stackoverflow.com/questions/144250/how-to-get-the-rgb-values-for-a-pixel-on-an-image-on -the-iphone) – Rayfleck 2011-05-20 14:28:56

回答

55

下面是一些示例代碼,將打印一串關於圖像的相關信息,以及圖像的像素數據的轉儲。它可以處理帶有alpha通道的圖像以及不帶圖像的圖像。該代碼甚至可以處理不在RGB色彩空間中的圖像,但我懷疑你很可能會在iOS上獲得這些圖像。

它複製並粘貼到你的項目,並嘗試運行它針對一些圖像文件,然後也許你可以使其適應您的需求

-(void)imageDump:(NSString*)file 
{ 
    UIImage* image = [UIImage imageNamed:file]; 
    CGImageRef cgimage = image.CGImage; 

    size_t width = CGImageGetWidth(cgimage); 
    size_t height = CGImageGetHeight(cgimage); 

    size_t bpr = CGImageGetBytesPerRow(cgimage); 
    size_t bpp = CGImageGetBitsPerPixel(cgimage); 
    size_t bpc = CGImageGetBitsPerComponent(cgimage); 
    size_t bytes_per_pixel = bpp/bpc; 

    CGBitmapInfo info = CGImageGetBitmapInfo(cgimage); 

    NSLog(
     @"\n" 
     "===== %@ =====\n" 
     "CGImageGetHeight: %d\n" 
     "CGImageGetWidth: %d\n" 
     "CGImageGetColorSpace: %@\n" 
     "CGImageGetBitsPerPixel:  %d\n" 
     "CGImageGetBitsPerComponent: %d\n" 
     "CGImageGetBytesPerRow:  %d\n" 
     "CGImageGetBitmapInfo: 0x%.8X\n" 
     " kCGBitmapAlphaInfoMask  = %s\n" 
     " kCGBitmapFloatComponents = %s\n" 
     " kCGBitmapByteOrderMask  = 0x%.8X\n" 
     " kCGBitmapByteOrderDefault = %s\n" 
     " kCGBitmapByteOrder16Little = %s\n" 
     " kCGBitmapByteOrder32Little = %s\n" 
     " kCGBitmapByteOrder16Big = %s\n" 
     " kCGBitmapByteOrder32Big = %s\n", 
     file, 
     (int)width, 
     (int)height, 
     CGImageGetColorSpace(cgimage), 
     (int)bpp, 
     (int)bpc, 
     (int)bpr, 
     (unsigned)info, 
     (info & kCGBitmapAlphaInfoMask)  ? "YES" : "NO", 
     (info & kCGBitmapFloatComponents) ? "YES" : "NO", 
     (info & kCGBitmapByteOrderMask), 
     ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrderDefault) ? "YES" : "NO", 
     ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder16Little) ? "YES" : "NO", 
     ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Little) ? "YES" : "NO", 
     ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder16Big) ? "YES" : "NO", 
     ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big) ? "YES" : "NO" 
    ); 

    CGDataProviderRef provider = CGImageGetDataProvider(cgimage); 
    NSData* data = (id)CGDataProviderCopyData(provider); 
    [data autorelease]; 
    const uint8_t* bytes = [data bytes]; 

    printf("Pixel Data:\n"); 
    for(size_t row = 0; row < height; row++) 
    { 
     for(size_t col = 0; col < width; col++) 
     { 
      const uint8_t* pixel = 
       &bytes[row * bpr + col * bytes_per_pixel]; 

      printf("("); 
      for(size_t x = 0; x < bytes_per_pixel; x++) 
      { 
       printf("%.2X", pixel[x]); 
       if(x < bytes_per_pixel - 1) 
        printf(","); 
      } 

      printf(")"); 
      if(col < width - 1) 
       printf(", "); 
     } 

     printf("\n"); 
    } 
} 

這裏有我嘗試了兩種圖像輸出示例。他們都是5x3 rgb。 「a.png」圖像具有alpha通道,而「b.rgb」不具有。

===== a.png ===== 
CGImageGetHeight: 5 
CGImageGetWidth: 3 
CGImageGetColorSpace: <CGColorSpace 0x4d08ff0> (kCGColorSpaceDeviceRGB) 
CGImageGetBitsPerPixel:  32 
CGImageGetBitsPerComponent: 8 
CGImageGetBytesPerRow:  20 
CGImageGetBitmapInfo: 0x00000003 
    kCGBitmapAlphaInfoMask  = YES 
    kCGBitmapFloatComponents = NO 
    kCGBitmapByteOrderMask  = NO 
    kCGBitmapByteOrderDefault = NO 
    kCGBitmapByteOrder16Little = NO 
    kCGBitmapByteOrder32Little = NO 
    kCGBitmapByteOrder16Big = NO 
    kCGBitmapByteOrder32Big = NO 
Pixel Data: 
(00,00,00,FF), (FF,FF,FF,FF), (FF,00,00,FF), (00,FF,00,FF), (00,00,FF,FF) 
(00,00,00,FF), (FF,FF,FF,FF), (FF,00,00,FF), (00,FF,00,FF), (00,00,FF,FF) 
(FF,FF,FF,00), (FF,FF,FF,00), (FF,FF,FF,00), (FF,FF,FF,00), (FF,FF,FF,00) 


===== b.png ===== 
CGImageGetHeight: 5 
CGImageGetWidth: 3 
CGImageGetColorSpace: <CGColorSpace 0x4d08ff0> (kCGColorSpaceDeviceRGB) 
CGImageGetBitsPerPixel:  24 
CGImageGetBitsPerComponent: 8 
CGImageGetBytesPerRow:  15 
CGImageGetBitmapInfo: 0x00000000 
    kCGBitmapAlphaInfoMask  = NO 
    kCGBitmapFloatComponents = NO 
    kCGBitmapByteOrderMask  = NO 
    kCGBitmapByteOrderDefault = NO 
    kCGBitmapByteOrder16Little = NO 
    kCGBitmapByteOrder32Little = NO 
    kCGBitmapByteOrder16Big = NO 
    kCGBitmapByteOrder32Big = NO 
Pixel Data: 
(00,00,00), (FF,FF,FF), (FF,00,00), (00,FF,00), (00,00,FF) 
(00,00,00), (FF,FF,FF), (FF,00,00), (00,FF,00), (00,00,FF) 
(00,00,00), (FF,FF,FF), (FF,00,00), (00,FF,00), (00,00,FF) 
+4

感謝你的回答,幫了我很多:) – alexpov 2011-09-13 07:13:05

+0

'bytes [row * bpr + col * bytes_per_pixel]'上次我寫這樣的代碼(不可否認的是很久以前,標準硬件),對於大圖像來說,對於每個像素來說都很慢。增加指針並使用加法而不是乘法會更快。你可能認爲這沒什麼大不了的,但是大的圖像會產生變化,這些像素加起來會很快。 – asveikau 2012-11-19 16:30:56

+1

感謝您的支持,有用。我注意到你正在打印寬度作爲高度,反之亦然。 – user441669 2012-12-30 06:53:54