在Swift中用纯色创建UIImage


140

我想以编程方式创建由纯色填充的UIImage。有人知道如何在Swift中执行此操作吗?


UIImage没有-initWithSize:andColor:方法,但是NSImage在OS X上有方法。您是否为此使用自定义库或类别?
ttarik 2014年

抱歉,确实是我通过一个类别使用了它(看一个旧项目)。只需编辑我的问题。
亨利·潘

Answers:


194

另一个与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))

斯威夫特3.0

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

1
如果你想用1X大小创造的形象,开始与这个码UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0) 参考:developer.apple.com/library/ios/documentation/UIKit/Reference/...
nahung89

3
如何使这些图像更圆角?
Umair Afzal,2013年

为什么我们不能只返回image?为什么需要这样做?self.init(cgImage: cgImage)
Andrey Gagan

@AndreyGagan AFAIK,您不能用UIImage在构造函数中新创建的“替换”自身,但可以通过UIImage.init(cgImage: )构造函数进行链接。
Alnitak

2
无法以适当的比例创建图像。例如,当尺寸为1x1时,当主屏幕比例为2.0时将返回图像2x2。你应该叫self.init(cgImage: cgImage, scale: image!.scale, orientation: image!.imageOrientation)
玛丽安CERNY

92

这是另一个选择。我相信您想要一个确切的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代码中并调用它

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
}

我认为没有方法UIRectMake(0, 0, size.width, size.height),这似乎是正确的方法:CGRectMake(0, 0, size.width, size.height)
亨利·范

1
通常,尝试使用let而不是不var变量。这里似乎既不rect也不image应该使用var声明。
Zorayr 2015年

1
如何使这些图像更圆角?
Umair Afzal,2013年

83

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

3
我喜欢创建的图像不是可选的
jlukanta

1
我非常喜欢这个,对我来说,扩展来自颜色而不是图像非常有意义。
魁北克'19

1
(⚠️iOS 10或更高版本)。好和干净的答案顺便说一句。
Frouo

19

一种更干净的方法是将逻辑封装在UIImage扩展内:

import UIKit

extension UIImage {
  class func imageWithColor(color: UIColor) -> UIImage {
    let rect: CGRect = CGRectMake(0, 0, 1, 1)
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), false, 0)
    color.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
  }
}

现在,消费者可以致电UIImage.imageWithColor(UIColor.blackColor())以创建具有黑色背景的图像。


如何使这些图像更圆角?
Umair Afzal,2013年

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

第三种方法是从蒽酚那里借来的。稍微复杂一点:

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

2
可能达到了OP想要的效果,但是他们拥有创建a UIImage而不是设置a 的方法,这毫无价值UIImageView
ttarik 2014年

第二种方法仍然创建图像视图,而不是图像,这是@ ev0lution指出的内容。
rdelmar 2014年

编辑3附。现在我们有很多方法。最后一个带有UIImageView。
史蒂夫·罗森伯格

1
该方法getImageWithColor(color: UIColor, size: CGSize) -> UIImage足以解决问题,因为我认为并不是每个人都会将其与UIImageView一起使用
Henry Pham

如何使这些图像更圆角?
Umair Afzal

9

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

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

6

一种不错的方法是具有如下所示的计算属性:

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

我认为这里的一些答案有些误导。大多数时候,您将需要指定图像的大小,而不是特定情况(例如1x1)。但这是一个不错的方法。
亨利·范

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
}

0

圆角矩形

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

}

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.