iOS之UIImage的三中读取方法
来源:互联网 发布:软件系统安全架构 编辑:程序博客网 时间:2024/05/16 06:58
首先在项目中导入创建这个UIImage的分类
【UIImage+animatedGIF.h】
#import <UIKit/UIKit.h>/** UIImage (animatedGIF) This category adds class methods to `UIImage` to create an animated `UIImage` from an animated GIF.*/@interface UIImage (animatedGIF)/* UIImage *animation = [UIImage animatedImageWithAnimatedGIFData:theData]; I interpret `theData` as a GIF. I create an animated `UIImage` using the source images in the GIF. The GIF stores a separate duration for each frame, in units of centiseconds (hundredths of a second). However, a `UIImage` only has a single, total `duration` property, which is a floating-point number. To handle this mismatch, I add each source image (from the GIF) to `animation` a varying number of times to match the ratios between the frame durations in the GIF. For example, suppose the GIF contains three frames. Frame 0 has duration 3. Frame 1 has duration 9. Frame 2 has duration 15. I divide each duration by the greatest common denominator of all the durations, which is 3, and add each frame the resulting number of times. Thus `animation` will contain frame 0 3/3 = 1 time, then frame 1 9/3 = 3 times, then frame 2 15/3 = 5 times. I set `animation.duration` to (3+9+15)/100 = 0.27 seconds.*/+ (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)theData;/* UIImage *image = [UIImage animatedImageWithAnimatedGIFURL:theURL]; I interpret the contents of `theURL` as a GIF. I create an animated `UIImage` using the source images in the GIF. I operate exactly like `+[UIImage animatedImageWithAnimatedGIFData:]`, except that I read the data from `theURL`. If `theURL` is not a `file:` URL, you probably want to call me on a background thread or GCD queue to avoid blocking the main thread.*/+ (UIImage *)animatedImageWithAnimatedGIFURL:(NSURL *)theURL;@end
【UIImage+animatedGIF.m】
#import "UIImage+animatedGIF.h"#import <ImageIO/ImageIO.h>#if __has_feature(objc_arc)#define toCF (__bridge CFTypeRef)#define fromCF (__bridge id)#else#define toCF (CFTypeRef)#define fromCF (id)#endif@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
然后在UIViewController中使用
#import "ViewController.h"#import "UIImage+animatedGIF.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建一个图片控件,UIImageView: 是用来显示图片的控件 UIImageView *image=[[UIImageView alloc]initWithFrame:CGRectMake(10, 20, 100, 20)]; // 给图片控件添加图片 [image setImage:[UIImage imageNamed:@"player1"]]; //把图片控件添加到我的视图上面去 [self.view addSubview:image]; // UIImageView 使用的时候,总是会用到UIImage,// 就可以理解为,图片控件总是需要添加图片对象// 类似于,UILabel 总是需要用NSString 或者@"" 来添加字符 // 创建 UIImage 对象 尽量使用 imageNamed 方法创建图片对象// 原因:比较节省内存 // 1、 读取 图片路径// 2、把图片转成data// 3、用data 生成图片对象// 4、把图片对象加到图片控件上面 // 把Gif的图片路径读出来,也就是找到图片在哪儿 NSString *path=[[NSBundle mainBundle]pathForResource:@"FlagZombie" ofType:@"gif"]; // 把图片用图片路径读取出来,转成我们可以用的NSData NSData *data=[NSData dataWithContentsOfFile:path]; // 用图片数据,转成我们的图片对象,Gif 图片对象 UIImage *img=[UIImage animatedImageWithAnimatedGIFData:data]; //把图片设置到图片控件上面 [image setImage:img]; }- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
0 0
- iOS之UIImage的三中读取方法
- iOS之UIImage的三中读取方法
- iOS 开发之Resize UIimage的三种方法
- iOS 开发之Resize UIimage的三种方法
- iOS UIimage拉伸的三种方法
- ios中,uiimage拼接图片的方法
- iOS NSMutableDictionary中UIImage的存储和读取
- IOS实现UIImage倒影的三种方法
- IOS uiimage 拉伸的方法
- iOS中改变UIImage的颜色和大小的方法
- IOS开发UIImage中stretchableImageWithLeftCapWidth方法的解释
- iOS开发中常用的分类方法---UIImage+extension
- iOS中UIImage转换为NSData 方法
- [iOS]从UIImage得到RGB32的方法
- ios开发UIImage imageNamed方法的误用
- ios开发UIImage imageNamed方法的误用
- ios获得UIImage的主色调方法
- ios开发UIImage imageNamed方法的误用
- 查看django orm执行的sql
- 读书笔记--大话设计模式
- 内存管理:使用链式栈实现内存的有效管理与监控
- TabError: Inconsistent use of tabs and spaces in indentation
- iOS:hidesBottomBarWhenPushed的正确用法
- iOS之UIImage的三中读取方法
- 【JAVA基础】JAVA中分包的规范
- zoj 2734 Exchange Cards
- nyoj35表达式求值
- IOS学习之解析数据(NSJSONSerialization)
- iOS开发-Day18-OC NSArray&NSMutableArray
- ubuntu下Mycli的安装
- subscription-manager
- 常见笔试面试