I want to programmatically create an UIImage filled by a solid color. Anyone have an idea of how to do this in Swift?
-
`UIImage` doesn't have an `-initWithSize:andColor:` method, but `NSImage` does on OS X. Are you using a custom library or category for this? – ttarik Oct 24 '14 at 05:35
-
Sorry, it's true that I used it through a category (looking at an old project). Just edit my question. – Henry Pham Oct 24 '14 at 11:23
15 Answers
Another nice solution, Swift 3.0
public extension UIImage {
convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
Swift 2.2 compatible, is to create another constructor in UIImage, in this way:
public extension UIImage {
public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.CGImage else { return nil }
self.init(CGImage: cgImage)
}
}
In this way you can create the custom colored-image in this way:
let redImage = UIImage(color: .redColor())
Or, optionally, create the image with a custom size:
let redImage200x200 = UIImage(color: .redColor(), size: CGSize(width: 200, height: 200))

- 7,904
- 1
- 47
- 44

- 21,000
- 15
- 120
- 146
-
1if you want to create image with 1x size, start with this code `UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0)` ref: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIGraphicsBeginImageContextWithOptions – nahung89 Jan 20 '16 at 04:03
-
3
-
Why we can't just return `image`? Why need to do this? `self.init(cgImage: cgImage)` – Andrey Gagan Jan 24 '17 at 12:49
-
@AndreyGagan AFAIK, you can't "replace" self with the newly created `UIImage` in a constructor, but you can chain via the `UIImage.init(cgImage: )` constructor instead. – Alnitak Mar 11 '17 at 15:17
-
4The image is not created with proper scale. E.g. when the size is 1x1, an image 2x2 is returned when the main screen scale is 2.0. You should call `self.init(cgImage: cgImage, scale: image!.scale, orientation: image!.imageOrientation)` – Marián Černý Oct 20 '17 at 12:06
-
Swift 4 version:
extension UIColor {
func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { rendererContext in
self.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
}
}
}
Usage:
let image0 = UIColor.orange.image(CGSize(width: 128, height: 128))
let image1 = UIColor.yellow.image()

- 431
- 4
- 12

- 50,398
- 25
- 166
- 151
-
8
-
1I like this very much, to me it makes a lot of sense for the extension to be from color rather than image. – quemeful Jul 12 '19 at 12:32
-
1
-
Here's another option. I believe you wanted an exact UIImage object.
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRectMake(0, 0, size.width, size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Stick this in your Swift code and call it
Swift 3.1:
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}

- 16,233
- 18
- 112
- 180

- 1,314
- 1
- 8
- 8
-
I think there is no method `UIRectMake(0, 0, size.width, size.height)`, this seems to be the correct one: `CGRectMake(0, 0, size.width, size.height)`. – Henry Pham Oct 24 '14 at 10:52
-
1Generally, try to use `let` instead of `var` for immutable variables; here seems like neither `rect` nor `image` should be using `var` declaration. – Zorayr Apr 26 '15 at 00:37
-
1
A cleaner approach would be to encapsulate the logic inside an UIImage
extension:
import UIKit
extension UIImage {
class func imageWithColor(color: UIColor) -> UIImage {
let rect: CGRect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Now the consumer can call, UIImage.imageWithColor(UIColor.blackColor())
to create an image with black background.
A minor tweak to @neoneye's excellent answer, allowing the calling code not to need to create the CGSize, and altered the name to not collide with numerous others:
Swift 4
extension UIColor {
func imageWithColor(width: Int, height: Int) -> UIImage {
let size = CGSize(width: width, height: height)
return UIGraphicsImageRenderer(size: size).image { rendererContext in
self.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
}
}
}

- 3,234
- 3
- 16
- 19
-
Thank you. I used this, but I changed the width and height params to `CGFloat`. – Marcus Adams Jan 05 '21 at 19:54
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.backgroundColor = UIColor.redColor()
}
}
Similar method if you want draw the image yourself vs. connecting one via IBOutlet.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var frame = CGRectMake(100,100,100,100)
var imageView2 = UIImageView(frame: frame)
imageView2.backgroundColor = UIColor.redColor()
self.view.addSubview(imageView2)
}
}
Third method borrowing from anthonyliao. A little more complicated:
class ViewController: UIViewController {
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(CGRectMake(0, 0, 100, 100))
var image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
override func viewDidLoad() {
super.viewDidLoad()
var imageView = UIImageView(frame: CGRectMake(100,100,100,100))
let screenImage = getImageWithColor(UIColor.redColor(), size: CGSize(width: 100, height: 100))
imageView.image = screenImage
self.view.addSubview(imageView)
}
}

- 19,348
- 7
- 46
- 53
-
2This *probably* achieves the effect that OP wanted but it's worth nothing that they had a method to create a `UIImage`, not to set a `UIImageView`. – ttarik Oct 24 '14 at 05:41
-
Your second method still creates an image view, not an image, which is what @ev0lution was pointing out. – rdelmar Oct 24 '14 at 05:53
-
edit 3 attached. Now we have a bunch of ways. Final one with a UIImageView. – Steve Rosenberg Oct 24 '14 at 06:18
-
1The method `getImageWithColor(color: UIColor, size: CGSize) -> UIImage` is enough as the answer, as I think not everyone will use this together with an UIImageView – Henry Pham Oct 24 '14 at 11:07
-
You can use the new iOS 10 UIGraphicsImageRenderer API.
Here is an extension on UIColor in Swift 3.1
extension UIColor {
func getImage(size: CGSize) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: size)
return renderer.image(actions: { rendererContext in
self.setFill()
rendererContext.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
})
}}

- 81
- 1
- 3
A nice way is to have a computed property like this:
extension UIColor {
var imageRepresentation : UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(self.cgColor)
context?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Usage:
let redImage = UIColor.red.imageRepresentation

- 5,115
- 9
- 46
- 74
-
I think some answers here are a little misleading. Most of the time you will need to specify the size of the image, not a specific case (like 1x1). But this is a nice approach. – Henry Pham Aug 24 '17 at 09:11
Swift 3 version of @anthonyliao Accepted answer:
class func getImageWithColor(color: UIColor, size: CGSize) -> UIImage
{
let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: size.width, height: size.height))
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}

- 1,359
- 15
- 24
Swift 5, Xcode 12.4 - UIImageView's solution
If you have to deal with UIImageView
s like in my case, you could opt for a more compact solution like: exampleImageView.fill()
or exampleImageView.fill(with: .black)
.
Extension's code:
extension UIImageView {
func fill(with color: UIColor = .lightGray) {
let size = self.bounds.size
let image = UIGraphicsImageRenderer(size: size).image { rendererContext in
color.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
}
self.image = image
}
}

- 1,528
- 17
- 25
Rect with rounded corners
extension UIImage {
convenience init?(color: UIColor) {
let rect = CGRect(x: 0, y: 0, width: 10, height: 2)
UIGraphicsBeginImageContextWithOptions(CGSize(width: 10, height: 2), false, 0)
let bezierPath = UIBezierPath(roundedRect: rect, cornerRadius: 8)
color.setFill()
bezierPath.fill()
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
guard let cgImage = image.cgImage else {
return nil
}
self.init(cgImage: cgImage)
}
}
Swift 5 / Get not optional UIImage
public static func withColor(_ color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let image = UIGraphicsImageRenderer(size: size, format: format).image { rendererContext in
color.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
}
return image
}
Don't forget to use format.scale = 1 if it needed

- 61
- 3
-
1Welcome to StackOverflow Mikhail. While your code example may solve the question an explanation of how and why this solves the problem would really help to improve the quality of your answer. Remember that you're answering the question for readers in the future, not just the person asking now. I suggest you add an explanation to your answer. You might find the [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) article helpful. – Mike Poole Jan 14 '21 at 14:32
-
Works great! Used it to set the background color of a UISegmentedControl(), wherein they don't provide API to do it through .backgroundColor or other means, and this did the trick. Thanks! – clearlight Apr 04 '23 at 10:39
2023. Honestly it's this simple!
let image = UIGraphicsImageRenderer(size: sz).image { rendererContext in
UIColor.gray.setFill()
rendererContext.fill(CGRect(origin: .zero, size: sz))
}

- 27,874
- 70
- 431
- 719
we can use UIGraphicsImageRenderer to create the UIImage or use traditional CGContext approach, below is convenience init function which creates UIImage with given color
extension UIImage {
/// create UIImage with color and given size
convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1), alpha: CGFloat = 1, scale: CGFloat = 0) {
if #available(tvOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { (ctx) in
let size = renderer.format.bounds.size
ctx.fill(CGRect(origin: .zero, size: size))
ctx.cgContext.setFillColor(color.cgColor)
}
guard let cgImage = image.cgImage else { return nil }
self.init(cgImage: cgImage)
} else {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, scale)
let context = UIGraphicsGetCurrentContext()!
let fillColor = color.withAlphaComponent(alpha)
context.setFillColor(fillColor.cgColor)
context.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
}

- 11,748
- 3
- 50
- 60
If your application support iOS 10 or above, we should use UIGraphicsImageRenderer
since it is faster.
Here are some static methods / init methods (optional UIImage
) in UIImage
's extension:
import UIKit
extension UIImage {
static func from(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = 1
return UIGraphicsImageRenderer(size: size, format: format).image { context in
color.setFill()
context.fill(CGRect(origin: .zero, size: size))
}
}
static func from(color: UIColor, size: CGFloat = 1) -> UIImage {
return from(color: color, size: CGSize(width: size, height: size))
}
static func from(color: UIColor) -> UIImage {
return from(color: color, size: 1)
}
convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let image = UIGraphicsImageRenderer(size: size, format: format).image { context in
color.setFill()
context.fill(CGRect(origin: .zero, size: size))
}
guard let cgImage = image.cgImage else { return nil }
self.init(cgImage: cgImage)
}
convenience init?(color: UIColor, size: CGFloat = 1) {
self.init(color: color, size: CGSize(width: size, height: size))
}
convenience init?(color: UIColor) {
self.init(color: color, size: 1)
}
}
struct Example {
func createAnImageWithColorRed() {
UIImage(color: .red, size: CGSize(width: 10, height: 10))
UIImage(color: .red, size: 10)
UIImage(color: .red)
UIImage.from(color: .red, size: CGSize(width: 10, height: 10))
UIImage.from(color: .red, size: 10)
UIImage.from(color: .red)
}
}
Preview:

- 711
- 1
- 11
- 23