How to get Image extension/format from UIImage in swift?

14,636

Solution 1

You can try this:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
    let assetPath = info[UIImagePickerControllerReferenceURL] as! NSURL
    if (assetPath.absoluteString?.hasSuffix("JPG"))! {
        print("JPG")
    }
    else if (assetPath.absoluteString?.hasSuffix("PNG"))! {
        print("PNG")
    }
    else if (assetPath.absoluteString?.hasSuffix("GIF"))! {
        print("GIF")
    }
    else {
        print("Unknown")
    }
}

Solution 2

You need to cover the image to raw data, probably using UIImagePNGRepresentation() or UIImageJPEGRepresentation(), then send THAT up to your server. That data will be in either PNG or JPEG format, respectively.

Solution 3

If preferred using URL, In swift 5.2 you can use

enum ImageFormat {
    case png
    case jpeg
    case gif
    case tiff
    case unknown
    
    init(byte: UInt8) {
        switch byte {
        case 0x89:
            self = .png
        case 0xFF:
            self = .jpeg
        case 0x47:
            self = .gif
        case 0x49, 0x4D:
            self = .tiff
        default:
            self = .unknown
        }
    }
}

extension Data {
    var imageFormat: ImageFormat{
        guard let header = map({ $0 as UInt8 })[safe: 0] else {
            return .unknown
        }
        
        return ImageFormat(byte: header)
    }
}

extension Collection {
    
    /// Returns the element at the specified index iff it is within bounds, otherwise nil.
    /// - Parameters:
    ///   - Parameter index: The index of the item to get safely the element
    /// - Returns: The element if available or nil otherwise
    subscript(safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
    
}

I found that:

jpegData(compressionQuality: CGFloat)
pngData()

Always succeed and it's not memory efficient. In one case I saw an image of 1.6Mb becoming 6MB just because of pngData()

Share:
14,636
Alexa289
Author by

Alexa289

Updated on June 27, 2022

Comments

  • Alexa289
    Alexa289 almost 2 years

    I am trying to upload an image to my server, but before uploading, i need to check whether it is valid format or not.

    let say i only want .jpeg and .png only, so if the users pick .gif format image from their phone, I will show some alert.

    I get the image from the user gallery/camera, and then I want to check the format, but I don't know how to check the format

    @IBAction func selectPictureButtonDidPressed(_ sender: Any) {
        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.allowsEditing = true
        
        let actionSheet = UIAlertController(title: "Photo Source", message: "please choose your source", preferredStyle: .actionSheet)
        
        // action camera
        let actionCamera = UIAlertAction(title: "Camera", style: .default) { (action) in
            if UIImagePickerController.isSourceTypeAvailable(.camera) {
                imagePickerController.sourceType = .camera
                self.present(imagePickerController, animated: true, completion: nil)
            } else {
                self.showAlert(alertTitle: "Opppss", alertMessage: "camera can't be used / not available", actionTitle: "OK")
                print("camera can't be used / not available")
            }
        }
        
        // action photo library
        let actionPhotoLibrary = UIAlertAction(title: "Photo Library", style: .default) { (action) in
            imagePickerController.sourceType = .photoLibrary
            self.present(imagePickerController, animated: true, completion: nil)
        }
        
        //action cancel
        let actionCancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        
        actionSheet.addAction(actionCamera)
        actionSheet.addAction(actionPhotoLibrary)
        actionSheet.addAction(actionCancel)
        
        self.present(actionSheet, animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        postImage.image = image
        picker.dismiss(animated: true, completion: nil)
        
        doesItHasImage = true
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    

    How do I check that format?

    i have tried to find on google, but I just get the image format if it is derived from an URL. not directly from UIImage like this

    import UIKit
    import ImageIO
    
    struct ImageHeaderData{
        static var PNG: [UInt8] = [0x89]
        static var JPEG: [UInt8] = [0xFF]
        static var GIF: [UInt8] = [0x47]
        static var TIFF_01: [UInt8] = [0x49]
        static var TIFF_02: [UInt8] = [0x4D]
    }
    
    enum ImageFormat{
        case Unknown, PNG, JPEG, GIF, TIFF
    }
    
    extension NSData{
        var imageFormat: ImageFormat{
            var buffer = [UInt8](repeating: 0, count: 1)
            self.getBytes(&buffer, range: NSRange(location: 0,length: 1))
            if buffer == ImageHeaderData.PNG
            {
                return .PNG
            } else if buffer == ImageHeaderData.JPEG
            {
                return .JPEG
            } else if buffer == ImageHeaderData.GIF
            {
                return .GIF
            } else if buffer == ImageHeaderData.TIFF_01 || buffer == ImageHeaderData.TIFF_02{
                return .TIFF
            } else{
                return .Unknown
            }
        }
    }
    
    // USAGE
    let imageURLFromParse = NSURL(string : "https://i.stack.imgur.com/R64uj.jpg")
    let imageData = NSData(contentsOf: imageURLFromParse! as URL)
    print(imageData!.imageFormat)