2012-02-27 13 views
6

Estoy tratando de descubrir cómo cambiar el color/tono de un UIImage. Descubrí que iOS5 tiene muchos filtros de imagen, pero me cuesta encontrar documentación sobre el uso correcto del filtro CIColorMatrix.¿Cómo se usa CIColorMatrix en iOS5?

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

} 

¿Qué código va en el diccionario para este filtro?

Respuesta

20

Un mes más tarde ...

Este es un ejemplo de CIColorMatrix ajustar todos sus parámetros :)

-(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]; 
} 

Así que esto es lo que hace la muestra:

En 1 creamos el ciimage, si obtienes nada allí, asegúrate de pasar el UIImage/CGImage o la ruta correcta.

En 2 crear el filtro, lo saben :)

En 3 establece los parámetros de filtro a sus valores predeterminados, CoreImage guía de programación sugiere que deberíamos hacer esto aunque (no he experimentado ningún cosas extrañas/malo si evitarse.)

En 4 Ajuste la entrada ciimage

De 5 través 8 establecemos los parámetros. Por ejemplo, hice el vector rojo {1,1,1,0} para que la imagen se vea rojiza. 6, 7 y 8 y no es necesario aquí, ya que sus valores son los mismos que los valores por defecto (recuerde que llamamos -setDefaults?), Pero para los propósitos educativos supongo que están bien :)

En 9 establece la imagen de salida, aunque no es dibujado aún.

Finalmente, en 10 le dices a CoreImage que dibuje la imagen de salida en una CGImage, y ponemos esa CGImage en un UIImage y dentro de un UIImageView.

Este es el resultado (he utilizado la misma imagen que this tutorial):

Reddish

espero que ayude.

+0

Excelente respuesta. Solo una nota al margen con la nota n. ° 1. A veces, la imagen es nula debido al tipo de imagen. Entonces, a veces es necesario crear una imagen y luego una imagen de eso. – Aggressor

+0

@Aggressor ¿Podría dar un ejemplo de un tipo de imagen que devolverá nil para ciimage? Me gustaría editar la respuesta al respecto :) – nacho4d

+0

Aquí hay un artículo que explica el 3. https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94.Si trabajas con un tipo conocido (digamos un .jpg) y siempre sabes que tendrás el CIImage, entonces estás a salvo. Pero si su aplicación toma varios tipos de formatos de archivo, entonces debe tener precauciones para cuando el CIImage sea nulo y en su lugar tomar el CGImage y convertirlo a CIImage (lo que puede significar volver a dibujarlo en el contexto y tomar el UIImage-> CIImage de ese) – Aggressor

5

Sólo un ejemplo Swift con una cadena a añadir a la respuesta anterior por 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") 

Obsérvese que los valores predeterminados son 1,0,0 0,1,0 y 0,0,1, respectivamente, para RGB y si quieres volverlo más rojo, establecerás inputRVector en 1,1,1 y dejarás los otros iguales (ya que esto multiplica los componentes azul y verde por valores rojos)