27

This isn't what you probably thought it was to begin with. I know how to use UIImage's, but I now need to know how to create a "blank" UIImage using:

CGRect screenRect = [self.view bounds];

Well, those dimensions. Anyway, I want to know how I can create a UIImage with those dimensions colored all white. No actual images here.

Is this even possible? I am sure it is, but maybe I am wrong.

Edit

This needs to be a "white" image. Not a blank one. :)

Cœur
  • 37,241
  • 25
  • 195
  • 267
Josiah
  • 4,663
  • 2
  • 31
  • 49
  • curious what you need a blank image for... – nielsbot Jan 30 '13 at 00:51
  • @nielsbot, I can image you would be. I do take screenshots of my current view, and then animate it over on swipe. However, at times if memory is deallocated or if I go into history and jump to an item at a different location, then I will have no images to navigate with. I do not just want to take a screenshot, since it is full of incorrect contents. Therefore, if I detect no more screenshots, I show a blank one instead. However, I might just end up taking a picture of my view when it does not have anything in it. But we'll see. :) – Josiah Jan 30 '13 at 00:54
  • why not just have your viewer handle the case of view == nil and not draw anything? If this is in an UIView, you can use `view.backgroundColor = [ UIColor whiteColor ];` – nielsbot Jan 30 '13 at 01:11
  • @nielsbot, That was going to be my fallback plan. I really just wanted to find out if there are no images, and then just drop an image in, so the animation can work unchanged. But if I can't color my empty, I guess that is what I will do. – Josiah Jan 30 '13 at 01:21
  • but it should work the same in either case... you have a view and may or may not have an image inside it... in either case your view animations will be the same. – nielsbot Jan 30 '13 at 07:21
  • @nielsbot, That's true, I ended up basically doing that. Thanks for your help! – Josiah Jan 30 '13 at 13:20

6 Answers6

39

You need to use CoreGraphics, as follows.

CGSize size = CGSizeMake(desiredWidth, desiredHeight);
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
[[UIColor whiteColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

The code creates a new CoreGraphics image context with the options passed as parameters; size, opaqueness, and scale. By passing 0 for scale, iOS automatically chooses the appropriate value for the current device.

Then, the context fill colour is set to [UIColor whiteColor]. Immediately, the canvas is then actually filled with that color, by using UIRectFill() and passing a rectangle which fills the canvas.

A UIImage is then created of the current context, and the context is closed. Therefore, the image variable contains a UIImage of the desired size, filled white.

Benjamin Mayo
  • 6,649
  • 2
  • 26
  • 25
  • That you very much. That would do it. Unfortunately I just went ahead and used a white view, but this could still come in handy! – Josiah Jan 30 '13 at 02:28
12

Swift version:

extension UIImage {

    static func emptyImage(with size: CGSize) -> UIImage? {
        UIGraphicsBeginImageContext(size)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

}
AamirR
  • 11,672
  • 4
  • 59
  • 73
Rudolf Adamkovič
  • 31,030
  • 13
  • 103
  • 118
  • [`UIGraphicsGetImageFromCurrentImageContext()`](https://developer.apple.com/documentation/uikit/1623924-uigraphicsgetimagefromcurrentima) returns optional `UIImage` – Orkhan Alikhanov Jan 20 '18 at 14:31
  • Nice and short thanks, just had to change return type to `UIImage?` – AamirR Mar 11 '18 at 19:58
4

If you want to draw just an empty image, you could use UIKit UIImageBeginImageContextWithOptions: method.

    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    CGContextAddRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height)); // this may not be necessary
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

The code above assumes that you draw a image with a size of width x height. It adds rectangle into the graphics context, but it may not be necessary. Try it yourself. This is the way to go. :)

Or, if you want to create a snapshot of your current view you would type code like;

 UIGraphicsBeginImageContext(CGSizeMake(self.view.size.width, self.view.size.height));
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

Don't forget to include Quartz library if you use layer.

  • Thanks, but at the moment this is creating a transparent image. I need the image to be colored white. Is there a way you can do this? – Josiah Jan 30 '13 at 01:00
  • Thanks -- maybe this is a hack but I used the transparent image as a Pin.Image on a custom MKAnnotation on MKMapView. My problem was that I was adding a custom image as a subview (and not setting the pin image) so the pin remained its default size. By adding a transparent image the size of my custom subview, it was then able to catch taps correctly for the entire subview. – Timothy Lee Russell May 31 '15 at 00:07
2

Based on @HixField and @Rudolf Adamkovič answer. here's an extension which returns an optional, which I believe is the correct way to do this (correct me if I'm wrong!)?

This extension allows you to create a an empty UIImage of what ever size you need (up to memory limit) with what ever fill color you want, which defaults to white, if you want the image to be the clear color you would use something like the following:

let size = CGSize(width: 32.0, height: 32.0)
if var image = UIImage.imageWithSize(size:size, UIColor.clear) {
    //image was successfully created, do additional stuff with it here.
}

This is for swift 3.x:

extension UIImage {
     static func imageWithSize(size : CGSize, color : UIColor = UIColor.white) -> UIImage? {
         var image:UIImage? = nil
         UIGraphicsBeginImageContext(size)
         if let context = UIGraphicsGetCurrentContext() {
               context.setFillColor(color.cgColor)
               context.addRect(CGRect(origin: CGPoint.zero, size: size));
               context.drawPath(using: .fill)
               image = UIGraphicsGetImageFromCurrentImageContext();
        }
        UIGraphicsEndImageContext()
        return image
    }
}
Chucky
  • 398
  • 3
  • 15
1

Using the latest UIGraphics classes, and in swift, this looks like this (note the CGContextDrawPath that is missing in the answer from user1834305, this is the reason that is produces an transparant image) :

static func imageWithSize(size : CGSize, color : UIColor) -> UIImage {
    UIGraphicsBeginImageContext(size)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextAddRect(context, CGRect(x: 0, y: 0, width: size.width, height: size.height));
    CGContextDrawPath(context, .Fill)
    let image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image
}
HixField
  • 3,538
  • 1
  • 28
  • 54
0

Same solution in C# for Xamarin.iOS :

                UIGraphics.BeginImageContext(new CGSize(width, height));
                var image = UIGraphics.GetImageFromCurrentImageContext();
                UIGraphics.EndImageContext();
sandeepani
  • 353
  • 3
  • 12