Objective c 在转换为 UIImage 时丢失了 CIImage 内存
Posted
技术标签:
【中文标题】Objective c 在转换为 UIImage 时丢失了 CIImage 内存【英文标题】:Objective c lost CIImage memory when converting to UIImage 【发布时间】:2016-04-28 17:22:29 【问题描述】:我有以下代码:
- (void)applySepiaFilter
// Set previous image
NSData *buffer = [NSKeyedArchiver archivedDataWithRootObject: self.mainImage.image];
[_images push:[NSKeyedUnarchiver unarchiveObjectWithData: buffer]];
[_images push:[NSKeyedUnarchiver unarchiveObjectWithData: buffer]];
UIImage* u = [_images pop];
CIImage *image = [[CIImage alloc] initWithCGImage:u.CGImage];//[CIImage imageWithContentsOfURL:fileNameAndPath];
CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"
keysAndValues: kCIInputImageKey, image,
@"inputIntensity", @0.8, nil];
CIImage *outputImage = [filter outputImage];
//UIImage *newImage =
self.mainImage.image = [UIImage imageWithCIImage:outputImage];
其中 _images 是一个堆栈:
#import "Stack.h"
@implementation Stack
NSMutableArray *stack;
-(id)init
self = [super init];
if(self!=nil)
stack = [[NSMutableArray alloc] init];
return self;
-(void)push:(id)obj
[stack addObject:obj];
-(id)pop
id lastObj = [stack lastObject];
if (stack.count > 1)
[stack removeLastObject];
return lastObj;
-(NSUInteger)size
return stack.count;
@end
self.mainImage 是一个 UIImageView。
第一次运行该方法时,我得到了所需的棕褐色过滤器。我相信它没有正确保存 self.mainImage.image,因为如果我连续两次运行该方法,我会得到 self.mainImage.image 的空白图像,如果我第三次运行它,我会收到 SIGABRT 错误。 我添加了一个断点并开始遍历代码。我注意到在 self.mainImage.image 方法的第一遍结束时是一个 CIImage *。这让我很困惑,因为它应该是 UIImage *(见图)。Screenshot during debug
让我担心的另一件事是,我注意到缓冲区大小明显小于第二遍时的大小。这让我相信图像没有被保存。同样在第二遍期间,调试器说 *imge 为空。 (见截图)Debugging screenshot during second pass
【问题讨论】:
将图像转换回CGImage
并从中创建UIImage
【参考方案1】:
并不是 mainImage.image 没有被正确保存,而是 UIImageView
——就像任何与 CoreGraphics 相关的东西——使用了它的 UIImage
的 CGImage
。在documentation for which我们看到
如果 UIImage 对象是使用 CIImage 对象初始化的,则该属性的值为 NULL。
所以你在这里要做的是制作一个CGImage
-backed UIImage,然后摆脱所有CoreImage数据分配;将self.imageView.image
分配给类似的东西
- (UIImage *)imageFromCIImage:(CIImage *)ciImage
CIContext *ciContext = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [ciContext createCGImage:ciImage fromRect:[ciImage extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return image;
【讨论】:
不要在主线程中进行这种转换,这会耗费大量时间。以上是关于Objective c 在转换为 UIImage 时丢失了 CIImage 内存的主要内容,如果未能解决你的问题,请参考以下文章
Objective C - 将 UIImage 保存为 BMP 文件