Get image file type programmatically in swift

好久不见. 提交于 2019-12-18 10:56:35

问题


I am downloading images from parse with file totes PNG and JPEG.

When image is downloaded to the app I need to determine what the file type is so I can handle image accordingly.

Had a look at API for uiimageview and did a search but can't find any solution in swift.

Any input appreciated

Trying to get url from PFFIle §:

let imageURLFromParse = NSURL(string : caseImageFile2.url);

// Error here: 'NSURL?' does not have a member named 'pathExtension'                   
if(imageURLFromParse.pathExtension!.lowercaseString == ".jpg" || imageURLFromParse.pathExtension.lowercaseString == ".jpeg"){

  println("Parse image ext is a jpg: \(imageURLFromParse.pathExtension.lowercaseString)");

  fileExtenion = ".jpg";

} else {                        
  println("Parse image is a png: \(imageURLFromParse.pathExtension.lowercaseString)");

  fileExtenion = ".png";                           
}

回答1:


Update for Swift 3.0.2

Based on Hoa's answer and Kingfisher library

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)

You can use this with Both local and online images.




回答2:


You have to get the first byte of your image in binary. This byte indicate which kind of image type. Here is the code that I've used for my project but in Objective-c:

uint8_t c;
        [_receivedData getBytes:&c length:1];

        NSString *extension = @"jpg";

        switch (c) {
            case 0xFF:
            {
                extension = @"jpg";
            }
            case 0x89:
            {
                extension = @"png";
            }
                break;
            case 0x47:
            {
                extension = @"gif";
            }
                break;
            case 0x49:
            case 0x4D:
            {
                extension = @"tiff";
            }
                break;
            default:
                FLog(@"unknown image type");
        }

Try with this in swift (1.2, else you have to use var ext):

func imageType(imgData : NSData) -> String
{
    var c = [UInt8](count: 1, repeatedValue: 0)
    imgData.getBytes(&c, length: 1)

    let ext : String

    switch (c[0]) {
    case 0xFF:

        ext = "jpg"

    case 0x89:

        ext = "png"
    case 0x47:

        ext = "gif"
    case 0x49, 0x4D :
        ext = "tiff"
    default:
        ext = "" //unknown
    }

    return ext
}



回答3:


I wanted to know what extension is my image after I have picked it. I used this:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
  if (!(picker.sourceType == UIImagePickerControllerSourceType.Camera)) {
    let assetPath = info[UIImagePickerControllerReferenceURL] as! NSURL
    if assetPath.absoluteString.hasSuffix("JPG") {



回答4:


You can test in project https://github.com/bonyadmitr/ImageFormat

Add to project

import Foundation

/// can be done "heic", "heix", "hevc", "hevx"
enum ImageFormat: String {
    case png, jpg, gif, tiff, webp, heic, unknown
}

extension ImageFormat {
    static func get(from data: Data) -> ImageFormat {
        switch data[0] {
        case 0x89:
            return .png
        case 0xFF:
            return .jpg
        case 0x47:
            return .gif 
        case 0x49, 0x4D:
            return .tiff 
        case 0x52 where data.count >= 12:
            let subdata = data[0...11]

            if let dataString = String(data: subdata, encoding: .ascii),
                dataString.hasPrefix("RIFF"),
                dataString.hasSuffix("WEBP")
            {    
                return .webp
            }

        case 0x00 where data.count >= 12 :
            let subdata = data[8...11]

            if let dataString = String(data: subdata, encoding: .ascii),
                Set(["heic", "heix", "hevc", "hevx"]).contains(dataString)
                ///OLD: "ftypheic", "ftypheix", "ftyphevc", "ftyphevx"
            {    
                return .heic
            }
        default:
            break
        }
        return .unknown
    } 

    var contentType: String {
        return "image/\(rawValue)"
    }
}

Using

for file in ["1.jpg", "2.png", "3.gif", "4.svg", "5.TIF", "6.webp", "7.HEIC"] {
    if let data = Data(bundleFileName: file) {
        print(file, ImageFormat.get(from: data))
    }
}

/// Result
/// 1.jpg jpg
/// 2.png png
/// 3.gif gif
/// 4.svg unknown
/// 5.TIF tiff
/// 6.webp webp
/// 7.HEIC heic



回答5:


Why not simply do the following:

let ext = NSURL(fileURLWithPath: path/of/your/file as! String).pathExtension
print(ext!)

This will give you the extension of the file.




回答6:


@XueYu's answer helped me out a lot. Heres an update for Data rather than NSData

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 Data {
    var imageFormat: ImageFormat {
        var buffer = [UInt8](repeating: 0, count: 1)
        copyBytes(to: &buffer, from: 0..<1)
        if buffer == ImageHeaderData.PNG { return .PNG }
        if buffer == ImageHeaderData.JPEG { return .JPEG }
        if buffer == ImageHeaderData.GIF { return .GIF }
        if buffer == ImageHeaderData.TIFF_01 || 
           buffer == ImageHeaderData.TIFF_02 {
            return .TIFF
        }
        return .Unknown
    }
}



回答7:


This code will use for Swift 5 And iOS 12. If we use this code we can get Documents and Images File type

import UIKit
import Photos

class ViewController {

     let imagePicker = UIImagePickerController()

     override func viewDidLoad() {
        super.viewDidLoad()

        checkPermission()
     }
}

extension ViewController : UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIDocumentPickerDelegate {

     func checkPermission() {

         let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
         switch photoAuthorizationStatus {
         case .authorized:
             print("Access is granted by user")
             accessDocsAndImages()
         case .notDetermined:
             PHPhotoLibrary.requestAuthorization({ newStatus in
                 print("status is \(newStatus)")
                 if newStatus == PHAuthorizationStatus.authorized {
                     /* do stuff here */
                     print("success")
                 }
             })
         case .restricted:
             print("User do not have access to photo album.")
         case .denied:
             print("User has denied the permission.")
         @unknown default:
             print("Defults")
         }   
     }

     func accessDocsAndImages() {

         imagePicker.allowsEditing = true
         imagePicker.delegate = self
         let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .alert)
         let openCameraAction = UIAlertAction(title: "Camera", style: .default, handler: {
             (alert: UIAlertAction!) -> Void in
             return
         })

         let openGalleryAction = UIAlertAction(title: "Open Gallery", style: .default, handler: {
             (alert: UIAlertAction!) -> Void in
             self.imagePicker.sourceType = .photoLibrary
             self.present(self.imagePicker, animated: true, completion: nil)
             print("Opened gallery")
         })
         let openDocAction = UIAlertAction(title: "Open Documents", style: .default, handler: {
             (alert: UIAlertAction!) -> Void in
             print("Opened gallery")
             let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.content", "public.item", "public.composite-content", "public.data", "public.database", "public.calendar-event", "public.message", "public.presentation", "public.contact", "public.archive", "public.disk-image", "public.text", "public.plain-text", "public.utf8-plain-text", "public.utf16-external-plain-​text", "public.utf16-plain-text", "com.apple.traditional-mac-​plain-text", "public.rtf","public.pdf", "public.movie", "public.audiovisual-content", "public.video", "public.audio"], in: .import)
             documentPicker.delegate = self
             //documentPicker.modalPresentationStyle = .formSheet
             documentPicker.allowsMultipleSelection = true
             self.present(documentPicker, animated: true, completion: nil)
         })
         let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
             (alert: UIAlertAction!) -> Void in
             print("cancelled")
         })
         optionMenu.addAction(openGalleryAction)
         optionMenu.addAction(openCameraAction)
         optionMenu.addAction(openDocAction)
         optionMenu.addAction(cancelAction)
         self.present(optionMenu, animated: true, completion: nil)
     }

     func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

         if let asset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
             let assetResources = PHAssetResource.assetResources(for: asset)

             print(assetResources.first!.originalFilename)

             if (assetResources.first!.originalFilename.hasSuffix("JPG")) {
                 print("jpg")
             } else if (assetResources.first!.originalFilename.hasSuffix("JPEG")) {
                 print("jpeg")
             } else if (assetResources.first!.originalFilename.hasSuffix("PNG")) {
                 print("png")
             } else if (assetResources.first!.originalFilename.hasSuffix("GIF")) {
                 print("gif")
             } else if (assetResources.first!.originalFilename.hasSuffix("TIFF")) {
                 print("tiff")
             } else if (assetResources.first!.originalFilename.hasSuffix("WEBP")) {
                 print("webp")
             } else if (assetResources.first!.originalFilename.hasSuffix("HEIC")) {
                 print("heic")
             } else if (assetResources.first!.originalFilename.hasSuffix("HEIX")) {
                 print("heix")
             } else if (assetResources.first!.originalFilename.hasSuffix("HEVC")) {
                 print("hevc")
             } else if (assetResources.first!.originalFilename.hasSuffix("HEVX")) {
                 print("hevx")
             } else {
                 print("Unknown")
             }
         }
         dismiss(animated: true, completion: nil)
     }

     private func imagePickerControllerDidCancel(picker: UIImagePickerController) {

         dismiss(animated: true, completion: nil)
     }

     func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {

         print(url)
     }

     func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {

         let cico = urls[0] as URL
         print(cico)
         print(urls[0])
         print(urls[0].lastPathComponent)
         print(urls[0].pathExtension)
         let urlWithoutFileExtension: URL =  urls[0].deletingPathExtension()
         let fileNameWithoutExtension: String = urlWithoutFileExtension.lastPathComponent
         print(fileNameWithoutExtension)
         dismiss(animated: true, completion: nil)
     }

     func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {

         print(" cancelled by user")

     }
 }


来源:https://stackoverflow.com/questions/29644168/get-image-file-type-programmatically-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!