¿Cómo cambiar el tono de UIImage programáticamente?

Soy muy nuevo en el procesamiento de imágenes. Tengo que implementar el efecto de tono en mi proyecto de aplicación de iPhone. Por lo tanto, necesito cambiar el tono de UIImage . Proporcione cualquier código de muestra o enlace de tutorial para esto.

Gracias por adelantado

En primer lugar, debe decidir si está haciendo una imagen con un matiz fijo o rotando el tono existente . Ejemplos de ambos se muestran a continuación.

Cambios de tono

Tono fijo

La reparación del tono se puede hacer utilizando las herramientas de dibujo estándar; solo asegúrese de que el modo de fusión esté configurado en kCGBlendModeHue y dibuje con el tono apropiado. Esto se deriva de la solución de Nitish, aunque descubrí que hacer una saturation inferior a 1.0 tenía resultados inconsistentes. Este método permite variar el alfa, pero para la saturación verdadera que no sea del 100%, probablemente necesites una segunda ronda de sorteo.

 - (UIImage*) imageWithImage:(UIImage*) source fixedHue:(CGFloat) hue alpha:(CGFloat) alpha; // Note: the hue input ranges from 0.0 to 1.0, both red. Values outside this range will be clamped to 0.0 or 1.0. { // Find the image dimensions. CGSize imageSize = [source size]; CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height); // Create a context containing the image. UIGraphicsBeginImageContext(imageSize); CGContextRef context = UIGraphicsGetCurrentContext(); [source drawAtPoint:CGPointMake(0,0)]; // Draw the hue on top of the image. CGContextSetBlendMode(context, kCGBlendModeHue); [[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set]; UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent]; [imagePath fill]; // Retrieve the new image. UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } 

Tono girado

Para girar el tono, necesita filtros de Imagen de núcleo. El siguiente código convierte el UIImage a un CIImage, y luego convierte el resultado a UIImage para su visualización. Dependiendo de dónde provenga su imagen, es posible que pueda evitar uno o ambos de estos pasos.

Convenientemente, el primer ejemplo en la Guía de progtwigción de imágenes principales: el uso de filtros de imágenes principales usa el filtro CIHueAdjust.

 // #import  // Partially from https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/CoreImaging/ci_tasks/ci_tasks.html - (UIImage*) imageWithImage:(UIImage*) source rotatedByHue:(CGFloat) deltaHueRadians; { // Create a Core Image version of the image. CIImage *sourceCore = [CIImage imageWithCGImage:[source CGImage]]; // Apply a CIHueAdjust filter CIFilter *hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"]; [hueAdjust setDefaults]; [hueAdjust setValue: sourceCore forKey: @"inputImage"]; [hueAdjust setValue: [NSNumber numberWithFloat: deltaHueRadians] forKey: @"inputAngle"]; CIImage *resultCore = [hueAdjust valueForKey: @"outputImage"]; // Convert the filter output back into a UIImage. // This section from http://stackoverflow.com/a/7797578/1318452 CIContext *context = [CIContext contextWithOptions:nil]; CGImageRef resultRef = [context createCGImage:resultCore fromRect:[resultCore extent]]; UIImage *result = [UIImage imageWithCGImage:resultRef]; CGImageRelease(resultRef); return result; } 
 - (void) changeToHue:(float)hue saturation:(float)saturation { UIGraphicsBeginImageContext(self.bounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); UIView *hueBlend = [[UIView alloc] initWithFrame:self.bounds]; hueBlend.backgroundColor = [UIColor colorWithHue:hue saturation:saturation brightness:1 alpha:1]; CGContextDrawImage(context, self.bounds, self.image.CGImage); CGContextSetBlendMode(context, kCGBlendModeHue); [hueBlend.layer renderInContext:context]; self.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } 

Tomando el excelente ejemplo de tono fijo de Dondragmer como punto de partida. Esta es mi modificación para solucionar el problema de las áreas transparentes que se configuran con el mismo matiz.

 - (UIImage*) imageWithImage:(NSString *)name fixedHue:(CGFloat) hue alpha:(CGFloat) alpha; // Note: the hue input ranges from 0.0 to 1.0, both red. Values outside this range will be clamped to 0.0 or 1.0. { UIImage *source = [UIImage imageNamed:name]; // Find the image dimensions. CGSize imageSize = [source size]; CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height); // Create a context containing the image. UIGraphicsBeginImageContext(imageSize); CGContextRef context = UIGraphicsGetCurrentContext(); [source drawAtPoint:CGPointMake(0,0)]; // Setup a clip region using the image CGContextSaveGState(context); CGContextTranslateCTM(context, 0, source.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextClipToMask(context, imageExtent, source.CGImage); //[[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set]; CGContextFillRect(context, imageExtent); // Draw the hue on top of the image. CGContextDrawImage(context, imageExtent, source.CGImage); CGContextSetBlendMode(context, kCGBlendModeHue); [[UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:alpha] set]; UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent]; [imagePath fill]; CGContextRestoreGState(context); // remove clip region // Retrieve the new image. UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } 

Gracias a:

¿Cómo cambiar el tono de UIIMAGE que tiene un área transparente?

CGContextClipToMask UIImage Mask Invertir arriba y abajo

En el blog Swift de Apple, me encontré con este tutorial de la aplicación de filtrado de fotos: https://developer.apple.com/swift/blog/?id=16

El siguiente es el código de muestra editado para crear un método contenido que devuelve un UIImage con un matiz aleatorio aplicado.

 func applyHue(source: UIImage) -> UIImage { // Create a place to render the filtered image let context = CIContext(options: nil) // Create an image to filter let inputImage = CIImage(image: source) // Create a random color to pass to a filter let randomColor = [kCIInputAngleKey: (Double(arc4random_uniform(314)) / 100)] // Apply a filter to the image let filteredImage = inputImage!.imageByApplyingFilter("CIHueAdjust", withInputParameters: randomColor) // Render the filtered image let renderedImage = context.createCGImage(filteredImage, fromRect: filteredImage.extent) // Return a UIImage return UIImage(CGImage: renderedImage) } 

Versión rápida del código rotativo de Dondragmer anterior

 // Convert the filter output back into a UIImage. // This section from http://stackoverflow.com/a/7797578/1318452 func imageWithImage(source: UIImage, rotatedByHue: CGFloat) -> UIImage { // Create a Core Image version of the image. let sourceCore = CIImage(CGImage: source.CGImage) // Apply a CIHueAdjust filter let hueAdjust = CIFilter(name: "CIHueAdjust") hueAdjust.setDefaults() hueAdjust.setValue(sourceCore, forKey: "inputImage") hueAdjust.setValue(CGFloat(rotatedByHue), forKey: "inputAngle") let resultCore = hueAdjust.valueForKey("outputImage") as CIImage! let context = CIContext(options: nil) let resultRef = context.createCGImage(resultCore, fromRect: resultCore!.extent()) let result = UIImage(CGImage: resultRef) return result! }