如何将CIFilter应用于UIImage?

时间:2014-05-26 07:42:28

标签: ios objective-c uiimage core-image cifilter

当我尝试将过滤器应用于用户选择的UIImage时,我的应用程序崩溃了(它在没有应用过滤器的情况下工作正常)。我添加了“CoreImage”框架并将其导入到我的项目中,因此我可以为用户选择的图像创建过滤器。

我尝试通过为UIImage创建类别(基于Apple's documentation,然后在用户选择的UIImage上调用相应的方法来应用过滤器。以下是我的类别标题和正文的代码;我做错了什么?(请注意,“randColor”是一个生成随机颜色的类UIColor类方法)

#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
#import "UIColor+CustomColorCategory.h"

@interface UIImage (MonoChromeFilter)

- (UIImage *) applyMonoChromeWithRandColor;

@end

#import "UIImage+MonoChromeFilter.h"

@implementation UIImage (MonoChromeFilter)

- (UIImage *)applyMonoChromeWithRandColor
{
    CIContext *context = [CIContext contextWithOptions:nil];

    CIImage *ciImage = [[CIImage alloc] initWithImage:self];

    CIFilter *filter = [CIFilter filterWithName:@"CIColorMonochrome"];

    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:[UIColor randColor] forKey:kCIAttributeTypeColor];

    CIImage *result = [filter valueForKey:kCIOutputImageKey];

    CGRect extent = [result extent];

    CGImageRef cgImage = [context createCGImage:result fromRect:extent];

    UIImage *filteredImage = [[UIImage alloc] initWithCGImage:cgImage];

    return filteredImage;
}

@end

以下是viewController中调用此类别的方法:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [picker dismissViewControllerAnimated:YES completion:^{
        UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
        editedImage = [editedImage applyMonoChromeWithRandColor];

        self.blogImageOutlet.image = editedImage;
        self.blogImageOutlet.layer.cornerRadius = self.blogImageOutlet.frame.size.width / 2.0;
        [self.blogImageOutlet setClipsToBounds:YES];

        [self saveImageToLibrary:editedImage];

    }];
}

2 个答案:

答案 0 :(得分:7)

我明白了!在调试并使用其他一些项目作为参考之后,我意识到我遇到了两个问题。首先,我试图使用UIColor进行CIColor,这不是直接可行的。我首先必须将UIColor转换为CIColor以便能够应用它。接下来,我没有使用正确的字符串作为CIFilter值键。修改后的代码如下(现在可以使用!)

#import "UIImage+MonoChromeFilter.h"

@implementation UIImage (MonoChromeFilter)

+ (UIImage *) applyMonoChromeWithRandColor: (UIImage *)uIImage
{

    //  Convert UIColor to CIColor
    CGColorRef colorRef = [UIColor randColor].CGColor;
    NSString *colorString = [CIColor colorWithCGColor:colorRef].stringRepresentation;
    CIColor *coreColor = [CIColor colorWithString:colorString];

    CIContext *context = [CIContext contextWithOptions:nil];

    //  Convert UIImage to CIImage
    CIImage *ciImage = [[CIImage alloc] initWithImage:uIImage];

    //  Set values for CIColorMonochrome Filter
    CIFilter *filter = [CIFilter filterWithName:@"CIColorMonochrome"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:@1.0 forKey:@"inputIntensity"];
    [filter setValue:coreColor forKey:@"inputColor"];

    CIImage *result = [filter valueForKey:kCIOutputImageKey];

    CGRect extent = [result extent];

    CGImageRef cgImage = [context createCGImage:result fromRect:extent];

    UIImage *filteredImage = [[UIImage alloc] initWithCGImage:cgImage];

    return filteredImage;
}

@end

答案 1 :(得分:0)

试试吧,这对我来说就像冠军一样,

我们为单张图片应用了不同的 CIFilter

以下是实施代码,

           //CISepiaTone Effect,

            CIContext *imageContext = [CIContext contextWithOptions:nil];
            CIImage *image = [[CIImage alloc]initWithImage:inputimage];
            CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"
                                          keysAndValues: kCIInputImageKey, image,
                                @"inputIntensity", @1, nil];

            CIImage *result = [filter valueForKey: @"outputImage"];
            CGImageRef cgImageRef = [imageContext createCGImage:result fromRect:[result extent]];
            UIImage *targetImage = [UIImage imageWithCGImage:cgImageRef];
            detailsVc.filterImage=targetImage;
            [self.navigationController pushViewController:detailsVc animated:YES];



            //CIVignette Effect 

            CIContext *imageContext = [CIContext contextWithOptions:nil];
            CIImage *image = [[CIImage alloc] initWithImage:inputimage];

            CIFilter *vignette = [CIFilter filterWithName:@"CIVignette"];
            [vignette setDefaults];
            [vignette setValue: image forKey: @"inputImage"];
            [vignette setValue: [NSNumber numberWithFloat: 1.0] forKey: @"inputIntensity"];
            [vignette setValue: [NSNumber numberWithFloat: 10.00 ] forKey: @"inputRadius"];

            CIImage *result = [vignette valueForKey: @"outputImage"];
            CGImageRef cgImageRef = [imageContext createCGImage:result fromRect:[result extent]];
            UIImage *targetImage = [UIImage imageWithCGImage:cgImageRef];
            detailsVc.filterImage=targetImage;
            [self.navigationController pushViewController:detailsVc animated:YES];

有关详细实现,您可以参考此GitHub项目文件ImageFilter

希望如此,这对某些人有帮助。