将过滤器应用于CIImage时获取EXC_BAD_ACCESS [核心图像]

时间:2017-05-11 07:38:29

标签: ios objective-c filter uicollectionview core-image

我正在开发Imagebase应用程序。我想在图像上应用一些过滤器。为此,我使用了[核心图像]。

我在数组中存储了一些FilterName,并将滤镜效果显示为预览我正在使用UICollection视图。当用户点击预览图像时,过滤器将应用于主Imageview。但是当我点击预览单元格时,则在主要Imageview上成功应用了过滤器。但之后,当我拖动集合视图单元格以应用下一个预览时,我在过滤方法上遇到BAD_ACCESS错误。

-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername

以下是我应用过滤器的代码: -

使用Filter数组和RegisterCollectionview单元格进行初始设置: -

-(void)setUpDefaultUI{
    [self HideControlsAndSetupUI];

    arrFilter = @[ @"Original",
                   @"CILinearToSRGBToneCurve",
                   @"CIPhotoEffectChrome",
                   @"CIPhotoEffectFade",
                   @"CIPhotoEffectInstant",
                   @"CIPhotoEffectMono",
                   @"CIPhotoEffectNoir",
                   @"CIPhotoEffectProcess",
                   @"CIPhotoEffectTonal",
                   @"CIPhotoEffectTransfer",
                   @"CISRGBToneCurveToLinear",
                   @"CIVignette",
                   // @"CIVignetteEffect",
                   @"CISepiaTone",
                   ];

    [self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
    [self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
    _imgEdit.image=_stillImage; // To apply filter on this Image 
    _OriginalImage=_stillImage; // Original image if user declined to use filter

}

CollectionView数据源: -

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {


    NSLog(@"filterAvailable");

    ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];

    if (cell == nil) {
        NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
        cell = [xib objectAtIndex:0];
        [cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
    }
      if (indexPath.item==0) {
        cell.imgVw.image = _OriginalImage; //Original Image on 0 index
    }else{
         UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Apply filter on this method
        cell.imgVw.image=img;
}
    return cell;
}

Collectionview代表: -

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    ActivityCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
    if (cell == nil) {
        NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
        cell = [xib objectAtIndex:0];
    }
 if (indexPath.item==0) {
        _imgEdit.image=_OriginalImage; // Set original image in main Imageview
    }else{
        UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]];
        _imgEdit.image = img;  // Apply filter on Main Imageview 
    }
    }

从此方法过滤应用: -

-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
    UIImageOrientation originalOrientation = picture.imageOrientation;
    CGFloat originalScale = picture.scale;
    CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
    CIContext *context = [CIContext contextWithOptions:nil];
     CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
    CIImage *outputImage = [filter outputImage];
    CGImageRef cgimg =
    [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];

    //CGImageRelease(CGImageRef) method.
    CGImageRelease(cgimg);
    return newImg;

}

错误图片: -   - BAD_ACCESS enter image description here

enter image description here

2 个答案:

答案 0 :(得分:0)

  1. 您确定picture是有效的UIImage对象吗?在applyFilter:withFilterName:的开头放置一个断点,并使用Xcode的快速查看来确认它是你认为的。
  2. 同时检查Filtername是否为有效字符串。
  3. 如果这些都是正确的,这看起来很可疑:

    CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];

    钥匙和钥匙这里的值是一个未终止的列表。尝试删除第一个nil后的所有内容:

    CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil];

    另请注意CIVignette& CISepiaTone有其他输入参数(请参阅Apple的Core Image Filter Reference

答案 1 :(得分:0)

最后,我遇到了问题。实际上问题是,我在这两种方法中对静止图像应用滤镜。

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {

 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

因此,最终解决方案在两种方法中使用不同的图像。

以下是代码: - //初始设置      - (无效)setUpDefaultUI {         [self HideControlsAndSetupUI];

    arrFilter = @[ @"Original",
                   @"CILinearToSRGBToneCurve",
                   @"CIPhotoEffectChrome",
                   @"CIPhotoEffectFade",
                   @"CIPhotoEffectInstant",
                   @"CIPhotoEffectMono",
                   @"CIPhotoEffectNoir",
                   @"CIPhotoEffectProcess",
                   @"CIPhotoEffectTonal",
                   @"CIPhotoEffectTransfer",
                   @"CISRGBToneCurveToLinear",
                   @"CIVignette",
                   // @"CIVignetteEffect",
                   @"CISepiaTone",
                   ];

    [self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
    [self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
    _imgEdit.image=_stillImage;
    _OriginalImage=_stillImage;
    temp=_OriginalImage;
}

//数据源方法使用过滤器

在集合视图中显示图像
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {


    NSLog(@"filterAvailable");

    ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];



    if (cell == nil) {
        NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
        cell = [xib objectAtIndex:0];
        //[cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
        cell.imgVw.clipsToBounds = YES;

        cell.imgVw.layer.cornerRadius = 5;

    }
  if (indexPath.item==0) {
        cell.imgVw.image = _OriginalImage; //Set original image of 1st index

    }else{
        UIImage *img=[self applyFilter:temp withFilterName:[arrFilter objectAtIndex:indexPath.row]];    // Set temp image in place of stilimage
        cell.imgVw.image=img;

        }
 return cell;
}

//在主Imageview上应用过滤器。

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    if (_EnumPhotos==defaultPhotos) {

    if (indexPath.item==0) {
        _imgEdit.image=_OriginalImage; //If user click on 1st index then original filter applied on main image
    }else{

         UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Use still image here .
        _imgEdit.image = img; // Apply image on main image view
    }
    }
}

//应用过滤器方法

-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
    UIImageOrientation originalOrientation = picture.imageOrientation;
    CGFloat originalScale = picture.scale;
    CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
    CIContext *context = [CIContext contextWithOptions:nil];
     CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
    CIImage *outputImage = [filter outputImage];
    CGImageRef cgimg =
    [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];

    //CGImageRelease(CGImageRef) method.
    CGImageRelease(cgimg);
    return newImg;

}