iphone uiimage core-graphics drawrect tint

iphone - ¿Cómo puedo teñir un UIImage con gradiente?



core-graphics drawrect (4)

EDITAR: Aquí hay una versión que admite pantallas sin retina y retina

El método puede ser usado como una categoría para UIImage

+ (UIImage *)imageWithGradient:(UIImage *)img startColor:(UIColor *)color1 endColor:(UIColor *)color2 { UIGraphicsBeginImageContextWithOptions(img.size, NO, img.scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, img.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextSetBlendMode(context, kCGBlendModeNormal); CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height); //CGContextDrawImage(context, rect, img.CGImage); // Create gradient NSArray *colors = [NSArray arrayWithObjects:(id)color2.CGColor, (id)color1.CGColor, nil]; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL); // Apply gradient CGContextClipToMask(context, rect, img.CGImage); CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, img.size.height), 0); UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGGradientRelease(gradient); CGColorSpaceRelease(space); return gradientImage; }

Edición: cambio añadido por sobri

Busqué por todas partes pero no encontré la solución. Tengo la imagen 1. ¿Cómo puedo tintarlos con un degradado para obtener las imágenes 2 y 3? Aquí están esas imágenes:

Los tintes que les apliqué a través de Photoshop son gradientes lineales simples de 2 colores.

Y mi pregunta es: ¿cómo puedo lograr este efecto programáticamente?

Solución: jrtc27 me dio ejemplo casi de trabajo. Lo arreglé (para ARC) y lo hice reutilizable (usando la categoría de UIImage). Aquí es:

- (UIImage *)tintedWithLinearGradientColors:(NSArray *)colorsArr { CGFloat scale = self.scale; UIGraphicsBeginImageContext(CGSizeMake(self.size.width * scale, self.size.height * scale)); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, self.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextSetBlendMode(context, kCGBlendModeNormal); CGRect rect = CGRectMake(0, 0, self.size.width * scale, self.size.height * scale); CGContextDrawImage(context, rect, self.CGImage); // Create gradient UIColor *colorOne = [colorsArr objectAtIndex:1]; // top color UIColor *colorTwo = [colorsArr objectAtIndex:0]; // bottom color NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, (id)colorTwo.CGColor, nil]; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL); // Apply gradient CGContextClipToMask(context, rect, self.CGImage); CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0,self.size.height * scale), 0); UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return gradientImage; }


Versión Swift (como extensión de UIImage, usando la respuesta de Remy):

import UIKit extension UIImage { func tintedWithLinearGradientColors(colorsArr: [CGColor]) -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale); guard let context = UIGraphicsGetCurrentContext() else { return UIImage() } context.translateBy(x: 0, y: self.size.height) context.scaleBy(x: 1, y: -1) context.setBlendMode(.normal) let rect = CGRect.init(x: 0, y: 0, width: size.width, height: size.height) // Create gradient let colors = colorsArr as CFArray let space = CGColorSpaceCreateDeviceRGB() let gradient = CGGradient(colorsSpace: space, colors: colors, locations: nil) // Apply gradient context.clip(to: rect, mask: self.cgImage!) context.drawLinearGradient(gradient!, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: self.size.height), options: .drawsAfterEndLocation) let gradientImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return gradientImage! } }


Versión Swift 4.

extension UIImage { func tintedWithLinearGradientColors(colorsArr: [CGColor!]) -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale); let context = UIGraphicsGetCurrentContext() CGContextTranslateCTM(context, 0, self.size.height) CGContextScaleCTM(context, 1.0, -1.0) CGContextSetBlendMode(context, kCGBlendModeNormal) let rect = CGRectMake(0, 0, self.size.width, self.size.height) // Create gradient let colors = colorsArr as CFArray let space = CGColorSpaceCreateDeviceRGB() let gradient = CGGradientCreateWithColors(space, colors, nil) // Apply gradient CGContextClipToMask(context, rect, self.CGImage) CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0, self.size.height), 0) let gradientImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return gradientImage } }


Creo que lo siguiente debería funcionar - ¡comenta si no lo hace!

// Load image UIImage *image = [UIImage imageNamed:@"MyCoolImage.png"]; CGFloat scale = image.scale; UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scale, image.size.height * scale)); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, image.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextSetBlendMode(context, kCGBlendModeMultiply); CGRect rect = CGRectMake(0, 0, image.size.width * scale, image.size.height * scale); CGContextDrawImage(context, rect, image.CGImage); // Create gradient UIColor *colorOne = ....; UIColor *colorTwo = ....; NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, (id)colorTwo.CGColor, nil]; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, NULL); // Apply gradient CGContextClipToMask(context, rect, image.CGImage); CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0,image.size.height * scale), 0); CGGradientRelease(gradient); UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

Crédito a CoffeeShopped por la idea básica.