Створіть UIImage із суцільним кольором у Swift


140

Я хочу програмно створити UIImage, наповнену суцільним кольором. Хтось має уявлення про те, як це зробити в Swift?


UIImageне має -initWithSize:andColor:методу, але він NSImageпрацює в OS X. Ви використовуєте для цього власну бібліотеку чи категорію?
ttarik

Вибачте, це правда, що я використовував це через категорію (дивлячись на старий проект). Просто відредагуйте моє запитання.
Генрі Фам

Відповіді:


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

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
якщо ви хочете створити зображення у розмірі 1x, почніть з цього коду UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0) ref: developer.apple.com/library/ios/documentation/UIKit/Reference/…
nahung89

3
Як ми можемо зробити ці зображення кутовими?
Умаїр Афзал

Чому ми не можемо просто повернутися image? Навіщо це робити? self.init(cgImage: cgImage)
Андрій Гаган

@AndreyGagan AFAIK, ви не можете "замінити" себе на новостворений UIImageу конструкторі, але можете UIImage.init(cgImage: )замість цього виконати ланцюг через конструктор.
Альнітак

2
Зображення не створюється в належному масштабі. Наприклад, коли розмір 1х1, зображення 2x2 повертається, коли масштаб основного екрана дорівнює 2,0. Вам слід зателефонуватиself.init(cgImage: cgImage, scale: image!.scale, orientation: image!.imageOrientation)
Marián Černý

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 і зателефонуйте

Швидкий 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декларацію.
Зорайр

1
Як ми можемо зробити ці зображення кутовими?
Умаїр Афзал

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
Мені це дуже подобається, для мене це має велике значення, щоб розширення було не кольоровим, а кольоровим.
пам'ятний

1
(⚠️ iOS 10 або новіші). Гарна та чиста відповідь btw.
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())створити зображення з чорним фоном.


Як ми можемо зробити ці зображення кутовими?
Умаїр Афзал

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
Це, мабуть, досягає ефекту, якого хотів ОП, але нічого не варто, щоб у них був метод створити, а UIImageне встановити UIImageView.
ttarik

Ваш другий метод все ще створює перегляд зображення, а не зображення, на що вказував @ ev0lution.
rdelmar

редагувати 3 додається. Зараз у нас є купа способів. Заключний з UIImageView.
Стів Розенберг

1
Методу getImageWithColor(color: UIColor, size: CGSize) -> UIImageдостатньо як відповіді, тому що я думаю, що не всі будуть використовувати це разом з UIImageView
Генрі Фам

Як ми можемо зробити ці зображення кутовими?
Умаїр Афзал

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.

Ось розширення на UIColor у 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

Гарний спосіб - мати обчислену властивість, як це:

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

Swift 3 версія @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
}

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

}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.