How to access pixels of an NSBitmapImageRep?
I have an NSBitmapImageRep
that is created like this:
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:waveformSize.width
pixelsHigh:waveformSize.height
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:YES
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:0
bitsPerPixel:0];
Now I want to access the pixel data so I get a pointer to the pixel planes using
unsigned char *bitmapData;
[imageRep getBitmapDataPlanes:&bitmapData];
According to the Docu开发者_开发百科mentation this returns a C array of five character pointers. But how can it do that? since the type of the argument is unsigned char **
, it can only return an array of char
s, but not an array of char
pointers.
So, this leaves me wondering how to access the individual pixels. Do you have an idea how to do that?
(I know there is the method – setColor:atX:y:
, but it seems to be pretty slow if invoked for every single pixel of a big bitmap.)
If you just want to iterate over the pixels, -bitmapData should be all you need.
According to the Documentation this returns a C array of five character pointers. But how can it do that? since the type of the argument is
unsigned char **
, it can only return an array of chars, but not an array of char pointers.
Incorrect. unsigned char **
is a pointer to at least one pointer to at least one unsigned char
.
So, you're supposed to pass a pointer to an array of pointers—that is, a pointer to an array of arrays. Something like this:
unsigned char *buffers[5];
[bitmapImageRep getBitmapDataPlanes:buffers];
If the image rep is planar, then each element of buffers
will be a pointer to a component plane; for RGB, buffers[0]
is the red plane, buffers[1]
is the green plane, buffers[2]
is the blue plane, and buffers[3]
is the alpha plane. Each plane is, of course, a buffer holding the values for that channel (as unsigned char
s).
If the image rep is not planar, then you'll get only one element, which is the RGBA data.
Of particular note is this sentence from the documentation you linked to:
If there are less than five planes, the remaining pointers will be set to
NULL
.
This means that the code you show contains a buffer overflow: You're passing a pointer to storage for one pointer, but the image rep expects storage for no fewer than five, and it will give you five pointers and/or NULL
s, so it will be writing beyond the end of the storage you gave it. This will smash your stack, crash your application, or both.
精彩评论