I've captured a picture to an UIImage, but now I want to access the data and analyse them. Really, I just want the middle row, converted to greyscale, for now I want to discard the rest. However, UIImage doesn't give me access to the raw data, I have to convert it to either PNG or JPEG in an NSData using functions like UIImagePNGRepresentation(image). That's fine, but how do I continue to convert a PNG file to raw pixels?
UIImage has provided me with the dimensions of the picture, and I expect the pixels to be in ARGB format, but I haven't found the equivalent of NSBitmapImageRep in the SDK. Any suggestions on how I can convert an NSData* with a ARGB PNG image into a grayscale NSArray* of int or similar?
I am trying to get into iPhone stuff, and have made some progress wrapping my head around Obj-C and such. I am trying to get the raw pixel data from a UIImage as well (similar problem as you seemed to be having).
I know I need to convert it to a CGImage, but I can't get the code in the apple link above to compile in my app.
Can anyone help? I am trying to simply get those two functions:
CreateARGBBitmapContext and ManipulateImagePixelData
to compile into my app. How should I do this? Where should they go? They are C functions (not Obj-C) so should they go into a .c file, or a .m file? Or do I need to use a .mm file?
I have tried most everything I can think of but no progress so far.
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.
// 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?
Not all combinations of pixel formats are supported with CGBitmapContextCreate(). See the section on Supported Pixel Formats in the Quartz 2D Programming Guide. Pretty sure the combination you're using isn't supported.
Yes, I had read those and am coming to the conclusion that what I want is not directly supported. I have also discovered that UIImage SHOULD only contain an image of maximum size 1024 x 1024 pixels, which is also "interesting"
I will now try and manually alter the buffer and remove all the alpha bytes (that is, I will have to check first if I really do have 8 bits per colour component in my graphics context
I am also wondering if there is another way I could get at the pixel data in my photo. Let's see .... will post the result soon.
hai niks,
as i m also working on Barcode reader i have a bit of doubt. i have developed a c code to read 24-bit bmp barcode. i ported it successfully on iphone. But the problem here nw is that i don't know how to convert jpeg file to bmp file.Can u share ur knowledge with me regarding above problem.
can u send me some code which does this conversion.
thanx