2010-07-18 85 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