Tạo UIImage với màu đơn sắc trong Swift


140

Tôi muốn lập trình tạo ra một UIImage được lấp đầy bởi một màu đơn sắc. Bất cứ ai cũng có một ý tưởng về cách làm điều này trong Swift?


UIImagekhông có -initWithSize:andColor:phương thức, nhưng NSImagetrên OS X. Bạn có đang sử dụng thư viện hoặc danh mục tùy chỉnh cho việc này không?
ttarik

Xin lỗi, đúng là tôi đã sử dụng nó thông qua một danh mục (nhìn vào một dự án cũ). Chỉ cần chỉnh sửa câu hỏi của tôi.
Henry Phạm

Câu trả lời:


194

Một giải pháp hay khác, tương thích Swift 2.2 , là tạo một hàm tạo khác trong UIImage, theo cách này:

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

Theo cách này, bạn có thể tạo hình ảnh màu tùy chỉnh theo cách này:

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

Hoặc, tùy ý, tạo hình ảnh với kích thước tùy chỉnh:

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

Swift 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
nếu bạn muốn tạo hình ảnh với kích thước 1x, hãy bắt đầu với mã này UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0) ref: developer.apple.com/library/ios/documentation/UIKit/Reference/...
nahung89

3
Làm thế nào chúng ta có thể làm cho những hình ảnh góc tròn hơn?
Umair Afzal

Tại sao chúng ta không thể quay trở lại image? Tại sao cần phải làm điều này? self.init(cgImage: cgImage)
Andrey Gagan

@AndreyGagan AFAIK, bạn không thể "thay thế" bản thân bằng cái mới được tạo UIImagetrong một hàm tạo, nhưng UIImage.init(cgImage: )thay vào đó bạn có thể xâu chuỗi qua hàm tạo.
Alnitak

2
Hình ảnh không được tạo ra với tỷ lệ thích hợp. Ví dụ: khi kích thước là 1x1, hình ảnh 2x2 được trả về khi tỷ lệ màn hình chính là 2.0. Bạn nên gọiself.init(cgImage: cgImage, scale: image!.scale, orientation: image!.imageOrientation)
Marián erný

92

Đây là một lựa chọn khác. Tôi tin rằng bạn muốn một đối tượng UIImage chính xác.

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
}

Dán mã này vào mã Swift của bạn và gọi nó

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
}

Tôi nghĩ rằng không có phương pháp UIRectMake(0, 0, size.width, size.height), đây có vẻ là một phương pháp chính xác : CGRectMake(0, 0, size.width, size.height).
Henry Phạm

1
Nói chung, cố gắng sử dụng letthay vì varcho các biến không thay đổi; ở đây có vẻ như không nên rectvà cũng không imagenên sử dụng varkhai báo.
Zorayr

1
Làm thế nào chúng ta có thể làm cho những hình ảnh góc tròn hơn?
Umair Afzal

83

Phiên bản 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))
        }
    }
}

Sử dụng:

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

3
Tôi thích rằng hình ảnh được tạo ra không phải là một tùy chọn
jlukanta

1
Tôi rất thích điều này, với tôi nó rất có ý nghĩa đối với phần mở rộng là từ màu sắc chứ không phải hình ảnh.
tuyệt vời

1
(IOS 10 trở lên). Đẹp và sạch câu trả lời btw.
frouo

19

Một cách tiếp cận sạch hơn sẽ là gói gọn logic bên trong một UIImagephần mở rộng:

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

Bây giờ người tiêu dùng có thể gọi, UIImage.imageWithColor(UIColor.blackColor())để tạo một hình ảnh với nền đen.


Làm thế nào chúng ta có thể làm cho những hình ảnh góc tròn hơn?
Umair Afzal

10
class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.backgroundColor = UIColor.redColor()
    }
}

Phương pháp tương tự nếu bạn muốn tự vẽ hình ảnh so với kết nối thông qua 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)
    }
}

Phương pháp thứ ba mượn từ anthonyliao. Một chút phức tạp hơn:

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
Điều này có thể đạt được hiệu quả mà OP muốn nhưng không có gì đáng để họ có phương pháp để tạo UIImage, chứ không phải đặt UIImageView.
ttarik

Phương pháp thứ hai của bạn vẫn tạo ra chế độ xem hình ảnh, không phải hình ảnh, đó là những gì @ ev0lutions đã chỉ ra.
ndelmar

chỉnh sửa 3 đính kèm. Bây giờ chúng tôi có một loạt các cách. Cuối cùng với một UIImageView.
Steve Rosenberg

1
Phương pháp getImageWithColor(color: UIColor, size: CGSize) -> UIImagenày là đủ như câu trả lời, vì tôi nghĩ không phải ai cũng sẽ sử dụng phương pháp này cùng với UIImageView
Henry Phạm

Làm thế nào chúng ta có thể làm cho những hình ảnh góc tròn hơn?
Umair Afzal

9

Một điều chỉnh nhỏ cho câu trả lời tuyệt vời của @ neoneye, cho phép mã cuộc gọi không cần tạo CGSize và thay đổi tên để không va chạm với nhiều người khác:

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

8

Bạn có thể sử dụng API UIGraphicsImageRenderer iOS 10 mới .

Đây là một phần mở rộng trên UIColor trong 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))
    })
}}

6

Một cách hay là có một tài sản được tính toán như thế này:

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

Sử dụng:

let redImage = UIColor.red.imageRepresentation

Tôi nghĩ rằng một số câu trả lời ở đây là một chút sai lệch. Hầu hết thời gian bạn sẽ cần chỉ định kích thước của hình ảnh, không phải là trường hợp cụ thể (như 1x1). Nhưng đây là một cách tiếp cận tốt đẹp.
Henry Phạm

4

Phiên bản Swift 3 của @anthonyliao Câu trả lời được chấp nhận:

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

Rect với các góc tròn

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

}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.