2010-07-18 4 views
5

Ich habe eine UIImage und ich würde gerne seine Daten in eine Datei und dann eine zugeordnete Datei, um etwas Speicher zu speichern. Anscheinend sind die UIImage Daten privat und es ist nicht möglich, darauf zuzugreifen. Hättest du irgendwelche Vorschläge, um das zu lösen?Memory Map UIImage

Danke!

Antwort

8

Wenn Sie die codierten Bilddaten im Speicher ablegen möchten, dann mappen Sie eine Datei und stellen Sie einen Verweis auf die Daten bereit, indem Sie eine CGDataProviderRef an CGImageCreate übergeben.

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

Wo munmap_wrapper so etwas wie dieses:

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

Wenn Sie den Speicher wollen die tatsächlichen Pixel abzubilden, anstelle der codierten Quellendaten, Sie etwas ähnliches mit einem CGBitmapContext tun würde. Sie würden auch den Anbieter und das Bild erstellen, sodass das Bild auf die gleichen Pixel wie der Kontext verweist. Was im Kontext gezeichnet wird, ist der Inhalt des Bildes. Die Breite, Höhe, der Farbraum und andere Parameter sollten für den Kontext und das Bild identisch sein.

context = CGBitmapContextCreate(mapped , ...); 

In diesem Fall wird Länge mindestens bytes_per_row * Höhe seines Bytes, so dass die Datei muss mindestens so groß.

Wenn Sie ein vorhandenes Bild haben und die Pixel mappen möchten, erstellen Sie den Bitmap-Kontext mit der Größe und dem Farbraum Ihres Bildes und verwenden Sie CGContextDrawImage, um das Bild im Kontext zu zeichnen.

Sie haben nicht die Quelle Ihres Bildes angegeben, aber wenn Sie es zur Laufzeit erstellen, wäre es effizienter, es direkt im Bitmap-Kontext zu erstellen. Jede Bilderstellung erfordert einen Bitmap-Kontext hinter den Kulissen, so dass es genauso gut von Anfang an auf den Speicher abgebildet werden kann.

+0

Danke für diese großartige Antwort! Ich werde das untersuchen. Ich bin mit Speicherabbildung nicht wirklich vertraut, aber ich suchte nach Möglichkeiten, um meine Speicherbelegung niedrig zu halten. Ja, ich habe Zugriff auf die Bitmap, da ich diese Bitmap manipuliere und sie dann mit CGDataProviderRef und CGImageCreate in einen UIImage umwandle. Ich denke also, ich könnte die Speicherzuordnung an dieser Stelle vornehmen, indem ich dem CGDataProviderRef Speicherdaten zuordnen würde. – Kamchatka

+0

Sie könnten 'MAP_ANON' versuchen, wenn Sie sich nicht um die Datei kümmern. Damit können Sie mmap fast wie malloc behandeln. – drawnonward

+0

Kann ich MAP_ANON verwenden, ohne eine Datei anzugeben? Wenn ich eine mmap mache und dann versuche, die Daten mit der gleichen Größe wie mmap zu speichern, bekomme ich eine EXC_BAD_ACCESS. – Kamchatka