在 Swift 中创建纯色 UIImage

问题描述 投票:0回答:16

我想以编程方式创建一个由纯色填充的 UIImage。有人知道如何在 Swift 中做到这一点吗?

ios swift uiimage
16个回答
245
投票

另一个不错的解决方案, 斯威夫特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兼容,就是在UIImage中创建另一个构造函数,这样:

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

通过这种方式,您可以通过以下方式创建自定义彩色图像:

    let redImage = UIImage(color: .redColor())

或者,可以选择创建具有自定义尺寸的图像:

    let redImage200x200 = UIImage(color: .redColor(), size: CGSize(width: 200, height: 200))

157
投票

Swift 4 版本:

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

用途:

let image0 = UIColor.orange.image(CGSize(width: 128, height: 128))
let image1 = UIColor.yellow.image()

93
投票

这是另一种选择。我相信您想要一个精确的 UIImage 对象。

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
}

将其粘贴到您的 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
}

26
投票

更简洁的方法是将逻辑封装在

UIImage
扩展中:

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

现在消费者可以调用,

UIImage.imageWithColor(UIColor.blackColor())
来创建黑色背景的图像。


14
投票

对 @neoneye 的出色答案进行了细微调整,允许调用代码不需要创建 CGSize,并更改名称以不与许多其他名称冲突:

斯威夫特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))
        }
    }
}

10
投票
class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.backgroundColor = UIColor.redColor()
    }
}

如果您想自己绘制图像,则使用类似的方法与通过 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)
    }
}

第三种方法借自anthonyliao。稍微复杂一点:

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

8
投票

您可以使用新的 iOS 10 UIGraphicsImageRenderer API。

这是 Swift 3.1 中 UIColor 的扩展

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

7
投票

一个好的方法是拥有像这样的计算属性:

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

用途:

let redImage = UIColor.red.imageRepresentation

4
投票

@anthonyliao 的 Swift 3 版本接受的答案:

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
}

4
投票

Swift 5, Xcode 12.4 - UIImageView 的解决方案

如果您必须处理

UIImageView
,就像我的情况一样,您可以选择更紧凑的解决方案,例如:
exampleImageView.fill()
exampleImageView.fill(with: .black)

扩展程序代码:

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

3
投票

带圆角的矩形

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

2
投票

斯威夫特5 / 获取非可选 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
    }

如果需要,不要忘记使用format.scale = 1


2
投票

2023。说实话,就这么简单!

let image = UIGraphicsImageRenderer(size: sz).image { rendererContext in
    UIColor.gray.setFill()
    rendererContext.fill(CGRect(origin: .zero, size: sz))
}

1
投票

我们可以使用 UIGraphicsImageRenderer 来创建 UIImage 或使用传统的 CGContext 方法,下面是方便的 init 函数,它创建具有给定颜色的 UIImage

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

1
投票

如果您的应用程序支持 iOS 10 或更高版本,我们应该使用

UIGraphicsImageRenderer
,因为它更快

以下是

UIImage
扩展中的一些静态方法/初始化方法(可选
UIImage
):

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

预览:


0
投票

我发现这个效果很好并且具有更好的性能:

public extension UIImage{
    static func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { context in
                   color.setFill()
                   context.fill(CGRect(origin: .zero, size: size))
               }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.