How to create UIImage with vertical gradient using “from-color” and “to-color”

后端 未结 9 641
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-04 00:09

How to create new image just with gradient colors, using \"from-color\" and \"to-color\"?

9条回答
  •  无人及你
    2021-01-04 00:50

    UPDATED TO Swift 3

    I wrote UIImage extension for Swift but you can also use it from Objective-C:

    import UIKit
    
    private let ChannelDivider: CGFloat = 255
    
    public class RGBA: NSObject {
        var red: CGFloat
        var green: CGFloat
        var blue: CGFloat
        var alpha: CGFloat
    
        init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
            self.red = red
            self.green = green
            self.blue = blue
            self.alpha = alpha
        }
    
        init(intRed: Int, green: Int, blue: Int, alpha: Int) {
            self.red = CGFloat(intRed)/ChannelDivider
            self.green = CGFloat(green)/ChannelDivider
            self.blue = CGFloat(blue)/ChannelDivider
            self.alpha = CGFloat(alpha)/ChannelDivider
        }
    }
    
    public class Grayscale: NSObject {
        var white: CGFloat
        var alpha: CGFloat
    
        init(white: CGFloat, alpha: CGFloat) {
            self.white = white
            self.alpha = alpha
        }
    }
    
    public class GradientPoint: NSObject {
        var location: CGFloat
        var color: C
    
        init(location: CGFloat, color: C) {
            self.location = location
            self.color = color
        }
    }
    
    extension UIImage {
    
        public class func image(withGradientPoints gradientPoints: [GradientPoint<[CGFloat]>], colorSpace: CGColorSpace, size: CGSize) -> UIImage? {
            UIGraphicsBeginImageContextWithOptions(size, false, 0);
            guard
                let context = UIGraphicsGetCurrentContext(),
                let gradient = CGGradient(colorSpace: colorSpace,
                                          colorComponents: gradientPoints.flatMap { $0.color },
                                          locations: gradientPoints.map { $0.location }, count: gradientPoints.count) else {
                                            return nil
            }
    
            context.drawLinearGradient(gradient, start: CGPoint.zero, end: CGPoint(x: 0, y: size.height), options: CGGradientDrawingOptions())
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return image
        }
    
        public class func image(withRGBAGradientPoints gradientPoints: [GradientPoint], size: CGSize) -> UIImage? {
            return image(withGradientPoints: gradientPoints.map {
                GradientPoint(location: $0.location, color: [$0.color.red, $0.color.green, $0.color.blue, $0.color.alpha])
            }, colorSpace: CGColorSpaceCreateDeviceRGB(), size: size)
        }
    
        public class func image(withRGBAGradientColors gradientColors: [CGFloat: RGBA], size: CGSize) -> UIImage? {
            return image(withRGBAGradientPoints: gradientColors.map {  GradientPoint(location: $0, color: $1)}, size: size)
        }
    
        public class func image(withGrayscaleGradientPoints gradientPoints: [GradientPoint], size: CGSize) -> UIImage? {
            return image(withGradientPoints: gradientPoints.map {
                GradientPoint(location: $0.location, color: [$0.color.white, $0.color.alpha]) },
                         colorSpace: CGColorSpaceCreateDeviceGray(), size: size)
        }
    
        public class func image(withGrayscaleGradientColors gradientColors: [CGFloat: Grayscale], size: CGSize) -> UIImage? {
            return image(withGrayscaleGradientPoints: gradientColors.map { GradientPoint(location: $0, color: $1) }, size: size)
        }
    }
    

    You can create gradient image using RGBA colors:

    // Objective-C
    RGBA *startColor = [[RGBA alloc] initWithRed:1 green:0 blue:0 alpha:1];
    RGBA *endColor = [[RGBA alloc] initWithIntRed:0 green:255 blue:0 alpha:255];
    UIImage *gradientImage = [UIImage imageWithRGBAGradient: @{ @0: startColor, @1: endColor} size: CGSizeMake(32, 64)];
    
    // Swift
    let startColor = RGBA(red: 1, green: 0, blue: 0, alpha: 1)
    let endColor = RGBA(intRed: 0, green: 255, blue: 0, alpha: 255)
    let gradientImage = UIImage.image(withRGBAGradientPoints: [0: startColor, 1: endColor], size: CGSizeMake(32, 64))
    

    And grayscale colors:

    // Objective-C
    Grayscale *startColor = [[Grayscale alloc] initWithWhite:1 alpha:1];
    Grayscale *endColor = [[Grayscale alloc] initWithWhite:0 alpha: 0.5];
    UIImage *gradientImage = [UIImage imageWithGrayscaleGradient: @{ @0: startColor, @1: endColor} size: CGSizeMake(32, 64)];
    
    // Swift
    let startColor = Grayscale(white: 1, alpha: 1)
    let endColor = Grayscale(white:0, alpha: 0.5)
    let gradientImage = UIImage.image(withGrayscaleGradientPoints: [0: startColor, 1: endColor], size: CGSizeMake(32, 64))
    

    If you are not going to use this code from Objective-C than you can remove NSObject inheritance from RGBA, Grayscale and GradientPoint.

提交回复
热议问题