I am syncing BMP images between my iOS app (Swift 3) and an app (on MS Windows) that supports only BMP format.
BMP images created on the MS Windows app are downloaded as base64 strings, saved as Data
and displayed quite easily using some lines of code like:
let imageData = Data(base64Encoded: value)
let image = UIImage(data: imageData)
This is generating a UIImage
from downloaded BMP image and works perfectly because I cas display the image.
But I also need to create BMP images (drawn signatures) from the iOS app and for that, I'm using this library https://github.com/felipesantolim/SHFSignature, thanks to Felipe.
This library generates a UIImage
which I save as Data
and I can display it on my iOS app.
But when I send it as base64 string the problem is that se MS Windows app can't display it (format not supported, only BMP image).
Can anybody help me generate a real BMP image from a UIImage
or directly from the SHFSignature
image function?
Thanks
I needed to do the same thing - take a UIImage from iOS and save it out into a usable Windows .bmp file. I actually used it on an Adafruit PyPortal IoT device, not a Windows machine, but the technique below worked fine. Saved the data to Firebase Storage and was able to use it in the PyPortal.
I found a helpful extension here: Convert UIImage to NSData and convert back to UIImage in Swift?
I used this extension: // Note you'll need to import MobileCoreServices for the k values to be recognized
import MobileCoreServices
extension UIImage {
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}
func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}
And I called it in my code like this:
(the image I was converting was a UIImage
value named backgroundImage
that is a property of the class where the code below resides).
let options: NSDictionary = [:]
let convertToBmp = self.backgroundImage.toData(options: options, type: .bmp)
guard let bmpData = convertToBmp else {
print("😡 ERROR: could not convert image to a bitmap bmpData var.")
return
}
Cheers!