如何从UIImage或CGImage获取基础像素数据?

时间:2011-11-18 21:09:27

标签: objective-c iphone uiimage cgimage

我在网上尝试了很多“解决方案”,我发现所有这些都有错误因此无法正常工作。我需要知道UIImage中像素的颜色。我怎样才能获得这些信息?

2 个答案:

答案 0 :(得分:7)

获取原始数据

来自Apple的Technical Q&A QA1509它说,这将通过从数据提供商处获取原始图像数据来获取原始图像数据。

CFDataRef CopyImagePixels(CGImageRef inImage) 
{     
   return CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 
}

需要不同的格式或颜色空间

如果您希望获得颜色匹配的数据并使用特定格式,您可以使用类似于以下代码示例的内容:

void ManipulateImagePixelData(CGImageRef inImage)
{
    // Create the bitmap context
    CGContextRef cgctx = CreateARGBBitmapContext(inImage);
    if (cgctx == NULL) 
    { 
        // error creating context
        return;
    }

     // Get image width, height. We'll use the entire image.
    size_t w = CGImageGetWidth(inImage);
    size_t h = CGImageGetHeight(inImage);
    CGRect rect = {{0,0},{w,h}}; 

    // Draw the image to the bitmap context. Once we draw, the memory 
    // allocated for the context for rendering will then contain the 
    // raw image data in the specified color space.
    CGContextDrawImage(cgctx, rect, inImage); 

    // Now we can get a pointer to the image data associated with the bitmap
    // context.
    void *data = CGBitmapContextGetData (cgctx);
    if (data != NULL)
    {

        // **** You have a pointer to the image data ****

        // **** Do stuff with the data here ****

    }

    // When finished, release the context
    CGContextRelease(cgctx); 
    // Free image data memory for the context
    if (data)
    {
        free(data);
    }

}

CGContextRef CreateARGBBitmapContext (CGImageRef inImage)
{
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

     // Get image width, height. We'll use the entire image.
    size_t pixelsWide = CGImageGetWidth(inImage);
    size_t pixelsHigh = CGImageGetHeight(inImage);

    // Declare the number of bytes per row. Each pixel in the bitmap in this
    // example is represented by 4 bytes; 8 bits each of red, green, blue, and
    // alpha.
    bitmapBytesPerRow   = (pixelsWide * 4);
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    // Use the generic RGB color space.
    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    if (colorSpace == NULL)
    {
        fprintf(stderr, "Error allocating color space\n");
        return NULL;
    }

    // Allocate memory for image data. This is the destination in memory
    // where any drawing to the bitmap context will be rendered.
    bitmapData = malloc( bitmapByteCount );
    if (bitmapData == NULL) 
    {
        fprintf (stderr, "Memory not allocated!");
        CGColorSpaceRelease( colorSpace );
        return NULL;
    }

    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits 
    // per component. Regardless of what the source image format is 
    // (CMYK, Grayscale, and so on) it will be converted over to the format
    // specified here by CGBitmapContextCreate.
    context = CGBitmapContextCreate (bitmapData,
                                    pixelsWide,
                                    pixelsHigh,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaPremultipliedFirst);
    if (context == NULL)
    {
        free (bitmapData);
        fprintf (stderr, "Context not created!");
    }

    // Make sure and release colorspace before returning
    CGColorSpaceRelease( colorSpace );

    return context;
}

特定像素的颜色

假设RGB,一旦你有一个格式的数据,你喜欢找到颜色就是在数据数组中移动并在特定像素位置获取RGB值。

答案 1 :(得分:2)

如果您只想获得一个像素或几个像素,您可以尝试采用一种不同的方法。创建1x1位图上下文并使用偏移在其上绘制图像,以便获得所需的像素。

CGImageRef image = uiimage.CGImage;
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);

// Setup 1x1 pixel context to draw into
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char rawData[4];
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, 
                                             1, 
                                             1, 
                                             bitsPerComponent,
                                             bytesPerRow,
                                             colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);

// Draw the image
CGContextDrawImage(context,
                   CGRectMake(-offset.x, offset.y-height, width, height),
                   image);

// Done
CGContextRelease(context);

// Get the pixel information     
unsigned char red   = rawData[0];
unsigned char green = rawData[1];
unsigned char blue  = rawData[2];
unsigned char alpha = rawData[3];