6

我正在从 24 位 RGB 数据的 unsigned char * 创建一个 NSImage,如下所示:

NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
                            initWithBitmapDataPlanes:(unsigned char **)&data
                            pixelsWide:gWidth
                            pixelsHigh:gHeight
                            bitsPerSample:8
                            samplesPerPixel:3
                            hasAlpha:NO
                            isPlanar:NO
                            colorSpaceName:NSCalibratedRGBColorSpace
                            bytesPerRow:gWidth*3
                            bitsPerPixel:24];

NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(gWidth, gHeight)];
[img addRepresentation:bitmap];

我遇到的问题是我后来向“数据”写了更多的东西,我知道 NSImage 没有复制它。我这么说是因为如果我稍后将所有 0 写入我的数据缓冲区,那么图像就会全黑。

我在 Objective C 上苦苦挣扎,所以如果这是微不足道的,请耐心等待。

如果我制作“数据”的本地副本并且从不释放它,那么一切都会很好,但显然会泄漏:

unsigned char *copy_of_data = new unsigned char[len];
memcpy(copy_of_data, data, len);

我怎么能:

(1) 让 initWithBitmapDataPlanes 创建自己的副本并处理释放?

或者(2)在图像不再需要它之后,在适当的时候自己释放数据?

4

2 回答 2

7

传递参数可能是最简单NULL的。planes然后,在图像代表被分配和初始化后,向它索取它-bitmapData并将您的数据复制到其中。文档中建议使用此方法:

如果 planes 为 NULL 或 NULL 指针数组,则此方法分配足够的内存来保存其他参数描述的图像。然后,您可以获得指向该内存的指针(使用 getPixel:atX:y: 或 bitmapData 方法)并填写图像数据。在这种情况下,分配的内存将属于该对象,并在它被释放时被释放。

重点补充。

于 2013-04-19T05:37:11.913 回答
1

根据此处的文档,如果平面数据在您传入时有效,NSBitmapImageRep则不会获得平面数据的所有权。(“当对象本身被释放时,它不会尝试释放缓冲区。”)。

所以你自己一个人。最简单的方法是将指向数据的指针与指向图像代表的指针放在一起,当一个被释放时,释放另一个。(即,如果它们作为 ivars 保存或临时使用。)如果您使用 GC,这可能会更难。

最干净的是,您还可以创建一个小型包装类,它同时拥有图像表示对象和数据指针,并在该对象的-finalize(或-dealloc)中摆脱数据缓冲区。

于 2013-04-19T00:14:24.877 回答