在iOS5中如何使用CIColorMatrix?

7

我想知道如何改变UIImage的颜色/色调。我找到了iOS5中有很多图像过滤器,但是我很难找到有关正确使用“CIColorMatrix”过滤器的文档。

-(void)doCIColorMatrixFilter
{

    //does not work, returns nil image
    CIImage* inputImage = [CIImage imageWithCGImage:[[UIImage imageNamed:@"button.jpg"]CGImage]];

    CIFilter *myFilter;
    NSDictionary *myFilterAttributes;
    myFilter = [CIFilter filterWithName:@"CIColorMatrix"];
    [myFilter setDefaults];

    myFilterAttributes = [myFilter attributes];

    [myFilterAttributes setValue:inputImage forKey:@"inputImage"];
    //How to set up attributes?

    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *ciimage = [myFilter outputImage];
    CGImageRef cgimg = [context createCGImage:ciimage fromRect:[ciimage extent]];
    UIImage *uimage = [UIImage imageWithCGImage:cgimg scale:1.0f orientation:UIImageOrientationUp];
    [imageView setImage:uimage];
    CGImageRelease(cgimg);

}

这个过滤器需要的代码应该放在字典中哪里?
2个回答

23

一个月后...

这是使用CIColorMatrix设置所有参数的示例 :)

-(void)doCIColorMatrixFilter
{
    // Make the input image recipe
    CIImage *inputImage = [CIImage imageWithCGImage:[UIImage imageNamed:@"facedetectionpic.jpg"].CGImage]; // 1

    // Make the filter
    CIFilter *colorMatrixFilter = [CIFilter filterWithName:@"CIColorMatrix"]; // 2
    [colorMatrixFilter setDefaults]; // 3
    [colorMatrixFilter setValue:inputImage forKey:kCIInputImageKey]; // 4
    [colorMatrixFilter setValue:[CIVector vectorWithX:1 Y:1 Z:1 W:0] forKey:@"inputRVector"]; // 5
    [colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:1 Z:0 W:0] forKey:@"inputGVector"]; // 6
    [colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:0 Z:1 W:0] forKey:@"inputBVector"]; // 7
    [colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:1] forKey:@"inputAVector"]; // 8

    // Get the output image recipe
    CIImage *outputImage = [colorMatrixFilter outputImage];  // 9

    // Create the context and instruct CoreImage to draw the output image recipe into a CGImage
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]]; // 10

    // Draw the image in screen
    UIImageView *imageView2 = [[UIImageView alloc] initWithImage:[UIImage imageWithCGImage:cgimg]];
    CGRect f = imageView2.frame;
    f.origin.y = CGRectGetMaxY(imageView.frame);
    imageView2.frame = f;

    [self.view addSubview:imageView2];
}

这就是示例代码的作用:

1 中,我们创建了一个 CIImage,如果你在这里得到了 null 值,那么请确保传递正确的 UIImage/CGImage 或路径。

2 中创建了滤镜, 你应该知道这一点 :)

3 中将滤镜参数设置为默认值。CoreImage 编程指南建议我们这样做,尽管(如果避免)我没有尝试过任何奇怪/坏的事情。

4 中设置输入 CIImage。

58 我们设置了各种参数。例如,我将红色向量设置为 {1,1,1,0},所以图像看起来有点 678 在这里不是必要的,因为它们的值与默认值相同(记得我们调用了 -setDefaults 吗?),但出于教育目的,我想它们还是可以的 :)。

9 中设置输出图像,虽然还未绘制。

最后在 10 中,告诉 CoreImage 将输出图像绘制到 CGImage 中,然后我们将该 CGImage 放入一个 UIImage 中并将其放入 UIImageView 中。

这是结果(我使用与 教程相同的图像):

Reddish

希望对你有所帮助。


非常好的答案。只是关于第一条注释的一个侧面说明。有时候ciimage是nil,因为图像类型的原因。因此有时需要从cgimage创建ciimage。 - Aggressor
@Aggressor,您能否举个例子,说明哪种图像类型会使ciimage返回nil?我想编辑答案来解决这个问题 :) - nacho4d
这是一篇解释三者区别的文章:https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94。如果您正在使用已知类型(例如.jpg)并且始终知道将使用CIImage,则是安全的。但是,如果您的应用程序接受多种文件格式,则应当有防护措施以处理 CIImage 为 nil 的情况,并且改为获取 CGImage 并将其转换为 CIImage(可能需要在上下文中重新绘制,然后从中获取 UIImage->CIImage)。 - Aggressor

5

这是一个使用链式语法的Swift示例,添加到nacho4d的答案中。

var output = CIFilter(name: "CIColorControls")
output.setValue(ciImage, forKey: kCIInputImageKey)
output.setValue(1.8, forKey: "inputSaturation")
output.setValue(0.01, forKey: "inputBrightness")

filter = CIFilter(name: "CIColorMatrix")
filter.setDefaults()
filter.setValue(output.outputImage, forKey: kCIInputImageKey)
filter.setValue(CIVector(x: 1, y: 0.1, z: 0.1, w: 0), forKey: "inputRVector")
filter.setValue(CIVector(x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
filter.setValue(CIVector(x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")

注意,RGB 的默认值分别为 1,0,0 0,1,0 和 0,0,1。如果你想让它更红,你可以将 inputRVector 设置为 1,1,1,并保持其他不变(因为这会将蓝色和绿色分量乘以红色值)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接