You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
8.7 KiB
220 lines
8.7 KiB
// |
|
// KJBannerTool.m |
|
// KJBannerViewDemo |
|
// |
|
// Created by 杨科军 on 2019/7/30. |
|
// Copyright © 2019 杨科军. All rights reserved. |
|
// |
|
|
|
#import "KJBannerTool.h" |
|
#import <CommonCrypto/CommonDigest.h> |
|
|
|
@implementation KJBannerDatasInfo |
|
|
|
- (void)setImageUrl:(NSString *)imageUrl{ |
|
_imageUrl = imageUrl; |
|
switch (_superType) { |
|
case 0:{ // 混合,本地图片、网络图片、网络GIF |
|
//1.判断是本地还是网络 |
|
if ([KJBannerTool kj_bannerImageWithImageUrl:_imageUrl] == YES) { /// 本地图片 |
|
_type = KJBannerImageInfoTypeLocality; |
|
_image = [UIImage imageNamed:_imageUrl]; |
|
}else{ |
|
//2.判断是GIF还是网络图片 |
|
if ([KJBannerTool kj_bannerIsGifWithURL:_imageUrl] == YES) { |
|
_image = [KJBannerTool kj_bannerGetImageWithURL:_imageUrl]; |
|
_type = KJBannerImageInfoTypeGIFImage; |
|
}else{ |
|
//3.网络图片 |
|
_type = KJBannerImageInfoTypeNetIamge; |
|
} |
|
} |
|
} |
|
break; |
|
case 1:{ // 网络GIF和网络图片混合 |
|
if ([KJBannerTool kj_bannerIsGifWithURL:_imageUrl] == YES) { |
|
_image = [KJBannerTool kj_bannerGetImageWithURL:_imageUrl]; |
|
_type = KJBannerImageInfoTypeGIFImage; |
|
}else{ |
|
//3.网络图片 |
|
_type = KJBannerImageInfoTypeNetIamge; |
|
} |
|
} |
|
break; |
|
case 2:{ // 本地图片 |
|
_type = KJBannerImageInfoTypeLocality; |
|
_image = [UIImage imageNamed:_imageUrl]; |
|
} |
|
break; |
|
case 3:{ // 网络图片 |
|
_type = KJBannerImageInfoTypeNetIamge; |
|
} |
|
break; |
|
case 4:{ // 网络GIF图片 |
|
_image = [KJBannerTool kj_bannerGetImageWithURL:_imageUrl]; |
|
_type = KJBannerImageInfoTypeGIFImage; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
|
|
#pragma mark - 内部方法 |
|
/// 本地GIF和本地图片 |
|
- (void)kj_ImageLociaWithURL:(NSString*)imageUrl{ |
|
//2.判断是否为本地的gif |
|
if ([KJBannerTool kj_bannerIsGifImageWithImageName:imageUrl] == NO) { |
|
|
|
} |
|
} |
|
|
|
@end |
|
|
|
@implementation KJBannerTool |
|
|
|
+ (instancetype)sharedInstance { |
|
static dispatch_once_t onceToken; |
|
static id _sharedInstance; |
|
dispatch_once(&onceToken, ^{ |
|
_sharedInstance = [[self alloc] init]; |
|
}); |
|
return _sharedInstance; |
|
} |
|
|
|
/** 判断该字符串是不是一个有效的URL */ |
|
+ (BOOL)kj_bannerValidUrl:(NSString*)url{ |
|
NSString *regex = @"[a-zA-z]+://[^\\s]*"; |
|
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex]; |
|
return [urlTest evaluateWithObject:url]; |
|
} |
|
/** 根据图片名 判断是否是gif图 */ |
|
+ (BOOL)kj_bannerIsGifImageWithImageName:(NSString*)imageName{ |
|
NSString *ext = imageName.pathExtension.lowercaseString; |
|
return [ext isEqualToString:@"gif"] ? YES : NO; |
|
} |
|
/** 根据图片url 判断是否是gif图 */ |
|
+ (BOOL)kj_bannerIsGifWithURL:(id)url{ |
|
if (![url isKindOfClass:[NSURL class]]) { |
|
url = [NSURL URLWithString:url]; |
|
} |
|
NSData *data = [NSData dataWithContentsOfURL:url]; |
|
return [self contentTypeWithImageData:data] == KJBannerImageTypeGif ? YES : NO; |
|
} |
|
/// 根据image的data 判断图片类型 |
|
+ (KJBannerImageType)contentTypeWithImageData:(NSData *)data { |
|
uint8_t c; |
|
[data getBytes:&c length:1]; |
|
switch (c) { |
|
case 0xFF: |
|
return KJBannerImageTypeJpeg; |
|
case 0x89: |
|
return KJBannerImageTypePng; |
|
case 0x47: |
|
return KJBannerImageTypeGif; |
|
case 0x49: |
|
case 0x4D: |
|
return KJBannerImageTypeTiff; |
|
case 0x52: |
|
if ([data length] < 12) return KJBannerImageTypeUnknown; |
|
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; |
|
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) return KJBannerImageTypeWebp; |
|
return KJBannerImageTypeUnknown; |
|
} |
|
return KJBannerImageTypeUnknown; |
|
} |
|
|
|
/// 判断是网络图片还是本地 |
|
+ (BOOL)kj_bannerImageWithImageUrl:(NSString*)imageUrl{ |
|
return ([imageUrl hasPrefix:@"http"] || [imageUrl hasPrefix:@"https"]) ? NO : YES; |
|
} |
|
/// 播放网络Gif |
|
+ (NSTimeInterval)kj_bannerPlayGifWithImageView:(UIImageView*)imageView URL:(id)url{ |
|
if (![url isKindOfClass:[NSURL class]]) url = [NSURL URLWithString:url]; |
|
NSData *data = [NSData dataWithContentsOfURL:url]; |
|
CGImageSourceRef imageSource = CGImageSourceCreateWithData(CFBridgingRetain(data), nil); |
|
size_t imageCount = CGImageSourceGetCount(imageSource); |
|
NSMutableArray *images = [NSMutableArray array]; |
|
NSTimeInterval totalDuration = 0; |
|
for (int i = 0; i<imageCount; i++) { |
|
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(imageSource, i, nil); |
|
UIImage *image = [UIImage imageWithCGImage:cgImage]; |
|
[images addObject:image]; |
|
NSDictionary *properties = (__bridge_transfer NSDictionary*)CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil); |
|
NSDictionary *gifDict = [properties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary]; |
|
NSNumber *frameDuration = [gifDict objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime]; |
|
totalDuration += frameDuration.doubleValue; |
|
} |
|
imageView.animationImages = images; |
|
imageView.animationDuration = totalDuration; |
|
imageView.animationRepeatCount = 0; |
|
[imageView startAnimating]; |
|
return totalDuration; |
|
} |
|
// 获取网络GIF图 |
|
+ (UIImage*)kj_bannerGetImageWithURL:(id)url{ |
|
if (![url isKindOfClass:[NSURL class]]) url = [NSURL URLWithString:url]; |
|
NSData *data = [NSData dataWithContentsOfURL:url]; |
|
CGImageSourceRef imageSource = CGImageSourceCreateWithData(CFBridgingRetain(data), nil); |
|
size_t imageCount = CGImageSourceGetCount(imageSource); |
|
UIImage *animatedImage; |
|
if (imageCount <= 1) { |
|
animatedImage = [[UIImage alloc] initWithData:data]; |
|
}else{ |
|
NSMutableArray *images = [NSMutableArray array]; |
|
NSTimeInterval totalDuration = 0; |
|
CGImageRef cgImage = NULL; |
|
for (int i = 0; i<imageCount; i++) { |
|
cgImage = CGImageSourceCreateImageAtIndex(imageSource,i,nil); |
|
[images addObject:[UIImage imageWithCGImage:cgImage]]; |
|
NSDictionary *properties = (__bridge_transfer NSDictionary*)CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil); |
|
NSDictionary *gifDict = [properties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary]; |
|
NSNumber *frameDuration = [gifDict objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime]; |
|
totalDuration += frameDuration.doubleValue; |
|
} |
|
animatedImage = [UIImage animatedImageWithImages:images duration:totalDuration]; |
|
CGImageRelease(cgImage); |
|
images = nil; |
|
} |
|
CFRelease(imageSource); |
|
return animatedImage; |
|
} |
|
/// 保存gif在本地 |
|
+ (void)kj_bannerSaveWithImage:(UIImage*)image URL:(id)url{ |
|
NSString *directoryPath = KJBannerLoadImages; |
|
if (![[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:nil]) { |
|
NSError *error = nil; |
|
[[NSFileManager defaultManager] createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&error]; |
|
if (error) return; |
|
} |
|
if ([url isKindOfClass:[NSURL class]]) url = [url absoluteString]; |
|
NSString *name = [self kj_bannerMD5WithString:url]; |
|
NSString *path = [directoryPath stringByAppendingPathComponent:name]; |
|
NSData *data = UIImagePNGRepresentation(image); |
|
if (data) [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil]; |
|
} |
|
/// 从 File 当中获取Gif文件 |
|
+ (UIImage*)kj_bannerGetImageInFileWithURL:(id)url{ |
|
if ([url isKindOfClass:[NSURL class]]) url = [url absoluteString]; |
|
NSString *directoryPath = KJBannerLoadImages; |
|
NSString *name = [KJBannerTool kj_bannerMD5WithString:url]; |
|
NSString *path = [directoryPath stringByAppendingPathComponent:name]; |
|
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path]; |
|
NSData *fileData = [handle readDataToEndOfFile]; |
|
[handle closeFile]; |
|
return [[UIImage alloc]initWithData:fileData]; |
|
} |
|
/// md5加密 |
|
+ (NSString*)kj_bannerMD5WithString:(NSString*)string{ |
|
const char *original_str = [string UTF8String]; |
|
unsigned char digist[CC_MD5_DIGEST_LENGTH]; |
|
CC_MD5(original_str, (uint)strlen(original_str), digist); |
|
NSMutableString *outPutStr = [NSMutableString stringWithCapacity:10]; |
|
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++){ |
|
[outPutStr appendFormat:@"%02X", digist[i]]; |
|
} |
|
return [outPutStr lowercaseString]; |
|
} |
|
|
|
@end |
|
|
|
|