Как использовать CIColorMatrix в iOS5?

Я пытаюсь выяснить, как изменить цвет/оттенок 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);

}

Какой код входит в словарь для этого фильтра?


person Alex Stone    schedule 27.02.2012    source источник


Ответы (2)


Месяц спустя ...

Это пример установки 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, если вы получаете там nil, убедитесь, что вы передаете правильный UIImage/CGImage или путь.

В 2 создайте фильтр, вы это знаете :)

В 3 установите параметры фильтра по умолчанию, руководство по программированию CoreImage предлагает нам сделать это, хотя (я не экспериментировал с какими-либо странными/плохими вещами, если их избегать.)

В 4 установите входной ciimage

С 5 по 8 устанавливаем параметры. Например, я создал красный вектор {1,1,1,0}, чтобы изображение выглядело красноватым. 6, 7 и 8 и здесь не нужны, так как их значения такие же, как и по умолчанию (помните, мы назвали -setDefaults?), но для образовательных целей, я думаю, они подходят :)

В 9 задайте выходное изображение, хотя оно еще не нарисовано.

Наконец, в 10 вы указываете CoreImage отрисовывать выходное изображение в CGImage, и мы помещаем этот CGImage в UIImage и внутри UIImageView.

Вот результат (я использовал то же изображение, что и этот учебник):

Красноватый

Надеюсь, поможет.

person nacho4d    schedule 24.03.2012
comment
Отличный отличный ответ. Просто примечание с примечанием №1. Иногда ciimage равен нулю из-за типа изображения. Поэтому иногда необходимо создать cgiimage, а затем из него ciimage. - person Aggressor; 23.12.2014
comment
@Aggressor Не могли бы вы привести пример типа изображения, который возвращает nil для ciimage? Я хотел бы отредактировать ответ, касающийся этого :) - person nacho4d; 25.12.2014
comment
Вот статья, объясняющая 3. medium.com/@ranleung/ uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94 . Если вы работаете с известным типом (скажем, .jpg) и всегда знаете, что у вас будет CIImage, то вы в безопасности. Но если ваше приложение принимает несколько типов файловых форматов, вы должны иметь меры безопасности, когда CIImage равен нулю, и вместо этого брать CGImage и преобразовывать его в CIImage (что может означать перерисовку его в контексте и захват UIImage->CIImage из этого ) - person Aggressor; 25.12.2014

Просто пример 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")

Обратите внимание, что по умолчанию 1,0,0 0,1,0 и 0,0,1 соответственно для RGB, и если вы хотите сделать его более красным, вы должны установить inputRVector на 1,1,1 и оставить остальные такими же (поскольку это умножает синие и зеленые компоненты на красные значения)

person Aggressor    schedule 23.12.2014