开发者

How to access pixels of an NSBitmapImageRep?

开发者 https://www.devze.com 2022-12-24 15:05 出处:网络
I have an NSBitmapImageRep that is created like this: NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc]

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 chars, 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 chars).

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 NULLs, so it will be writing beyond the end of the storage you gave it. This will smash your stack, crash your application, or both.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号