Ios 如何解决在视网膜显示设备中加载图像时占用大量内存空间的问题?
我正在开发一个iPad paint应用程序,用户可以在其中绘制N幅图像,并有一个图库将绘制的图像导出到不同的社交网络等。这里的问题是,我收到了很多内存警告(最终导致崩溃)当我使用iPad视网膜设备时。我尝试分析并发现,与非视网膜设备相比,imageio_png_数据、VM:CoreAnimation、VM:CG光栅数据等项目占用了大量内存。我知道这与图像加载有关,因为我正在应用程序中加载png、JPG等图像文件格式 1.如何解决在视网膜显示设备中加载图像时占用大量内存空间的问题 2.如何使应用程序避免对imageio_png_数据、VM:CoreAnimation、VM:CG光栅数据等术语的大量内存消耗Ios 如何解决在视网膜显示设备中加载图像时占用大量内存空间的问题?,ios,objective-c,opengl-es,memory-profiling,Ios,Objective C,Opengl Es,Memory Profiling,我正在开发一个iPad paint应用程序,用户可以在其中绘制N幅图像,并有一个图库将绘制的图像导出到不同的社交网络等。这里的问题是,我收到了很多内存警告(最终导致崩溃)当我使用iPad视网膜设备时。我尝试分析并发现,与非视网膜设备相比,imageio_png_数据、VM:CoreAnimation、VM:CG光栅数据等项目占用了大量内存。我知道这与图像加载有关,因为我正在应用程序中加载png、JPG等图像文件格式 1.如何解决在视网膜显示设备中加载图像时占用大量内存空间的问题 2.如何使应用程
3.我得到一些信息,PVR纹理图像可用于解决图像的内存相关问题。我是否可以将其集成到本机iOS应用程序中。(我还在运行时保存图像,因为它是一个绘画应用程序。)如果此选项适合您,您可以压缩低质量的图像
UIImage *image = [UIImage imageNamed:@"image.png"];
NSData *imageData = UIImageJPEGRepresentation(image, 0.2); // 0.2 - quality
UIImage *lowQualityImage=[UIImage imageWithData:data];
如果有许多图像未存储在数组中,请使用NSCache。您应该在UIImage类别中实现此方法:
- (UIImage *)resizedImage:(CGSize)newSize
transform:(CGAffineTransform)transform
drawTransposed:(BOOL)transpose
interpolationQuality:(CGInterpolationQuality)quality {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
CGImageRef imageRef = self.CGImage;
// Build a context that's the same dimensions as the new size
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(imageRef),
0,
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef));
// Rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform);
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality);
// Draw into the context; this scales the image
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
// Clean up
CGContextRelease(bitmap);
CGImageRelease(newImageRef);
return newImage;
}
对于非视网膜,将UIImage的大小调整为UIImageViews大小;对于视网膜,将views大小乘以2。当使用视网膜(x2)图像时,加载的图像占用的内存约为4倍,对于(x3)图像占用的内存约为9倍。使用png等格式时,数据需要解压缩、复制并发送到GPU,这在某些情况下会导致每个图像的内存中有3个图像数据副本,这显然是不好的。不过你的iPad应该有足够的内存来加载更多的纹理,然后你可以实时绘制 根据您告诉我们的,很难知道您的问题真正在哪里,但您应该确保的第一件事是,当您加载图像时,您应该序列化操作。这意味着您应该加载1个纹理,确保已从加载中清除所有图像数据(3个副本中的2个),然后开始加载下一个纹理。我不知道你用什么来加载纹理,但在你的例子中,好的“获取原始RGBA数据”应该是最好的 如果情况并非如此,并且您实际上加载了太多的纹理,那么您需要考虑如何最小化纹理计数或其分辨率,这样您就达到了设备的功能,并且没有什么可以做的了。此外,使用纹理图集可能会对您有很大帮助
当涉及到纹理加载和删除时,可以考虑重新使用纹理,将新的数据发送给它,而不是删除和创建新的纹理。对于图像数据本身,您可以在一些加载时间(甚至可能只是第一次运行应用程序)加载图像,然后将原始RGBA数据保存到新文件中。使用此方法将显著减少纹理加载时间和内存占用,缺点是将使用用户磁盘空间