Create UIImage with solid color in Swift

IosSwiftUiimage

Ios Problem Overview


I want to programmatically create an UIImage filled by a solid color. Anyone have an idea of how to do this in Swift?

Ios Solutions


Solution 1 - Ios

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

Solution 2 - Ios

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

Solution 3 - Ios

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
}

Solution 4 - Ios

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.

Solution 5 - Ios

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

Solution 6 - Ios

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

Solution 7 - Ios

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

Solution 8 - Ios

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

Solution 9 - Ios

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
}

Solution 10 - Ios

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

Solution 11 - Ios

Swift 5, Xcode 12.4 - UIImageView's solution

If you have to deal with UIImageViews 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
    }
}

Solution 12 - Ios

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

Solution 13 - Ios

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:

enter image description here

Solution 14 - Ios

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHenry PhamView Question on Stackoverflow
Solution 1 - IosLuca DavanzoView Answer on Stackoverflow
Solution 2 - IosneoneyeView Answer on Stackoverflow
Solution 3 - IosanthonyliaoView Answer on Stackoverflow
Solution 4 - IosZorayrView Answer on Stackoverflow
Solution 5 - Iosdrew..View Answer on Stackoverflow
Solution 6 - IosSteve RosenbergView Answer on Stackoverflow
Solution 7 - IosMoustafa BaalbakiView Answer on Stackoverflow
Solution 8 - IosiOSGeekView Answer on Stackoverflow
Solution 9 - IosAyman IbrahimView Answer on Stackoverflow
Solution 10 - IosdroidView Answer on Stackoverflow
Solution 11 - IosAlessandro FrancucciView Answer on Stackoverflow
Solution 12 - IosMikhail YaskouView Answer on Stackoverflow
Solution 13 - IosChris SoView Answer on Stackoverflow
Solution 14 - IosSuhit PatilView Answer on Stackoverflow