美文网首页
Kingfisher - 图片的格式(ImageFormat)

Kingfisher - 图片的格式(ImageFormat)

作者: Longshihua | 来源:发表于2019-05-06 14:49 被阅读0次

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指定图片的类型为unknownPNGJPEGGIF四种类型,在枚举类型中嵌套HeaderData结构体,该结构体拥有PNGJPEG_SOIJPEG_IFGIF四个静态属性,每个属性都是一个数组,拥有对应数量的十六进制数值

接下来就是扩展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;
}

SDWebImage

相关内容

  • 苹果支持的图片类型

png格式是官方最推荐使用的图片格式

屏幕快照 2019-05-05 下午5.47.10.png

Supported Image Formats

  • 常用格式的简单介绍

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 来显示聊天界面的贴纸动画。

参考

移动端图片格式调研

相关文章

网友评论

      本文标题:Kingfisher - 图片的格式(ImageFormat)

      本文链接:https://www.haomeiwen.com/subject/jmyhoqtx.html