Skip to content

UIGraphicsBeginImageContext vs UIGraphicsImageRenderer

UIGraphicsBeginImageContextWithOptions has been deprecated from iOS17, and it will crash on iOS17 when the height or width of size argument is 0.

We should replace UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer.

Render an image with UIGraphicsBeginImageContext

swift
let bound = CGRect(x: 0, y: 0, width: 200, height: 200)
UIGraphicsBeginImageContextWithOptions(bound.size, false, UIScreen.main.scale)
if let context = UIGraphicsGetCurrentContext() {
    UIColor.darkGray.setStroke()
    context.stroke(bound)
    UIColor(red: 158/255, green: 215/255, blue: 245/255, alpha: 1).setFill()
    context.fill(CGRect(x: 1, y: 1, width: 140, height: 140))
    let image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()

The above code creates the following image:

render image rectangle

Render an image with UIGraphicsImageRenderer

Rendering the same image with UIGraphicsImageRenderer.

  1. [Optional] Create a UIGraphicsImageRendererFormat object and specify render parameters.
swift
let format = UIGraphicsImageRendererFormat.default()
format.opaque = true
  1. Create a UIGraphicsImageRenderer object, providing size arugment and format argument(optional).

    If you don't provider format object, the render uses default format for the current device.
swift
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200))
swift
let format = UIGraphicsImageRendererFormat.default()
format.opaque = false
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200),format: format)
  1. Call one of the three rendering methods and provide Core Graphics drawing instructions as the closure argument to execute the rendering.

    swift
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200))
    let image = renderer.image { (context) in
        UIColor.darkGray.setStroke()
        context.stroke(renderer.format.bounds)
        UIColor(red: 158/255, green: 215/255, blue: 245/255, alpha: 1).setFill()
        context.fill(CGRect(x: 1, y: 1, width: 140, height: 140))
    }
    swift
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200))
    let jpegData = renderer.jpegData(withCompressionQuality: 0.8) { context in
        UIColor.darkGray.setStroke()
        context.stroke(renderer.format.bounds)
        UIColor(red: 158/255, green: 215/255, blue: 245/255, alpha: 1).setFill()
        context.fill(CGRect(x: 1, y: 1, width: 140, height: 140))
    }
    let image = UIImage(data: jpegData)
    swift
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 200))
    let pngData = renderer.pngData { context in
        UIColor.darkGray.setStroke()
        context.stroke(renderer.format.bounds)
        UIColor(red: 158/255, green: 215/255, blue: 245/255, alpha: 1).setFill()
        context.fill(CGRect(x: 1, y: 1, width: 140, height: 140))
    }
    let image = UIImage(data: pngData)

References