Objective c 转换为 UIImage 时丢失 CIImage 内存

Objective c lost CIImage memory when converting to UIImage

我有以下代码:

- (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

并不是 mainImage.image 没有被正确保存,而是 UIImageView - 与 CoreGraphics 相关的任何东西 - 使用其 UIImageCGImage.在documentation for which我们看到

If the UIImage object was initialized using a CIImage object, the value of the property is NULL.

所以你在这里要做的是制作一个 CGImage 支持的 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;
}