2010-07-18 4 views
5

Ho un UIImage e vorrei mettere i suoi dati in un file e quindi utilizzare un file mappato per risparmiare memoria. Apparentemente, i dati UIImage sono privati ​​e non è possibile accedervi. Avresti qualche suggerimento per risolverlo?Memory Map UIImage

Grazie!

risposta

8

Se si desidera memorizzare la mappa dei dati di immagine codificati, quindi mmap un file e fornire un riferimento ai dati passando un CGDataProviderRef a CGImageCreate.

mapped = mmap(NULL , length , ...); 
provider = CGDataProviderCreateWithData(mapped , mapped , length , munmap_wrapper); 
image = CGImageCreate(... , provider , ...); 
uiimage = [UIImage imageWithCGImage:image]; 
... 

Dove munmap_wrapper è qualcosa di simile:

// conform to CGDataProviderReleaseDataCallback 
void munmap_wrapper(void *p , const void *cp , size_t l) { munmap(p , l); } 

Se si desidera la memoria mappare i pixel effettivi, al posto dei dati di origine codificati, si potrebbe fare qualcosa di simile con un CGBitmapContext. Dovresti anche creare il fornitore e l'immagine in modo che l'immagine faccia riferimento agli stessi pixel del contesto. Qualunque cosa sia disegnata nel contesto sarà il contenuto dell'immagine. La larghezza, l'altezza, lo spazio colore e altri parametri dovrebbero essere identici per il contesto e l'immagine.

context = CGBitmapContextCreate(mapped , ...); 

In questo caso, la lunghezza sarà almeno bytes_per_row * altezza byte in modo che il file deve essere almeno così grande.

Se si dispone di un'immagine esistente e si desidera eseguire l'mmap dei pixel, creare il contesto bitmap con le dimensioni e lo spazio colore dell'immagine e utilizzare CGContextDrawImage per disegnare l'immagine nel contesto.

Non hai detto la fonte della tua immagine, ma se la stai creando in fase di esecuzione sarebbe più efficiente crearla direttamente nel contesto bitmap. Qualsiasi creazione di immagini richiede un contesto bitmap dietro le quinte, quindi potrebbe essere la memoria mappata dall'inizio.

+0

Grazie per questa grande risposta! Lo esaminerò. Non ho molta familiarità con la mappatura della memoria, ma stavo cercando modi per mantenere basso l'uso della memoria. Sì, ho accesso alla bitmap poiché manipolo questa bitmap e quindi la converto in una UIImage usando un CGDataProviderRef e CGImageCreate. Quindi immagino che potrei fare la mappatura della memoria a questo punto dando un dato mappato in memoria al CGDataProviderRef. – Kamchatka

+0

Puoi provare 'MAP_ANON' se non ti interessa il file. Con quello puoi trattare mmap quasi come malloc. – drawnonward

+0

Posso usare MAP_ANON senza specificare un file? Se faccio un mmap e poi provo a memcpy i dati con le stesse dimensioni di mmap, ottengo un EXC_BAD_ACCESS. – Kamchatka