2013-04-18 10 views
6

を作成するinitWithBitmapDataPlanesを使用したとき、私はそうのような24ビットのRGBデータのunsigned char型の*からNSImageではを作成しています:ココアのメモリ管理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)画像が必要なくなった後、適切な場合はデータを自分自身で解放しますか?

答えて

6

planesパラメータにNULLを渡すのが最も簡単な場合があります。次に、画像担当者が割り当てられて初期化された後、その画像に-bitmapDataと尋ねて、そのデータをコピーします。このアプローチは、ドキュメントで提案されている:

平面がNULLであるか、またはNULLポインタの配列は、この方法は、他の引数で記述された画像を保持する 十分なメモリを割り当てる場合。 は、getPixel:atX:y:または bitmapDataメソッドを使用してこのメ​​モリへのポインタを取得し、画像データを入力できます。この場合、 割り当てられたメモリはオブジェクトに属し、 が解放されると解放されます。

強調が追加されました。

+0

Ooh!私は逃しました。私はそれに渦を巻いて、それがうまくいくかどうかを見ます。 – spartygw

+0

これは完璧に動作します!どうもありがとうございました。 – spartygw

1

docs hereによると、NSBitmapImageRepは、それが渡されたときに有効であれば、プレーンデータの所有権を取得しません(「オブジェクト自体が解放されると、バッファを解放しようとしません」)。

あなたはあなた自身です。最も簡単な方法は、ポインタを画像のポインタの横にあるデータの周りに置いておき、解放されたときにもう一方を解放することです。 (つまり、イヴァールとして保管されている場合や一時的に使用されている場合)、GCを使用している場合はそれが難しくなる可能性があります。

イメージ・オブジェクトとデータ・ポインタの両方を所有する小さなラッパー・クラスを作成し、そのオブジェクトの-finalize(または-dealloc)にデータ・バッファを取り除くこともできます。