iOS gif 图片播放实现方法 (image 扩展方案)
来源:互联网 发布:中国移动网络测速 编辑:程序博客网 时间:2024/04/29 12:26
1 image 扩展方案:
1.导入头文件
#import <ImageIO/ImageIO.h>#import <UIKit/UIKit.h>#if __has_feature(objc_arc)#define toCF (__bridge CFTypeRef)#define fromCF (__bridge id)#else#define toCF (CFTypeRef)#define fromCF (id)#endif/** UIImage (animatedGIF) This category adds class methods to `UIImage` to create an animated `UIImage` from an animated GIF.*/@interface UIImage (animatedGIF)
2.声明方法:
+ (UIImage * _Nullable)animatedImageWithAnimatedGIFData:(NSData * _Nonnull)theData;+ (UIImage * _Nullable)animatedImageWithAnimatedGIFURL:(NSURL * _Nonnull)theURL;
3.实现方法:
@implementation UIImage (animatedGIF)static int delayCentisecondsForImageAtIndex(CGImageSourceRef const source, size_t const i) { int delayCentiseconds = 1; CFDictionaryRef const properties = CGImageSourceCopyPropertiesAtIndex(source, i, NULL); if (properties) { CFDictionaryRef const gifProperties = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); if (gifProperties) { NSNumber *number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFUnclampedDelayTime); if (number == NULL || [number doubleValue] == 0) { number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime); } if ([number doubleValue] > 0) { // Even though the GIF stores the delay as an integer number of centiseconds, ImageIO “helpfully” converts that to seconds for us. delayCentiseconds = (int)lrint([number doubleValue] * 100); } } CFRelease(properties); } return delayCentiseconds;}static void createImagesAndDelays(CGImageSourceRef source, size_t count, CGImageRef imagesOut[count], int delayCentisecondsOut[count]) { for (size_t i = 0; i < count; ++i) { imagesOut[i] = CGImageSourceCreateImageAtIndex(source, i, NULL); delayCentisecondsOut[i] = delayCentisecondsForImageAtIndex(source, i); }}static int sum(size_t const count, int const *const values) { int theSum = 0; for (size_t i = 0; i < count; ++i) { theSum += values[i]; } return theSum;}static int pairGCD(int a, int b) { if (a < b) return pairGCD(b, a); while (true) { int const r = a % b; if (r == 0) return b; a = b; b = r; }}static int vectorGCD(size_t const count, int const *const values) { int gcd = values[0]; for (size_t i = 1; i < count; ++i) { // Note that after I process the first few elements of the vector, `gcd` will probably be smaller than any remaining element. By passing the smaller value as the second argument to `pairGCD`, I avoid making it swap the arguments. gcd = pairGCD(values[i], gcd); } return gcd;}static NSArray *frameArray(size_t const count, CGImageRef const images[count], int const delayCentiseconds[count], int const totalDurationCentiseconds) { int const gcd = vectorGCD(count, delayCentiseconds); size_t const frameCount = totalDurationCentiseconds / gcd; UIImage *frames[frameCount]; for (size_t i = 0, f = 0; i < count; ++i) { UIImage *const frame = [UIImage imageWithCGImage:images[i]]; for (size_t j = delayCentiseconds[i] / gcd; j > 0; --j) { frames[f++] = frame; } } return [NSArray arrayWithObjects:frames count:frameCount];}static void releaseImages(size_t const count, CGImageRef const images[count]) { for (size_t i = 0; i < count; ++i) { CGImageRelease(images[i]); }}static UIImage *animatedImageWithAnimatedGIFImageSource(CGImageSourceRef const source) { size_t const count = CGImageSourceGetCount(source); CGImageRef images[count]; int delayCentiseconds[count]; // in centiseconds createImagesAndDelays(source, count, images, delayCentiseconds); int const totalDurationCentiseconds = sum(count, delayCentiseconds); NSArray *const frames = frameArray(count, images, delayCentiseconds, totalDurationCentiseconds); UIImage *const animation = [UIImage animatedImageWithImages:frames duration:(NSTimeInterval)totalDurationCentiseconds / 100.0]; releaseImages(count, images); return animation;}static UIImage *animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceRef CF_RELEASES_ARGUMENT source) { if (source) { UIImage *const image = animatedImageWithAnimatedGIFImageSource(source); CFRelease(source); return image; } else { return nil; }}+ (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)data { return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithData(toCF data, NULL));}+ (UIImage *)animatedImageWithAnimatedGIFURL:(NSURL *)url { return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithURL(toCF url, NULL));}@end
2 web view 方案(todo )
使用webview 直接加载gif 直接可以播放(代码有空再帖)
3 将gif分解为N张图片(todo)
然后导入工程依次播放.(代码有空再帖)
0 0
- iOS gif 图片播放实现方法 (image 扩展方案)
- ios播放gif图片
- ios播放gif图片
- IOS播放GIF图片
- iOS 播放.GIF图片
- iOS 播放gif图片
- iOS播放Gif方案总结
- IOS 播放动态Gif图片
- iOS 中播放gif图片
- iOS播放GIF的方法
- 【代码笔记】iOS-gif图片播放
- iOS开发中实现显示gif图片的方法
- 播放GIF图片的最简单方法
- Android中播放Gif图片的方法
- Android中播放Gif图片的方法
- Windows Mobile C#实现GIF图片播放
- Android 实现播放本地GIF图片
- Android轻松实现播放Gif图片
- Hive-ORC文件存储格式
- bzoj3744 Gty的妹子序列
- emacs
- 完美解决Linux(Android)操作系统下aes解密失败的问题
- bzoj2002【HNOI2010】Bounce 弹飞绵羊
- iOS gif 图片播放实现方法 (image 扩展方案)
- (BFS)codeforces #Round354-div2-D
- <机器学习练习>EM算法
- MIPI协议的DCS指令格式
- 5.31
- poj 2828 线段树 单点更新
- android中保存Bitmap图片到指定文件夹中的方法
- LAMP的环境的搭建
- 百度地图之获取Android签名证书的sha1值