我必须将多个图像合并为单个(全部是高分辨率),它会占用大量内存。我将原始图像保存到本地目录,并将调整大小的图像设置为图像视图,放置在主图像上的不同位置。现在在保存最终合并图像时,我从本地目录中读取原始图像。这里内存增加,导致更多图像的错误(由于内存而崩溃)。
这里是代码:从本地目录中检索原始图像
UIImage *originalImage = [UIImage imageWithContentsOfFile:[self getOriginalImagePath:imageview.tag]];
是否有其他方法可以从本地目录获取图像而无需将其加载到内存中。
提前致谢
答案 0 :(得分:2)
如果图像没有进入内存,就无法加载图像。理论上,使用某些图像格式,您可以实现自己的读取器,在读取文件时缩小图像,以便原始大小永远不会在内存中结束,但这需要大量工作才能获得很少的收益。
总的来说,您最好只将不同尺寸的图像保存为单独的文件并仅加载正确的尺寸(您似乎根据屏幕尺寸缩放它们,因此不需要那么多不同的版本)。 / p>
如果您继续动态调整它们的大小,请尽量确保尽快删除原始版本,即不要再保留任何图像引用,并且可能将整个内容包含在内@autoreleasepool
(假设正在使用ARC):
@autoreleasepool {
UIImage *originalImage = [UIImage imageWithContentsOfFile:[self getOriginalImagePath:imageview.tag]];
UIImage *pThumbsImage = [self scaleImageToSize:CGSizeMake(AppScreenBound.size.width, AppScreenBound.size.height) imageWithImage:pOrignalImage];
originalImage = nil;
imageView.image = pThumbImage;
pThumbImage = nil;
// … ?
}
类似地处理创建中间版本的任何其他图像处理,即尽快删除不再需要的引用(例如通过分配nil
或使它们超出范围),并放置{{围绕可能生成临时对象的子部分。
答案 1 :(得分:1)
找到一个解决方案,将其作为我自己问题的答案发布,可能会帮助其他人。来自Image I/O Programming Guide
的参考“imageWithContentsOfFile:”的替代方法,可以使用 图像源
这是我如何使用它的代码。
UIImage *originalWMImage = [self createCGImageFromFile:your-image-path];
方法createCGImageFromFile:获取图像内容而不将其加载到内存
-(UIImage*) createCGImageFromFile :(NSString*)path
{
// Get the URL for the pathname passed to the function.
NSURL *url = [NSURL fileURLWithPath:path];
CGImageRef myImage = NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys[2];
CFTypeRef myValues[2];
// Set up options if you want them. The options here are for
// caching the image in a decoded form and for using floating-point
// values if the image format supports them.
myKeys[0] = kCGImageSourceShouldCache;
myValues[0] = (CFTypeRef)kCFBooleanTrue;
myKeys[1] = kCGImageSourceShouldAllowFloat;
myValues[1] = (CFTypeRef)kCFBooleanTrue;
// Create the dictionary
myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
(const void **) myValues, 2,
&kCFTypeDictionaryKeyCallBacks,
& kCFTypeDictionaryValueCallBacks);
// Create an image source from the URL.
myImageSource = CGImageSourceCreateWithURL((CFURLRef)url, myOptions);
CFRelease(myOptions);
// Make sure the image source exists before continuing
if (myImageSource == NULL){
fprintf(stderr, "Image source is NULL.");
return NULL;
}
// Create an image from the first item in the image source.
myImage = CGImageSourceCreateImageAtIndex(myImageSource,
0,
NULL);
CFRelease(myImageSource);
// Make sure the image exists before continuing
if (myImage == NULL){
fprintf(stderr, "Image not created from image source.");
return NULL;
}
return [UIImage imageWithCGImage:myImage];
}
答案 2 :(得分:0)
这是代码:调整大小的图像并简单地分配给imageview。然后我在imageview上执行缩放和旋转。
UIImage *pThumbsImage = [self scaleImageToSize:CGSizeMake(AppScreenBound.size.width, AppScreenBound.size.height) imageWithImage:pOrignalImage];
[imageView setImage:pThumbImage];
保存时:此代码在for循环中:(在主图像上合并的图像数量)
// get size of the second image
CGFloat backgroundWidth = canvasSize.width;
CGFloat backgroundHeight = canvasSize.height;
//Image View: to be merged
UIImageView* imageView = [[UIImageView alloc] initWithImage:stampImage];
[imageView setFrame:CGRectMake(0, 0, stampFrameSize.size.width , stampFrameSize.size.height)];
// Rotate Image View
CGAffineTransform currentTransform = imageView.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, radian);
[imageView setTransform:newTransform];
// Scale Image View
CGRect imageFrame = [imageView frame];
// Create Final Stamp View
UIView *finalStamp = nil;
finalStamp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, imageFrame.size.width, imageFrame.size.height)];
// Set Center of Stamp Image
[imageView setCenter:CGPointMake(imageFrame.size.width /2, imageFrame.size.height /2)];
[finalImageView addSubview:imageView];
// Create Image From image View;
UIGraphicsBeginImageContext(finalStamp.frame.size);
[finalStamp.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *pfinalMainImage = nil;
// Create Final Image With Stamp
UIGraphicsBeginImageContext(CGSizeMake(backgroundWidth, backgroundHeight));
[canvasImage drawInRect:CGRectMake(0, 0, backgroundWidth, backgroundHeight)];
[viewImage drawInRect:CGRectMake(stampFrameSize.origin.x , stampFrameSize.origin.y , stampImageFrame.size.width , stampImageFrame.size.height) blendMode:kCGBlendModeNormal alpha:fAlphaValue];
pfinalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
这里一切都很好。保存或生成合并图像时会出现问题。
答案 3 :(得分:0)
这是一个老问题,但我最近不得不面对这样的事情......所以我有答案。
我不得不将很多图像合并为一个,并且遇到了同样的问题。内存增加,直到应用程序崩溃。我创建的函数返回了UIImage,这就是问题所在。 ARC没有及时发布,因此我必须更改为返回CGImageRef并在适当的时间释放它们。