如何在iPhone上动态创建彩色的1x1 UIImage?


120

我想基于UIColor动态创建1x1 UIImage。

我怀疑这可以通过Quartz2d迅速完成,并且我正在仔细研究文档,以期掌握基本原理。但是,看起来有很多潜在的陷阱:无法正确识别每个事物的位数和字节数,未指定正确的标志,不会释放未使用的数据等。

如何使用Quartz 2d(或更简单的方法)安全地完成此操作?

Answers:


331

您可以为此使用CGContextSetFillColorWithColorCGContextFillRect

迅速

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
    }
}

迅捷3

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!
    }
}

目标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;
}

19
不错:-)我建议将此方法作为类方法放入一个类别中,然后可以将其简单地添加到项目中,并使用类似的行来调用[UIImage imageWithColor: [UIColor redColor]]

7
如果要循环创建这些图像或使用更大的尺寸,则优化将是仅在颜色为alpha时才使用不透明的画布。像这样:const CGFloat alpha = CGColorGetAlpha(color.CGColor); const BOOL opaque = alpha == 1; UIGraphicsBeginImageContextWithOptions(size, opaque, 0);
hpique

请提供快速版本
fnc12 2015年

有没有办法让swift成为自定义初始化程序?
Antzi 2015年

1
为什么要UIGraphicsGetCurrentContext()归来nil编辑:我知道了,我经过0rectwidth
Iulian Onofrei 2015年

9

这是基于Matt Stephen的代码的另一个选择。它创建可调整大小的纯色图像,以便您可以重复使用它或更改其大小(例如,将其用作背景)。

+ (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

我多次使用了马特·史蒂文(Matt Steven)的答案,因此将其归为一个类别:

@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

5

使用Apple最新的UIGraphicsImageRenderer,代码非常小:

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

对我来说,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)
    }

}

-7

好的,这不是您想要的,但是这段代码会画一条线。您可以调整它来说明重点。或者至少从中获得一些信息。

使图像为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();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.