Aplicación de gradiente a UIImage suavemente

Estoy intentando aplicar gradient a UIImage usando CoreGraphic; Sin embargo, el resultado que obtuve no es muy agradable. Quiero crear un degradado negro a transparente en la parte inferior de la image para crear un contraste para que coloque text. Sin embargo, el gradiente que pude no se combina bien con la image; Puedes ver claramente la separación en el centro . El resultado que estoy buscando es como esta aplicación: http://capptivate.co/2014/02/17/yummly-3/ ¿Cómo debo aplicar el gradiente para lograr esto? (Tengo que aplicar esto a una gran cantidad de imágenes).

Mi resultado:

introduzca la descripción de la imagen aquí

Aquí está mi código:

func imageWithGradient(img:UIImage!) -> UIImage{ UIGraphicsBeginImageContext(img.size) var context = UIGraphicsGetCurrentContext() img.drawAtPoint(CGPointMake(0, 0)) let colorSpace = CGColorSpaceCreateDeviceRGB() let locations:[CGFloat] = [0.50, 1.0] //1 = opaque //0 = transparent let bottom = UIColor(networking: 0, green: 0, blue: 0, alpha: 0.5).CGColor let top = UIColor(networking: 0, green: 0, blue: 0, alpha: 0).CGColor let gradient = CGGradientCreateWithColors(colorSpace, [top, bottom], locations) let startPoint = CGPointMake(img.size.width/2, 0) let endPoint = CGPointMake(img.size.width/2, img.size.height) CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } 

SWIFT 3

 func imageWithGradient(img:UIImage!) -> UIImage { UIGraphicsBeginImageContext(img.size) let context = UIGraphicsGetCurrentContext() img.draw(at: CGPoint(x: 0, y: 0)) let colorSpace = CGColorSpaceCreateDeviceRGB() let locations:[CGFloat] = [0.0, 1.0] let bottom = UIColor(networking: 0, green: 0, blue: 0, alpha: 0.5).cgColor let top = UIColor(networking: 0, green: 0, blue: 0, alpha: 0).cgColor let colors = [top, bottom] as CFArray let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: locations) let startPoint = CGPoint(x: img.size.width/2, y: 0) let endPoint = CGPoint(x: img.size.width/2, y: img.size.height) context!.drawLinearGradient(gradient!, start: startPoint, end: endPoint, options: CGGradientDrawingOptions(rawValue: UInt32(0))) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! } 

Probé esto en un parque infantil Swift, no pude replicar el problema exacto que estás describiendo, pero aquí hay algunas sugerencias que podrías probar.

Podría cambiar la forma en que configura las paradas en el gradiente, creo que tendría más sentido en lugar de cambiar el gradiente con las paradas, cambiar el punto inicial, es decir, en lugar de comenzar desde el borde superior, comenzar desde el centro vertical , algo como esto

 UIGraphicsBeginImageContext(image.size) var context = UIGraphicsGetCurrentContext() image.drawAtPoint(CGPointMake(0, 0)) let colorSpace = CGColorSpaceCreateDeviceRGB() let locations:[CGFloat] = [0.0, 1.0] let bottom = UIColor(networking: 0, green: 0, blue: 0, alpha: 0.5).CGColor let top = UIColor(networking: 0, green: 0, blue: 0, alpha: 0).CGColor let gradient = CGGradientCreateWithColors(colorSpace, [top, bottom], locations) let startPoint = CGPointMake(image.size.width / 2, image.size.height / 2) let endPoint = CGPointMake(image.size.width / 2, image.size.height) CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0) let finalImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() 

Las ubicaciones de avisos ahora son 0 y 1, mientras que la coorderada y startPoint ha desplazado hacia abajo.

kCGGradientDrawsBeforeStartLocation , mire pasar kCGGradientDrawsBeforeStartLocation como una opción a CGContextDrawLinearGradient , ya que eso también podría marcar la diferencia.