¿Cómo crear un UIImage 1×1 coloreado en el iPhone dinámicamente?

Me gustaría crear un UIImage 1×1 dinámicamente basado en un UIColor.

Sospecho que esto se puede hacer rápidamente con Quartz2d, ​​y estoy estudiando detenidamente la documentación tratando de comprender los fundamentos. Sin embargo, parece que hay muchas trampas potenciales: no identifica correctamente el número de bits y bytes por cosas, no especifica las banderas correctas, no libera datos no utilizados, etc.

¿Cómo se puede hacer esto de forma segura con Quartz 2d (u otra forma más sencilla)?

Puede usar CGContextSetFillColorWithColor y CGContextFillRect para esto:

Rápido

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

C objective

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

Aquí hay otra opción basada en el código de Matt Stephen. Crea una imagen de color sólido que se puede cambiar de tamaño de modo que pueda reutilizarla o cambiar su tamaño (por ejemplo, usarla como fondo).

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

Ponlo en una categoría UIImage y cambia el prefijo.

Utilicé la respuesta de Matt Steven muchas veces, así que hice una categoría para ella:

 @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 

Para mí, un init de conveniencia se siente más ordenado en 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) } } 

Ok, esto no será exactamente lo que quieres, pero este código dibujará una línea. Puedes adaptarlo para hacer un punto. O al menos obtener un poco de información de él.

Hacer la imagen 1×1 parece un poco extraño. Los trazos recorren la línea, por lo que un tramo de ancho 1.0 a 0.5 debería funcionar. Solo juega.

 - (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(); }