根据文件识别头信息获取图片文件的类型

一、概述

有时候单单获取图片的后缀名是无法判断该图片的类型,因此我们需要一种更准确的识别方式:读取图片数据的文件识别头。(每一个图片都由识别头+data组成)

二、一些已知的图片文件头标识

  1. JPEG
    文件头标识 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件标识)
    文件结束标识 (2 bytes): 0xff, 0xd9 (EOI)

  2. TGA
    未压缩的前5字节 00 00 02 00 00
    RLE压缩的前5字节 00 00 10 00 00

  3. PNG
    文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A

  4. GIF
    文件头标识 (6 bytes) 47 49 46 38 39(37) 61 (G I F 8 9 (7) a)

  5. BMP
    文件头标识 (2 bytes) 42 4D (B M)

  6. PCX
    文件头标识 (1 bytes) 0A

  7. TIFF
    文件头标识 (2 bytes) 4D 4D 或 49 49

  8. ICO
    文件头标识 (8 bytes) 00 00 01 00 01 00 20 20

  9. CUR
    文件头标识 (8 bytes) 00 00 02 00 01 00 20 20

  10. IFF
    文件头标识 (4 bytes) 46 4F 52 4D (F O R M)

  11. ANI
    文件头标识 (4 bytes) 52 49 46 46(R I F F)

三、代码判断

+ (NSString *)sd_contentTypeForImageData:(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 0x0A:
            return @"image/pca";
        case 0x52:
            // R as RIFF for WEBP
            if ([data length] < 12) {
                return nil;
            }
            
            NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
            if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                return @"image/webp";
            }
            
            return nil;
    }
    return nil;
  }

你可能感兴趣的:(根据文件识别头信息获取图片文件的类型)