简体   繁体   English

平滑地应用渐变到UIImage

[英]Applying Gradient to UIImage Smoothly

I am trying to apply gradient to UIImage using CoreGraphic; 我正在尝试使用CoreGraphic将渐变应用于UIImage; however, the result I got is not very nice. 但是,我得到的结果并不是很好。 I want to create a black to transparent gradient at the bottom of the image to create a contrast for me to place some text. 我想在图像的底部创建一个黑色到透明的渐变,为我创建一个对比,让我放置一些文本。 However, the gradient I was able doesn't blend well with the image; 然而,我能够的渐变与图像不能很好地融合; you can clearly see the separation in the center . 你可以清楚地看到中心的分离 The result I am looking for is like this application: http://capptivate.co/2014/02/17/yummly-3/ How should I apply the gradient to achieve this? 我正在寻找的结果就像这个应用程序: http//capptivate.co/2014/02/17/yummly-3/我应该如何应用渐变来实现这一目标? ( I have to apply this to large quantity of images ). (我必须将其应用于大量图像)。

My Result: 我的结果:

在此输入图像描述

Here is my code: 这是我的代码:

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(red: 0, green: 0, blue: 0, alpha: 0.5).CGColor
    let top = UIColor(red: 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 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(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor
    let top = UIColor(red: 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!
}

I tried this out in a Swift playground, I couldn't replicate the exact issue you are describing, however here are some suggestions that you could try. 我在Swift游乐场试过这个,我无法复制你所描述的确切问题,但是这里有一些你可以尝试的建议。

You could change the way you set up the stops in the gradient, I think it would make more sense to instead of shifting the gradient using the stops, shift the start point, ie instead of starting from the top edge, start from the vertical center, something like this 你可以改变在渐变中设置光圈的方式,我认为使用光圈而不是移动渐变更有意义,移动起点,即不是从顶边开始,而是从垂直中心开始,像这样的东西

UIGraphicsBeginImageContext(image.size)
var context = UIGraphicsGetCurrentContext()

image.drawAtPoint(CGPointMake(0, 0))

let colorSpace = CGColorSpaceCreateDeviceRGB()
let locations:[CGFloat] = [0.0, 1.0]
let bottom = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).CGColor
let top = UIColor(red: 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()

Notice locations is now 0 and 1, while the startPoint y coordinate has shifted downwards. 通知位置现在为0和1,而startPoint y坐标向下移动。

Alternatively, look at passing kCGGradientDrawsBeforeStartLocation as an option to CGContextDrawLinearGradient , as that could also make a difference. 或者,看看将kCGGradientDrawsBeforeStartLocation作为CGContextDrawLinearGradient的选项传递,因为这也可能有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM