2012-02-27 13 views
6

Sto cercando di scoprire come modificare il colore/tonalità di un UIImage. Ho scoperto che iOS5 ha molti filtri di immagine, ma ho difficoltà a trovare la documentazione sull'uso corretto del filtro CIColorMatrix.Come utilizzare CIColorMatrix in 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); 

} 

Quale codice va nel dizionario per questo filtro?

risposta

20

Un mese dopo ...

Questo è un esempio di CIColorMatrix impostando tutti i suoi parametri :)

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

Quindi questo è ciò che il campione non:

In 1 creiamo il ciimage, se stai ottenendo nil lì, assicurati di passare il giusto UIImage/CGImage o path.

Nel 2 creare il filtro, sai che questo :)

In 3 impostare i parametri del filtro ai suoi valori predefiniti, guida CoreImage programmazione suggerisce che dovremmo fare questo anche se (non ho sperimentato alcun strane cose/male se evitato.)

In 4 impostare l'ingresso ciimage

Da 5 attraverso 8 abbiamo impostato i parametri. Ad esempio ho realizzato il vettore rosso {1,1,1,0} in modo che l'immagine sia rossiccia. 6, 7 e 8 e non sarebbe necessaria perché i loro valori sono gli stessi valori predefiniti (ricordate abbiamo chiamato -setDefaults?), Ma per scopi didattici credo che stanno bene :)

Nel 9 impostare l'immagine di output, anche se non è disegnato ancora.

Infine in 10 si dice a CoreImage di disegnare l'immagine di output in un CGImage, e abbiamo messo quel CGImage in un UIImage e in un UIImageView.

questo è il risultato (io ho usato la stessa immagine this tutorial):

Reddish

Speranza che aiuta.

+0

Ottima risposta. Solo una nota a margine con la nota n. A volte il ciimage è nullo a causa del tipo di immagine. Quindi a volte è necessario creare cgimage e quindi una immagine da ciò. – Aggressor

+0

@Aggressor Puoi fornire un esempio di un tipo di immagine che restituirà zero per ciimage? Vorrei modificare la risposta indirizzandola :) – nacho4d

+0

Ecco un articolo che spiega il 3. https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94.Se stai lavorando con un tipo noto (ad esempio un .jpg) e sai sempre che avrai il CIImage allora sei al sicuro. Ma se la tua app prende più tipi di formati di file allora dovresti avere delle protezioni per quando CIImage è nullo e invece prendi il CGImage e convertilo in CIImage (che può significare ridisegnarlo nel contesto e afferrare l'UIImage-> CIImage da quel) – Aggressor

5

Solo un esempio Swift con una catena da aggiungere alla risposta di cui sopra da 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") 

Si noti che i valori di default sono 1,0,0 0,1,0 e 0,0,1 rispettivamente per RGB e se vuoi renderlo più rosso, devi impostare inputRVector su 1,1,1 e lasciare gli altri uguali (poiché moltiplica le componenti blu e verde con valori rossi)