在实际开发中,有时候会碰到图片类型不确定,需要判断图片类型进行其他操作,因此直接给Data做一个扩展,支持检测图片的类型。
扩展支持jpeg tiff bmp ico icns gif png webp等多种格式的图片类型判断。
从图片数据中截取第一个16进制数据,然后比对判断。
extension Data {
enum ImageType {
case unknown
case jpeg
case tiff
case bmp
case ico
case icns
case gif
case png
case webp
}
func detectImageType() -> Data.ImageType {
if self.count < 16 { return .unknown }
var value = [UInt8](repeating:0, count:1)
self.copyBytes(to: &value, count: 1)
switch value[0] {
case 0x4D, 0x49:
return .tiff
case 0x00:
return .ico
case 0x69:
return .icns
case 0x47:
return .gif
case 0x89:
return .png
case 0xFF:
return .jpeg
case 0x42:
return .bmp
case 0x52:
let subData = self.subdata(in: Range(NSMakeRange(0, 12))!)
if let infoString = String(data: subData, encoding: .ascii) {
if infoString.hasPrefix("RIFF") && infoString.hasSuffix("WEBP") {
return .webp
}
}
break
default:
break
}
return .unknown
}
static func detectImageType(with data: Data) -> Data.ImageType {
return data.detectImageType()
}
static func detectImageType(with url: URL) -> Data.ImageType {
if let data = try? Data(contentsOf: url) {
return data.detectImageType()
} else {
return .unknown
}
}
static func detectImageType(with filePath: String) -> Data.ImageType {
let pathUrl = URL(fileURLWithPath: filePath)
if let data = try? Data(contentsOf: pathUrl) {
return data.detectImageType()
} else {
return .unknown
}
}
static func detectImageType(with imageName: String, bundle: Bundle = Bundle.main) -> Data.ImageType? {
guard let path = bundle.path(forResource: imageName, ofType: "") else { return nil }
let pathUrl = URL(fileURLWithPath: path)
if let data = try? Data(contentsOf: pathUrl) {
return data.detectImageType()
} else {
return nil
}
}
}
源码地址 https://github.com/SunZhiC/DetectImageType
参考资料:
文件头标识大全 https://www.garykessler.net/library/file_sigs.html
网友评论