Как создать новое изображение только с цветами градиента, используя "цветные" и "цветные"?
Как создать UIImage с вертикальным градиентом, используя "цветные" и "цветные",
Ответ 1
Простой ответ, используя 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);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Ответ 2
Сначала вам нужно создать графический контекст в требуемом размере:
CGSize size = CGSizeMake(width, height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
Создайте цветовое пространство:
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
Теперь создайте градиент:
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);
Заполните контекст градиентом - это предполагает вертикальный градиент:
CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0, size.height), 0);
Теперь вы можете создать изображение из контекста:
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
Наконец, отпустите градиент, цветовое пространство и контекст:
CGGradientRelease(gradient);
CGColorSpaceRelease(colorspace);
UIGraphicsEndImageContext();
Ответ 3
Я думаю, это более осторожно
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)
}
}
Используйте это,
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)
Я тестировал на быстрые 3. Проверьте скриншот.
Ответ 4
ОБНОВЛЕНО Swift 3
Я написал расширение UIImage
для Swift, но вы также можете использовать его из 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)
}
}
Вы можете создать градиентное изображение с использованием цветов RGBA:
// 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))
И оттенки серого:
// 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))
Если вы не собираетесь использовать этот код из Objective-C, чем вы можете удалить наследование NSObject
из RGBA
, Grayscale
и GradientPoint
.
Ответ 5
Swift 3 версия ответа Mixel
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)
}
}
Ответ 6
Вам нужно добавить некоторые ПРОЗРАЧНОСТЬ в градиент?
Задайте значение альфа в объявлении цвета следующим образом:
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];
Нужно удалить его?
[gradient removeFromSuperlayer];//not tested
[работает на xCode 7.2.1 для iOS 9]
Ответ 7
Вот как я внедрил предложение Саймона (в другом месте этой темы) для создания многоразового "горячего" и "холодного" UIImage
, как показано ниже:
Objective-C код:
-(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;
}
Для использования:
UIImage* hotImage = [self createHotOrColdImage:TRUE];
UIImage* coldImage = [self createHotOrColdImage:FALSE];
Ответ 8
Раствор Xamarin:
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;
}
Ответ 9
Вы можете использовать https://github.com/leszek-s/LSCategories Это позволяет создавать изображение с градиентом следующим образом:
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)];