我想以编程方式创建一个由纯色填充的 UIImage。有人知道在 Swift 里怎么做吗?
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) } }
第三种方法借鉴了 Anthony liao,稍微复杂一点:
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) } }
还有一个选择,我相信您想要一个精确的 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 }
更简洁的方法是将逻辑封装在 UIImage扩展中:
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())来创建一个具有黑色背景的图像。
UIImage.imageWithColor(UIColor.blackColor())
另一个不错的解决办法, 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 兼容,是在 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))
Swift 3 version of@anthonyliao 接受回答:
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 }
您可以使用新的 IOS10 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)) }) }}
一个不错的方法是使用这样的计算属性:
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
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()
一个微小的调整,@neweye 的出色的答案,允许调用代码不需要创建 CGSize,并改变了名称,以免与许多其他名称发生冲突:
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)) } } }
圆角的直角
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) } }
我们可以使用 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) } } }
Swift 5 /< strong > 获取非可选的 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 }
如果需要,不要忘记使用 form.scale = 1
Swift 5,Xcode 12.4-UIImageView 的解决方案
如果您必须像我这样处理 UIImageView,您可以选择更紧凑的解决方案,如: exampleImageView.fill()或 exampleImageView.fill(with: .black)。
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 } }
如果您的应用程序支持 iOS10或更高版本,我们应该使用 UIGraphicsImageRenderer,因为它是 再快点。
UIGraphicsImageRenderer
下面是 UIImage扩展中的一些静态方法/init 方法(可选 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) } }
预览: