Search code examples
iosswiftuiimagebase64cgpath

Drawing a UIBezierPath to UIImage to Base64 Image not working in Swift


I created some code to create a UIBezierPath within a UIImage context. Then take the image and create a base64 string. I believe I am supposed to draw the path within the beginning and end of the UIImage. However after many hours, it is not working. I am copying the base64 string to a website to download the image to see if it works. I am writing this in playground:

import Foundation
import UIKit


UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
let image = UIGraphicsGetImageFromCurrentImageContext()

UIColor.blackColor().setStroke()
let path = UIBezierPath()
path.lineWidth = 2
path.moveToPoint(CGPointMake(100, 0))

path.addLineToPoint(CGPointMake(200, 40))
path.addLineToPoint(CGPointMake(160, 140))
path.addLineToPoint(CGPointMake(40, 140))
path.addLineToPoint(CGPointMake(0, 40))
path.closePath()

UIGraphicsEndImageContext();
let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)

The resulting PNG is 1000x1000 I am guessing because of my retina display. The image itself is completely transparent and nothing is visible. I am using this site to decode base64 and save a file, I've tried 2 others to see if it was the site. http://www.motobit.com/util/base64-decoder-encoder.asp

EDIT I just tried the following code to see if the issue with with my image or bezier or saving to bas64. This code worked great. So I think it's a problem with my bezier.

import Foundation
import UIKit

let image = UIImage(data: NSData(contentsOfURL: NSURL(string: "http://i.imgur.com/crr4m48.jpg")!)!)!

let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)

Solution

  • It looks like you're doing things out of order. For example:

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    

    Why are you getting image before you draw anything into the graphics context? I think you're going to get an empty image -- it's not like the image you get at the outset will change as you draw things in the context. Wait to get the image until after you finish all your drawing. Also, the docs for that function say:

    You should call this function only when a bitmap-based graphics context is the current graphics context. If the current context is nil or was not created by a call to UIGraphicsBeginImageContext, this function returns nil.

    So, make sure that you've satisfied that requirement and that the image you get back when you do call UIGraphicsBeginImageContext() is not nil.

    Next, you're creating a bezier path:

    let path = UIBezierPath()
    path.lineWidth = 2
    path.moveToPoint(CGPointMake(100, 0))
    path.addLineToPoint(CGPointMake(200, 40))
    //...
    

    but in order for that path to actually be drawn in your context, you have to do something that draws, such as calling path.fill() or path.stroke(). I don't see that anywhere, so even if you fix the first problem above, you're still going to end up with an empty image until you do some drawing.