Reputation: 5754
Suppose I have a UIImage
instance that I would like to convert into a data URI and inject into a UIWebView.
I know I can convert the UIImage to PNG/JPEG NSData
using PNGRepresentation
/JPEGRepresentation
methods. But then how do I make sure that the conversion is base64? And then how do I create a string with the actual URI and headers present?
Upvotes: 5
Views: 3506
Reputation: 311
Here's the Swift 5 version of @David Beck's answer in case if somebody need it:
extension UIImage {
func hasAlpha() -> Bool {
guard let cgImage = cgImage else {
return false
}
let alpha = cgImage.alphaInfo
return alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast
}
func dataURL() -> String? {
var imageData: Data? = nil
var mimeType: String? = nil
if hasAlpha() {
imageData = self.pngData()
mimeType = "image/png"
} else {
imageData = self.jpegData(compressionQuality: 1.0)
mimeType = "image/jpeg"
}
return "data:\(mimeType ?? "");base64,\(imageData?.base64EncodedString(options: []) ?? "")"
}
}
Upvotes: 2
Reputation: 1605
Here's an adaptation of @David Beck's answer, using Swift 4 / XCode 10.1 / iOS 12:
extension UIImage {
func hasAlpha() -> Bool {
let noAlphaCases: [CGImageAlphaInfo] = [.none, .noneSkipLast, .noneSkipFirst]
if let alphaInfo = cgImage?.alphaInfo {
return !noAlphaCases.contains(alphaInfo)
} else {
return false
}
}
func dataURI() -> String? {
var mimeType: String = ""
var imageData: Data
if hasAlpha(), let png = pngData() {
imageData = png
mimeType = "image/png"
} else if let jpg = jpegData(compressionQuality: 1.0) {
imageData = jpg
mimeType = "image/jpeg"
} else {
return nil
}
return "data:\(mimeType);base64,\(imageData.base64EncodedString())"
}
}
Upvotes: 1
Reputation: 10159
Here is a category on UIImage I use to do just that:
- (BOOL)hasAlpha
{
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
return (alpha == kCGImageAlphaFirst ||
alpha == kCGImageAlphaLast ||
alpha == kCGImageAlphaPremultipliedFirst ||
alpha == kCGImageAlphaPremultipliedLast);
}
- (NSString *)dataURL
{
NSData *imageData = nil;
NSString *mimeType = nil;
if (self.hasAlpha) {
imageData = UIImagePNGRepresentation(self);
mimeType = @"image/png";
} else {
imageData = UIImageJPEGRepresentation(self, 1.0);
mimeType = @"image/jpeg";
}
return [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [imageData base64EncodedStringWithOptions:0]];
}
This requires iOS 7 to encode the data as base64, but there are third party libraries to do the same thing.
Upvotes: 10
Reputation: 1131
Creating NSData out of it won't encode in base 64. NSData a binary data (bytes, in the range 0-255); base 64 encoding is a text encoding that uses a subset of ASCII to represent byte values. What you'll want to do is create the NSData, then use a conversion routine to encode it into a base 64 string; there's lots of references for doing that. Once you have the base64 string, use the standard methodology for inserting image data into HTML.
Upvotes: 1