Как динамически создать на iPhone цветной 1x1 UIImage? - PullRequest
114 голосов
/ 13 июня 2009

Я хотел бы создать динамический UIImage 1x1 на основе UIColor.

Я подозреваю, что это можно быстро сделать с помощью Quartz2d, ​​и я изучаю документацию, пытаясь понять основы. Тем не менее, похоже, что существует множество потенциальных ловушек: неправильная идентификация количества битов и байтов в каждой вещи, неправильная установка правильных флагов, не освобождение неиспользуемых данных и т. Д.

Как это можно безопасно сделать с помощью Quartz 2d (или другого более простого способа)?

Ответы [ 6 ]

327 голосов
/ 14 июня 2009

Вы можете использовать CGContextSetFillColorWithColor и CGContextFillRect для этого:

Swift

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

Swift3

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRect(origin: CGPoint(x: 0, y:0), size: CGSize(width: 1, height: 1))
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()!

        context.setFillColor(color.cgColor)
        context.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

Objective-C

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
8 голосов
/ 27 февраля 2014

Вот еще один вариант, основанный на коде Мэтта Стивена. Он создает изменяемое в размерах сплошное цветное изображение, чтобы вы могли использовать его повторно или изменить его размер (например, использовать его для фона).

+ (UIImage *)prefix_resizeableImageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 3.0f, 3.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];

    return image;
}

Поместите его в категорию UIImage и измените префикс.

6 голосов
/ 03 октября 2013

Я использовал ответ Мэтта Стивена много раз, поэтому создал для него категорию:

@interface UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension;
@end

@implementation UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension {
    CGRect rect = CGRectMake(0, 0, dimension, dimension);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
@end
3 голосов
/ 27 октября 2018

Используя новейший UIGraphicsImageRenderer от Apple, код довольно мал:

import UIKit

extension UIImage {
    static func from(color: UIColor) -> UIImage {
        let size = CGSize(width: 1, height: 1)
        return UIGraphicsImageRenderer(size: size).image(actions: { (context) in
            context.cgContext.setFillColor(color.cgColor)
            context.fill(.init(origin: .zero, size: size))
        })
    }
}
0 голосов
/ 10 июля 2018

Для меня удобство инициации в Swift выглядит лучше

extension UIImage {

    convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {

        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContext(rect.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        context.setFillColor(color.cgColor)
        context.fill(rect)

        guard let image = context.makeImage() else {
            return nil
        }
        UIGraphicsEndImageContext()

        self.init(cgImage: image)
    }

}
0 голосов
/ 14 июня 2009

Хорошо, это не совсем то, что вы хотите, но этот код нарисует линию. Вы можете адаптировать его, чтобы сделать точку. Или, по крайней мере, получить немного информации от него.

Создание изображения 1x1 кажется немного странным. Штрихи перемещаются по линии, поэтому должен работать штрих шириной 1,0 при 0,5. Просто поиграй.

- (void)drawLine{

UIGraphicsBeginImageContext(CGSizeMake(320,300));

CGContextRef ctx = UIGraphicsGetCurrentContext();

float x = 0;
float xEnd = 320;
float y = 300;

CGContextClearRect(ctx, CGRectMake(5, 45, 320, 300));

CGContextSetGrayStrokeColor(ctx, 1.0, 1.0);

CGContextSetLineWidth(ctx, 1);
CGPoint line[2] = { CGPointMake(x,y), CGPointMake(xEnd, y) };

CGContextStrokeLineSegments(ctx, line, 2);

UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
...