How to convert UIImage to BMP and save as Data (not JPG or PNG)
Asked Answered
T

1

3

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

Tatter answered 26/1, 2017 at 8:59 Comment(0)
C
4

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!

Clairvoyance answered 1/5, 2019 at 1:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.