Creating a simple 3 x 8 bit RGB bitmap buffer from a UIImage object?
Hi All,
I need to convert a UIImage to simple RGB byte values (8 bits per color component R, G & B, i.e. 3 x 8 = 24 bits per pixel).
So far I am using the UIImagePickerController to "snap" and retrieve a UIImage object. I need to create a bitmap with byte values like RGBRGBRGB.... etc
E.g. If I have a 10x10 pixel image I would need to allocate a void* buffer of 10 x 3 x 10 = 300 bytes for the bitmap buffer.
I am trying to use CGBitmapContextCreate and friends to do this but cannot find the appropriate color Space to do the conversion. First there is the Alpha value in the UIImage, 2nd, CGBitmapContextCreate is failing because it seems to think it has to copy the alpha value which I do not need in my bitmap context.
<pre>
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 24 bits/pixel; 3-component colorspace; kCGImageAlphaNone; 1920 bytes/row.
</pre>
I need to specify only 24 bits per pixel and not 32 as my graphics context (buffer) does not require the Alpha value.
Here is some code I have already tried:
<pre>
// Get imag size
CGSize size = image.size;
size_t pixelsWide = size.width;
size_t pixelsHigh = size.height;
CGRect rect = {{0,0},{pixelsWide,pixelsHigh}};
// 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.
size_t bitmapBytesPerRow = (pixelsWide * 3);
size_t bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the this RGB color space with no Alpha, just RGB
//CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB );
//CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB );
if (colorSpace == NULL)
{
NSLog(@"Error allocating color space");
return NULL;
}
void* bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
NSLog(@"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.
CGContextRef context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaNone);
if (context == NULL)
{
free (bitmapData);
NSLog(@"Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
// 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(context, rect, image.CGImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
void *data = CGBitmapContextGetData (context);
if (data != NULL)
{
// **** You have a pointer to the image data ****
NSLog(@"Conversion ok");
// **** Do stuff with the data here ****
}
// When finished, release the context
CGContextRelease(context);
// Free image data memory for the context
if (data)
{
free(data);
}
return NULL;
}
</pre>
Does anybody know how to do this like above or is there a different way?
|