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

后端 未结 9 572
佛祖请我去吃肉
佛祖请我去吃肉 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:27

    I think, It's more swifty

    Swift 3

    struct GradientPoint {
       var location: CGFloat
       var color: UIColor
    }
    
    
    
    extension UIImage {
    convenience init?(size: CGSize, gradientPoints: [GradientPoint]) {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
    
        guard let context = UIGraphicsGetCurrentContext() else { return nil }       // If the size is zero, the context will be nil.
        guard let gradient = CGGradient(colorSpace: CGColorSpaceCreateDeviceRGB(), colorComponents: gradientPoints.flatMap { $0.color.cgColor.components }.flatMap { $0 }, 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())
        guard let image = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { return nil }
        self.init(cgImage: image)
        defer { UIGraphicsEndImageContext() }
    }
    }
    
    
    extension UIImageView {
       func gradated(gradientPoints: [GradientPoint]) {
        let gradientMaskLayer       = CAGradientLayer()
        gradientMaskLayer.frame     = frame
        gradientMaskLayer.colors    = gradientPoints.map { $0.color.cgColor }
        gradientMaskLayer.locations = gradientPoints.map { $0.location as NSNumber }
        self.layer.insertSublayer(gradientMaskLayer, at: 0)
    }
    }
    

    Use like this,

    let points = [GradientPoint(location: 0, color: #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 0.2530534771)), GradientPoint(location: 0.2, color: #colorLiteral(red: 0.9686274529, green: 0.78039217, blue: 0.3450980484, alpha: 0.5028884243)), GradientPoint(location: 0.4, color: #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 0.3388534331)),
              GradientPoint(location: 0.6, color: #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 0.3458681778)), GradientPoint(location: 0.8, color: #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 0.3851232394))]
    
    UIImage(size: CGSize(width: 300, height: 300), gradientPoints: points)
    
    
    let veniceImageView = UIImageView(image: #imageLiteral(resourceName: "venice-italy.jpg"))
    veniceImageView.gradated(gradientPoints: points)
    

    I tested on swift 3. Check the screenshot.

    enter image description here

    0 讨论(0)
  • 2021-01-04 00:28

    Do you need some to add some TRANSPARENCY to the gradient?

    Set the alpha value in the color's declaration as follows:

    UIView *countDownView =[[UIView alloc]initWithFrame:CGRectMake((self.view.frame.size.width/2)-100, self.view.frame.size.height/2- 100, 200,200)];
    countDownView.layer.cornerRadius = 20.0;
    
    UIColor *colorFrom = [UIColor colorWithRed: 130/255. green:59/255. blue:216/255. alpha:1.0];
    UIColor *colorTo = [UIColor colorWithRed: 55/255. green:21/255. blue:250/255. alpha:0.5];
    
    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = countDownView.bounds;
    gradient.colors = [NSArray arrayWithObjects:(id)[colorFrom CGColor], (id)[colorTo CGColor], nil];
    gradient.cornerRadius = 20.0; //set the same cornerRadius than the UIView if needed
    
    [countDownView.layer insertSublayer:gradient atIndex:0];
    

    Need to remove it?

    [gradient removeFromSuperlayer];//not tested
    

    [works on xCode 7.2.1 for iOS 9]

    0 讨论(0)
  • 2021-01-04 00:32

    First you need to create a graphics context in the required size:

    CGSize size = CGSizeMake(width, height);
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    

    Create a colour space:

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    

    Now create the gradient:

    size_t gradientNumberOfLocations = 2;
    CGFloat gradientLocations[2] = { 0.0, 1.0 };
    CGFloat gradientComponents[8] = { r0, g0, b0, a0,     // Start color
                                      r1, g1, b1, a1, };  // End color
    
    CGGradientRef gradient = CGGradientCreateWithColorComponents (colorspace, gradientComponents, gradientLocations, gradientNumberOfLocations);
    

    Fill the context with the gradient - this assumes a vertical gradient:

    CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0, size.height), 0);
    

    Now you can create an image from the context:

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    

    Finally release the gradient, colour space and context:

    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorspace);
    UIGraphicsEndImageContext();
    
    0 讨论(0)
  • 2021-01-04 00:32

    Swift 3 version of Mixel's answer

    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<C>: 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<RGBA>], 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<Grayscale>], 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)
        }
    }
    
    0 讨论(0)
  • 2021-01-04 00:45

    You can use https://github.com/leszek-s/LSCategories It allows creating image with gradient like this:

    UIImage *gradient = [UIImage lsGradientImageWithSize:CGSizeMake(100, 100) startColor:[UIColor redColor] endColor:[UIColor greenColor] startPoint:CGPointMake(0.0, 0.0) endPoint:CGPointMake(0.0, 1.0)];
    
    0 讨论(0)
  • 2021-01-04 00:48

    A simpler answer, using a CAGradientLayer.

    CGSize size = CGSizeMake(width, height);
    CAGradientLayer *layer = [CAGradientLayer layer];
    layer.frame = CGRectMake(0, 0, size.width, size.height);
    layer.colors = @[(__bridge id)[UIColor blackColor].CGColor,  // start color
                     (__bridge id)[UIColor whiteColor].CGColor]; // end color
    
    UIGraphicsBeginImageContext(size);
    @try {
      [layer renderInContext:UIGraphicsGetCurrentContext()];
      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    } @finally {
      UIGraphicsEndImageContext();
    }
    
    0 讨论(0)
提交回复
热议问题