/// Detect a data's image type by reading the data's header 16 bytes (very fast).
CG_EXTERN YYImageType YYImageDetectType(CFDataRef data);
/// Convert YYImageType to UTI (such as kUTTypeJPEG).
CG_EXTERN CFStringRef _Nullable YYImageTypeToUTType(YYImageType type);
/// Convert UTI (such as kUTTypeJPEG) to YYImageType.
CG_EXTERN YYImageType YYImageTypeFromUTType(CFStringRef uti);
/// Get image type's file extension (such as @"jpg").
CG_EXTERN NSString *_Nullable YYImageTypeGetExtension(YYImageType type);
YYImageType YYImageDetectType(CFDataRef data) {
if (!data) return YYImageTypeUnknown;
uint64_t length = CFDataGetLength(data);
if (length < 16) return YYImageTypeUnknown;
const char *bytes = (char *)CFDataGetBytePtr(data);
uint32_t magic4 = *((uint32_t *)bytes);
switch (magic4) {
case YY_FOUR_CC(0x4D, 0x4D, 0x00, 0x2A): { // big endian TIFF
return YYImageTypeTIFF;
} break;
case YY_FOUR_CC(0x49, 0x49, 0x2A, 0x00): { // little endian TIFF
return YYImageTypeTIFF;
} break;
case YY_FOUR_CC(0x00, 0x00, 0x01, 0x00): { // ICO
return YYImageTypeICO;
} break;
case YY_FOUR_CC(0x00, 0x00, 0x02, 0x00): { // CUR
return YYImageTypeICO;
} break;
case YY_FOUR_CC('i', 'c', 'n', 's'): { // ICNS
return YYImageTypeICNS;
} break;
case YY_FOUR_CC('G', 'I', 'F', '8'): { // GIF
return YYImageTypeGIF;
} break;
case YY_FOUR_CC(0x89, 'P', 'N', 'G'): { // PNG
uint32_t tmp = *((uint32_t *)(bytes + 4));
if (tmp == YY_FOUR_CC('\r', '\n', 0x1A, '\n')) {
return YYImageTypePNG;
}
} break;
case YY_FOUR_CC('R', 'I', 'F', 'F'): { // WebP
uint32_t tmp = *((uint32_t *)(bytes + 8));
if (tmp == YY_FOUR_CC('W', 'E', 'B', 'P')) {
return YYImageTypeWebP;
}
} break;
/*
case YY_FOUR_CC('B', 'P', 'G', 0xFB): { // BPG
return YYImageTypeBPG;
} break;
*/
}
uint16_t magic2 = *((uint16_t *)bytes);
switch (magic2) {
case YY_TWO_CC('B', 'A'):
case YY_TWO_CC('B', 'M'):
case YY_TWO_CC('I', 'C'):
case YY_TWO_CC('P', 'I'):
case YY_TWO_CC('C', 'I'):
case YY_TWO_CC('C', 'P'): { // BMP
return YYImageTypeBMP;
}
case YY_TWO_CC(0xFF, 0x4F): { // JPEG2000
return YYImageTypeJPEG2000;
}
}
// JPG FF D8 FF
if (memcmp(bytes,"\377\330\377",3) == 0) return YYImageTypeJPEG;
// JP2
if (memcmp(bytes + 4, "\152\120\040\040\015", 5) == 0) return YYImageTypeJPEG2000;
return YYImageTypeUnknown;
}
CFStringRef YYImageTypeToUTType(YYImageType type) {
switch (type) {
case YYImageTypeJPEG: return kUTTypeJPEG;
case YYImageTypeJPEG2000: return kUTTypeJPEG2000;
case YYImageTypeTIFF: return kUTTypeTIFF;
case YYImageTypeBMP: return kUTTypeBMP;
case YYImageTypeICO: return kUTTypeICO;
case YYImageTypeICNS: return kUTTypeAppleICNS;
case YYImageTypeGIF: return kUTTypeGIF;
case YYImageTypePNG: return kUTTypePNG;
default: return NULL;
}
}
YYImageType YYImageTypeFromUTType(CFStringRef uti) {
static NSDictionary *dic;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dic = @{(id)kUTTypeJPEG : @(YYImageTypeJPEG),
(id)kUTTypeJPEG2000 : @(YYImageTypeJPEG2000),
(id)kUTTypeTIFF : @(YYImageTypeTIFF),
(id)kUTTypeBMP : @(YYImageTypeBMP),
(id)kUTTypeICO : @(YYImageTypeICO),
(id)kUTTypeAppleICNS : @(YYImageTypeICNS),
(id)kUTTypeGIF : @(YYImageTypeGIF),
(id)kUTTypePNG : @(YYImageTypePNG)};
});
if (!uti) return YYImageTypeUnknown;
NSNumber *num = dic[(__bridge __strong id)(uti)];
return num.unsignedIntegerValue;
}
NSString *YYImageTypeGetExtension(YYImageType type) {
switch (type) {
case YYImageTypeJPEG: return @"jpg";
case YYImageTypeJPEG2000: return @"jp2";
case YYImageTypeTIFF: return @"tiff";
case YYImageTypeBMP: return @"bmp";
case YYImageTypeICO: return @"ico";
case YYImageTypeICNS: return @"icns";
case YYImageTypeGIF: return @"gif";
case YYImageTypePNG: return @"png";
case YYImageTypeWebP: return @"webp";
default: return nil;
}
}
YYImage 图片格式代码节选
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 背景 图片文件我们常常在日常生活中都会使用,与我们的生活息息相关。你有没有想过,图片文件不同格式之间有什么差别吗?...
- 我们通常在办公中使用最多的就是WPS和office两款软件,就比如说在在WPS软件中办公,然后保存的文件就是以WP...