2011-05-20 77 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