Ios 在iPhone4/4S和iPad2上生成5400万像素的图像
我目前正在进行一个项目,该项目必须生成分辨率为9000x6000像素的拼贴画,由15张照片生成。我面临的问题是,当我完成绘制时,我得到一个空图像(这15个图像不是在上下文中绘制的) 这个问题只出现在内存512MB的设备上,比如iPhone 4/4S或iPad 2,我认为这是系统造成的问题,因为它无法为这个应用程序分配足够的内存。当我运行这一行时:Ios 在iPhone4/4S和iPad2上生成5400万像素的图像,ios,iphone,objective-c,memory-management,core-graphics,Ios,Iphone,Objective C,Memory Management,Core Graphics,我目前正在进行一个项目,该项目必须生成分辨率为9000x6000像素的拼贴画,由15张照片生成。我面临的问题是,当我完成绘制时,我得到一个空图像(这15个图像不是在上下文中绘制的) 这个问题只出现在内存512MB的设备上,比如iPhone 4/4S或iPad 2,我认为这是系统造成的问题,因为它无法为这个应用程序分配足够的内存。当我运行这一行时:UIGraphicsBeginImageContextWithOptions(outputSize,不透明,1.0f)应用程序的内存使用量增加了216M
UIGraphicsBeginImageContextWithOptions(outputSize,不透明,1.0f)代码>应用程序的内存使用量增加了216MB,总内存使用量达到240MB
我无法理解的是,为什么我试图在for循环中绘制的图像没有在当前上下文中呈现始终?我总是强调这个词,因为在30次测试中,图像只呈现一次(不改变任何代码行)
问题编号2:如果这是由于系统无法分配足够的内存而导致的问题,是否有其他方法来生成此映像,例如由文件输出流支持的CGContextRef,以便它不会将映像保留在内存中
这是代码:
CGSize outputSize = CGSizeMake(9000, 6000);
BOOL opaque = YES;
UIGraphicsBeginImageContextWithOptions(outputSize, opaque, 1.0f);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(currentContext, [UIColor blackColor].CGColor);
CGContextFillRect(currentContext, CGRectMake(0, 0, outputSize.width, outputSize.height));
for (NSUInteger i = 0; i < strongSelf.images.count; i++)
{
@autoreleasepool
{
AGAutoCollageImageData *imageData = (AGAutoCollageImageData *)strongSelf.layout.images[i];
CGRect destinationRect = CGRectMake(floorf(imageData.destinationRectangle.origin.x * scaleXRatio),
floorf(imageData.destinationRectangle.origin.y * scaleYRatio),
floorf(imageData.destinationRectangle.size.width * scaleXRatio),
floorf(imageData.destinationRectangle.size.height * scaleYRatio));
CGRect sourceRect = imageData.sourceRectangle;
// Draw clipped image
CGImageRef clippedImageRef = CGImageCreateWithImageInRect(((ALAsset *)strongSelf.images[i]).defaultRepresentation.fullScreenImage, sourceRect);
CGContextDrawImage(currentContext, drawRect, clippedImageRef);
CGImageRelease(clippedImageRef);
}
}
// Pull the image from our context
strongSelf.result = UIGraphicsGetImageFromCurrentImageContext();
// Pop the context
UIGraphicsEndImageContext();
cgsizeoutputsize=CGSizeMake(9000,6000);
布尔不透明=是;
UIGraphicsBeginImageContextWithOptions(输出大小,不透明,1.0f);
CGContextRef currentContext=UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(currentContext[UIColor blackColor].CGColor);
CGContextFillRect(currentContext,CGRectMake(0,0,outputSize.width,outputSize.height));
对于(i=0;i
附言:控制台只显示“内存警告”,预期会看到这些警告。听起来像一个很酷的项目
策略:尝试在每个循环结束时释放imageData
(明确地,在释放clippedImageRef
之后)
战略:
如果你确实需要用这样的“高”输入来支持这样的“低”RAM需求,也许你应该考虑2个备选方案:
压缩(显然):即使是最小的,肉眼可见的,JPEG压缩也可以走很长的路
拆分:从不“真正”合并图像。具有表示大图像的阵列数据结构。为表示逻辑制作实用程序
内存增加了216MB是显而易见的,因为54*4(每像素4字节)是216MB,我知道这是显而易见的:),但我不知道的是为什么这15幅图像没有在上下文中绘制。我把这些关于内存使用的信息仅仅作为提示发布。“我目前正在做一个项目,必须生成一个9000x6000像素分辨率的拼贴画,由15张照片生成。”——只是不要。台式机上很少有应用程序是最好的解决方案。提示:内存诊断工具将此分配归类为“疯狂请求”。好的,但不幸的是,我不能告诉我的客户。我试图说服他,我们应该在服务器上进行渲染,但没有成功。@arturgrigor为什么需要复合表示?希望不是200+MB的传输。对于Quartz使用的底层虚拟内存,最好使用单独的映像。使用单独的资源要好得多。您可以通过使用CGBitmapContext/CGImage将其渲染到内存映射文件来实现,但使用这种设计可能会在大多数情况下陷入死胡同。因此,问题不在于如何适应大内存需求,而在于如何将图像呈现为合成图像,因为资源需求非常高。