2010-07-18 152 views
5

我有一個UIImage,我想將其數據放入一個文件,然後使用映射文件來保存一些內存。顯然,UIImage數據是私密的,無法訪問它。你有任何建議來解決這個問題嗎?內存映射UIImage

謝謝!

回答

8

如果要存儲映射編碼的圖像數據,然後通過將CGDataProviderRef傳遞給CGImageCreate來mmap文件並提供對數據的引用。

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

哪裏munmap_wrapper是這樣的:

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

如果你想存儲映射的實際像素,而不是編碼的源數據,你會做一個CGBitmapContext類似的東西。您還可以創建提供程序和圖像,以便圖像指向與上下文相同的像素。無論在上下文中繪製什麼都將是圖像的內容。上下文和圖像的寬度,高度,色彩空間和其他參數應該相同。

context = CGBitmapContextCreate(mapped , ...); 

在這種情況下,長度將至少爲bytes_per_row *高度字節,所以文件必須至少大。

如果您有一個現有的圖像,並且您想要對像素進行mmap,那麼使用圖像的大小和顏色空間創建位圖上下文,並使用CGContextDrawImage在上下文中繪製圖像。

您沒有說出圖像的來源,但是如果您在運行時創建它,則直接在位圖上下文中創建它會更有效。任何圖像創建都需要在後臺創建位圖上下文,所以它可能是從一開始就映射的內存。

+0

感謝這個偉大的答案!我會研究這一點。我對存儲器映射並不十分熟悉,但我一直在尋找方法來減少內存使用量。 是的,我可以訪問位圖,因爲我操縱這個位圖,然後使用CGDataProviderRef和CGImageCreate將其轉換爲UIImage。所以我想我可以通過給CGDataProviderRef提供一個內存映射數據來做內存映射。 – Kamchatka 2010-07-18 15:46:13

+0

如果你不關心這個文件,你可以試試'MAP_ANON'。有了這個,你可以像對待malloc一樣對待mmap。 – drawnonward 2010-07-18 16:30:37

+0

我可以在不指定文件的情況下使用MAP_ANON嗎?如果我做了一個mmap,然後嘗試memcpy與mmap大小相同的數據,我得到一個EXC_BAD_ACCESS。 – Kamchatka 2010-07-18 16:43:28