Как получить доступ к пикселям NSBitmapImageRep? - PullRequest
0 голосов
/ 26 марта 2010

У меня есть NSBitmapImageRep, который создается так:

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];

Теперь я хочу получить доступ к данным пикселей, чтобы получить указатель на плоскости пикселей с помощью

unsigned char *bitmapData;
[imageRep getBitmapDataPlanes:&bitmapData];

Согласно Документации это возвращает массив C из пяти символьных указателей. Но как это может сделать это? поскольку тип аргумента unsigned char **, он может возвращать только массив char s, но не массив char указателей .

Итак, мне интересно, как получить доступ к отдельным пикселям. У вас есть идея, как это сделать?

(я знаю, что есть метод – setColor:atX:y:, но он кажется довольно медленным, если его вызывать для каждого отдельного пикселя большого растрового изображения.)

Ответы [ 2 ]

1 голос
/ 26 марта 2010

Если вы просто хотите перебрать пиксели, все, что вам нужно - это -bitmapData.

0 голосов
/ 27 марта 2010

Согласно документации это возвращает массив C из пяти символьных указателей. Но как это может сделать это? поскольку тип аргумента unsigned char **, он может возвращать только массив символов, но не массив указателей на символы.

Неправильно. unsigned char ** - это указатель на хотя бы один указатель на хотя бы один unsigned char.

Итак, вы должны передать указатель на массив указателей, то есть указатель на массив массивов. Примерно так:

unsigned char *buffers[5];
[bitmapImageRep getBitmapDataPlanes:buffers];

Если изображение является плоским, то каждый элемент buffers будет указателем на плоскость компонента; для RGB buffers[0] - красная плоскость, buffers[1] - зеленая плоскость, buffers[2] - синяя плоскость, buffers[3] - альфа-плоскость. Конечно, каждая плоскость - это буфер, содержащий значения для этого канала (как unsigned char с).

Если изображение не является плоским, то вы получите только один элемент - данные RGBA.

Особо следует отметить это предложение из документации, на которую вы ссылались:

Если самолетов меньше пяти, остальные указатели будут установлены на NULL.

Это означает, что код, который вы показываете, содержит переполнение буфера: вы передаете указатель на хранилище для одного указателя, но представитель изображения ожидает хранилища не менее пяти, и это даст вам пять указателей и / или NULL с, так что он будет записывать за пределы того места, которое вы ему дали. Это разобьет ваш стек, приведет к сбою приложения или к обоим.

...