2013-04-18 9 views
6

sto creando un NSImage da un unsigned char * di dati 24bit RGB in questo modo:cacao gestione della memoria quando si utilizza initWithBitmapDataPlanes per creare 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]; 

Il problema che sto avendo è che sto scrivendo in seguito più roba a 'dati' e so che NSImage non ne sta facendo una copia. Lo dico perché se in seguito scrivo tutti gli 0 sul mio buffer di dati, l'immagine diventa completamente nera.

Sto lottando con l'obiettivo C, quindi portami dietro se questo è banale.

Se faccio una copia locale dei 'dati' e mai libera poi le cose funzionano bene, ma perde ovviamente:

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

Come posso neanche:

(1) rendere i initWithBitmapDataPlanes creano la propria copia e gestire la deallocazione?

oppure (2) liberare i dati autonomamente, se necessario, dopo che l'immagine non ne ha più bisogno?

risposta

6

Potrebbe essere più semplice passare NULL per il parametro planes. Quindi, dopo che il rappresentante dell'immagine è stato assegnato e inizializzato, chiedilo per il suo -bitmapData e copia i tuoi dati in quello. Questo approccio è suggerito nei documenti:

Se piani è NULL o una matrice di puntatori NULL, questo metodo alloca memoria sufficiente per contenere l'immagine descritta dagli altri argomenti. L'utente può quindi ottenere i puntatori a questa memoria (con il metodo getPixel: atX: y: o bitmapData) e inserire i dati dell'immagine. In questo caso, la memoria allocata apparterrà all'oggetto e verrà liberata quando è liberato .

Enfasi aggiunta.

+0

Ooh! Ho perso questo. Farò un giro e vedrò se funziona. – spartygw

+0

Che funziona perfettamente! Grazie mille. – spartygw

1

Secondo lo docs here, NSBitmapImageRep non acquisisce la proprietà dei dati del piano se è valido quando lo si inoltra. ("Quando l'oggetto stesso viene liberato, non tenterà di liberare i buffer.").

Quindi sei da solo. Il modo più semplice è quello di mantenere il puntatore ai dati intorno al puntatore al rep di immagine, e quando uno viene rilasciato, libera l'altro. (Ad esempio, se vengono conservati come ivars o vengono utilizzati temporaneamente.) Potrebbe essere più difficile se si utilizza GC.

Molto pulito, è possibile anche creare una classe wrapper di piccole dimensioni che possiede sia l'oggetto rappresentante immagine sia il puntatore dati e nello -finalize (o -dealloc) di tale oggetto, eliminare il buffer di dati.

Problemi correlati