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

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

    Here's how I implemented Simon's suggestion (elsewhere in this thread) to create a reusable "hot" and "cold" UIImage like below:

    Objective-C code:

    -(UIImage*)createHotOrColdImage:(BOOL)bHot
    {
        //  Create a UIImage with either a "Hot" or "Cold" gradient background
        //
        const int WIDTH = 75;
        const int HEIGHT = 44;
    
        //  Do we want our UIImage to fade from black-to-red or black-to-blue ?
        UIColor* color = (bHot) ? [UIColor redColor] : [UIColor colorWithRed:0.3 green:0.3 blue:1.0 alpha:1.0];
    
        CGSize size = CGSizeMake(WIDTH, HEIGHT);
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    
        const CGFloat *components = CGColorGetComponents(color.CGColor);
        CGFloat red = components[0];
        CGFloat green = components[1];
        CGFloat blue = components[2];
    
        size_t gradientNumberOfLocations = 4;
        CGFloat gradientLocations[4] = { 0.0, 0.3, 0.7, 1.0 };
        CGFloat gradientComponents[16] = { red, green, blue, 0,
            red, green, blue, 1,
            red, green, blue, 1,
            red, green, blue, 0 }; 
    
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef gradient = CGGradientCreateWithColorComponents (colorspace, gradientComponents, gradientLocations, gradientNumberOfLocations);
    
        //  Create a UIImage containing this gradient
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        //  Make sure the gradient is vertical
        CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0, HEIGHT), 0);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        CGGradientRelease(gradient);
        CGColorSpaceRelease(colorspace);
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    To use:

    UIImage* hotImage = [self createHotOrColdImage:TRUE];
    UIImage* coldImage = [self createHotOrColdImage:FALSE];
    
    0 讨论(0)
  • 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<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)
        }
    }
    

    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.

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

    Xamarin solution:

        private UIImage GenerateBackgroundGradient(CGSize size, CGColor[] colors)
        {
            UIImage backgroundGradient = null;
    
            var layer = new CAGradientLayer
            {
                Frame = View.Frame,
                Colors = colors
            };
    
            UIGraphics.BeginImageContext(size);
            layer.RenderInContext(UIGraphics.GetCurrentContext());
            backgroundGradient = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
    
            return backgroundGradient;
        }
    
    0 讨论(0)
提交回复
热议问题