9

I've looked around everywhere, but I can't find a way to do this. I need to create a black UIImage of a certain width and height (The width and height change, so I can't just create a black box and then load it into a UIImage). Is there some way to make a CGRect and then convert it to a UIImage? Or is there some other way to make a simple black box?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
sinθ
  • 11,093
  • 25
  • 85
  • 121
  • 1
    If you just need a black box, create a `UIView` using your `CGRect` for the `frame`, set the `backgroundColor` to `[UIColor blackColor]`, and then add this new `UIView` to your existing view (e.g. `self.view` if doing this from a controller), using `addSubview`. – Rob Apr 14 '13 at 19:38
  • Closely related: [For swaths of color, which is cheaper, UIView or UIImage?](http://stackoverflow.com/q/13885588) See also: [Overlaying a UIImage with a color](http://stackoverflow.com/q/845278), which has [an answer](http://stackoverflow.com/a/10620128/603977) that tells you how to do what you're asking for. – jscs Apr 14 '13 at 19:42

5 Answers5

25

Depending on your situation, you could probably just use a UIView with its backgroundColor set to [UIColor blackColor]. Also, if the image is solidly-colored, you don't need an image that's actually the dimensions you want to display it at; you can just scale a 1x1 pixel image to fill the necessary space (e.g., by setting the contentMode of a UIImageView to UIViewContentModeScaleToFill).

Having said that, it may be instructive to see how to actually generate such an image:

Objective-C

CGSize imageSize = CGSizeMake(64, 64);
UIColor *fillColor = [UIColor blackColor];
UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[fillColor setFill];
CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Swift

let imageSize = CGSize(width: 420, height: 120)
let color: UIColor = .black
UIGraphicsBeginImageContextWithOptions(imageSize, true, 0)
let context = UIGraphicsGetCurrentContext()!
color.setFill()
context.fill(CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
Maetschl
  • 1,330
  • 14
  • 23
warrenm
  • 31,094
  • 6
  • 92
  • 116
6
UIGraphicsBeginImageContextWithOptions(CGSizeMake(w,h), NO, 0);
UIBezierPath* p =
    [UIBezierPath bezierPathWithRect:CGRectMake(0,0,w,h)];
[[UIColor blackColor] setFill];
[p fill];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Now im is the image.

That code comes almost unchanged from this section of my book: http://www.apeth.com/iOSBook/ch15.html#_graphics_contexts

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Solid. The only thing I would change is that `opaque` can be set to `YES` since we're presumably drawing an opaque color into the context. – warrenm Apr 14 '13 at 19:53
  • Actually if you set `opaque` to YES I think you don't even have to draw the black filled rectangle! :) An opaque graphics context *is* black. – matt Apr 14 '13 at 19:58
  • Good catch. I wonder if that's documented anywhere or if it's just an implementation quirk. – warrenm Apr 14 '13 at 22:07
  • It's documented in my book so I hope it's *not* an implementation quirk! – matt Apr 14 '13 at 22:08
3

Swift 3:

func uiImage(from color:UIColor?, size:CGSize) -> UIImage? {

    UIGraphicsBeginImageContextWithOptions(size, true, 0)
    defer {
        UIGraphicsEndImageContext()
    }

    let context = UIGraphicsGetCurrentContext()
    color?.setFill()
    context?.fill(CGRect.init(x: 0, y: 0, width: size.width, height: size.height))
    return UIGraphicsGetImageFromCurrentImageContext()
}
bradkratky
  • 1,577
  • 1
  • 14
  • 28
2

Like this

let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
      UIColor.black.setFill()
      UIRectFill(bounds)
}

As quoted in this WWDC vid

There's another function that's older; UIGraphicsBeginImageContext. But please, don't use that.

Bowdus
  • 33
  • 3
0

Here is an example that creates a black UIImage that is 1920x1080 by creating it from a CGImage created from a CIImage:

let frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 1920, height: 1080))
let cgImage = CIContext().createCGImage(CIImage(color: .black()), from: frame)!
let uiImage = UIImage(cgImage: cgImage)
Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86