Kingfisher图片格式判断
Kingfisher
中有图片格式化文件(ImageFormat.swift
),源码如下
/// Represents image format.
///
/// - unknown: The format cannot be recognized or not supported yet.
/// - PNG: PNG image format.
/// - JPEG: JPEG image format.
/// - GIF: GIF image format.
public enum ImageFormat {
/// The format cannot be recognized or not supported yet.
case unknown
/// PNG image format.
case PNG
/// JPEG image format.
case JPEG
/// GIF image format.
case GIF
struct HeaderData {
static var PNG: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]
static var JPEG_SOI: [UInt8] = [0xFF, 0xD8]
static var JPEG_IF: [UInt8] = [0xFF]
static var GIF: [UInt8] = [0x47, 0x49, 0x46]
}
}
extension Data: KingfisherCompatible {}
// MARK: - Misc Helpers
extension KingfisherWrapper where Base == Data {
/// Gets the image format corresponding to the data.
public var imageFormat: ImageFormat {
// 创建数组,拥有8个元素其值为0
var buffer = [UInt8](repeating: 0, count: 8)
// 获取Data前8个字节
(base as NSData).getBytes(&buffer, length: 8)
if buffer == ImageFormat.HeaderData.PNG {
return .PNG
} else if buffer[0] == ImageFormat.HeaderData.JPEG_SOI[0] &&
buffer[1] == ImageFormat.HeaderData.JPEG_SOI[1] &&
buffer[2] == ImageFormat.HeaderData.JPEG_IF[0]
{
return .JPEG
} else if buffer[0] == ImageFormat.HeaderData.GIF[0] &&
buffer[1] == ImageFormat.HeaderData.GIF[1] &&
buffer[2] == ImageFormat.HeaderData.GIF[2]
{
return .GIF
}
return .unknown
}
}
对于上面的代码,实现很简单:
使用枚举ImageFormat
指定图片的类型为unknown
、 PNG
、JPEG
、GIF
四种类型,在枚举类型中嵌套HeaderData
结构体,该结构体拥有PNG
、JPEG_SOI
、JPEG_IF
、GIF
四个静态属性,每个属性都是一个数组,拥有对应数量的十六进制数值
接下来就是扩展Data
,添加imageFormat
属性值获取图片对应的类型,类型判断的依据是看Data
中前几个字节是否一样,因为每种图片都含有固定的头信息块,前8位是存储图片格式的:
PNG
是:89 50 4E 47 0D 0A 1A 0A
JPEG
是:FF D8 FF
GIF
是:47, 49, 46
tiff
是:49或4D
如果想自己实现也很简单,扩展Data
public extension Data {
var fileExtension: String {
var values = [UInt8](repeating:0, count:1)
self.copyBytes(to: &values, count: 1)
let ext: String
switch (values[0]) {
case 0xFF:
ext = ".jpg"
case 0x89:
ext = ".png"
case 0x47:
ext = ".gif"
case 0x49, 0x4D :
ext = ".tiff"
default:
ext = ".png"
}
return ext
}
}
Finding image type from NSData or UIImage
SDWebImage图片类型
实现方式一致,类型相对全面一些
/**
*
* 根据图片数据获取图片的原始类型
*
* @param data 图片的二进制数据
* @return 图片的实际格式
*/
- (NSString *)typeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
case 0x89:
return @"image/png";
case 0x47:
return @"image/gif";
case 0x49:
case 0x4D:
return @"image/tiff";
case 0x52: {
//R as RIFF for WEBP
if (data.length < 12) {
return nil;
}
NSString *identifierTypeStr = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([identifierTypeStr hasPrefix:@"RIFF"] && [identifierTypeStr hasSuffix:@"WEBP"]) {
return @"image/webp";
}
return nil;
}
default:
break;
}
return nil;
}
相关内容
- 苹果支持的图片类型
png
格式是官方最推荐使用的图片格式
- 常用格式的简单介绍
JPEG
JPEG
是目前最常见的图片格式,它诞生于1992年,是一个很古老的格式。它只支持有损压缩,其压缩算法可以精确控制压缩比,以图像质量换得存储空间。由于它太过常见,以至于许多移动设备的 CPU 都支持针对它的硬编码与硬解码。
PNG
PNG
诞生在 1995 年,比JPEG晚几年。它本身的设计目的是替代 GIF 格式,所以它与 GIF 有更多相似的地方。PNG 只支持无损压缩,所以它的压缩比是有上限的。相对于 JPEG 和 GIF 来说,它最大的优势在于支持完整的透明通道。
GIF
GIF
诞生于 1987 年,随着初代互联网流行开来。它有很多缺点,比如通常情况下只支持 256 种颜色、透明通道只有 1 bit、文件压缩比不高。它唯一的优势就是支持多帧动画,凭借这个特性,它得以从 Windows 1.0 时代流行至今,而且仍然大受欢迎。
BMP
BMP
(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备有向量相关位图(DDB)和设备无向量相关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。
WebP
WebP
是 Google 在 2010 年发布的图片格式,希望以更高的压缩比替代 JPEG。它用 VP8 视频帧内编码作为其算法基础,取得了不错的压缩效果。它支持有损和无损压缩、支持完整的透明通道、也支持多帧动画,并且没有版权问题,是一种非常理想的图片格式。借由 Google 在网络世界的影响力,WebP 在几年的时间内已经得到了广泛的应用。看看你手机里的 App:微博、微信、QQ、淘宝、网易新闻等等,每个 App 里都有 WebP 的身影。Facebook 则更进一步,用 WebP 来显示聊天界面的贴纸动画。
网友评论