美文网首页
iOS展示gif图

iOS展示gif图

作者: 萧雪痕 | 来源:发表于2016-08-29 17:55 被阅读2652次

    展示本地gif图片
    SDWebImage比较占内存,FLAnimatedImage不怎么占用内存

    1.使用SDWebImage

    1. 导入头文件
      #import "UIImage+GIF.h"
    2. 设置gif图
      self.imageView.image = [UIImage sd_animatedGIFNamed:@"test"];
      也可以通过NSData导入
      + (UIImage *)sd_animatedGIFWithData:(NSData *)data

    2.使用FLAnimatedImage

    1. 导入头文件
      #import "FLAnimatedImage.h"
    2. 设置gif图
      NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"gif"];
      NSData *data = [NSData dataWithContentsOfFile:path];
      FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
      self.imageView.animatedImage = image;

    3.SDWebImage实现原理

    使用UIImage + GIF分类

    1.将gif图的每一帧导出为一个UIImage,并且算出每一帧的播放时间,将导出的image放入images数组中
    2.使用+ animatedImageWithImages: duration: 方法创建image,参数为第一步的images数组和播放总时长
    3.设置UIImageView的image时用sd_animatedGIFNamed:方法即可展示gif

    方法1: 通过NSData获取gif的UIImage
    方法名:+ (UIImage )sd_animatedGIFWithData:(NSData *)data;
    1. 获取gif数据,及其帧数
    2. 获取每帧的像素位图,求出每帧的播放时间
    3. 按照屏幕分辨率生成UIImage并放入数组
    4. 通过+ animatedImageWithImages: duration:生成UIImage
      + (UIImage *)sd_animatedGIFWithData:(NSData *)data {
      if (!data) {
      return nil;
      }
      //通过CFData读取gif文件的数据
      CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
      //获取gif文件的帧数
      size_t count = CGImageSourceGetCount(source);
      UIImage *animatedImage;
      if (count <= 1) {
      animatedImage = [[UIImage alloc] initWithData:data];
      }
      else {//大于一张图片时
      NSMutableArray *images = [NSMutableArray array];
      //设置gif播放的时间
      NSTimeInterval duration = 0.0f;
      for (size_t i = 0; i < count; i++) {
      //获取gif指定帧的像素位图
      CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
      if (!image) {
      continue;
      }
      //获取每张图的播放时间
      duration += [self sd_frameDurationAtIndex:i source:source];
      [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
      CGImageRelease(image);
      }
      if (!duration) {//如果播放时间为空
      duration = (1.0f / 10.0f) * count;
      }
      animatedImage = [UIImage animatedImageWithImages:images duration:duration];
      }
      CFRelease(source);
      return animatedImage;
      }
    方法2:获取指定帧的image的播放时间
    方法名:+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source
    1. 获取指定帧图片的属性字典
    2. 获取图片的gif属性字典
    3. 获取每一帧的播放时间(如果小于0.1,设置为0.1)
      + (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
      float frameDuration = 0.1f;
      //获取这一帧图片的属性字典
      CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
      NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
      //获取gif属性字典
      NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
      //获取这一帧持续的时间
      NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
      if (delayTimeUnclampedProp) {
      frameDuration = [delayTimeUnclampedProp floatValue];
      }
      else {
      NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
      if (delayTimeProp) {
      frameDuration = [delayTimeProp floatValue];
      }
      }
      //如果帧数小于0.1,则指定为0.1
      if (frameDuration < 0.011f) {
      frameDuration = 0.100f;
      }
      CFRelease(cfFrameProperties);
      return frameDuration;
      }
    方法3:通过图片的Name获取UIImage
    方法名:+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;
    1. 根据屏幕分辨率给图片自动加后缀(@2x)
    2. 从mainBundle中获取Data数据
    3. 调用方法 + sd_animatedGIFWithData:
      + (UIImage *)sd_animatedGIFNamed:(NSString *)name {
      //判断屏幕分辨率
      CGFloat scale = [UIScreen mainScreen].scale;
      if (scale > 1.0f) {
      NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"];
      NSData *data = [NSData dataWithContentsOfFile:retinaPath];
      if (data) {
      return [UIImage sd_animatedGIFWithData:data];
      }
      NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
      data = [NSData dataWithContentsOfFile:path];
      if (data) {
      return [UIImage sd_animatedGIFWithData:data];
      }
      return [UIImage imageNamed:name];
      }
      else {
      NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
      NSData *data = [NSData dataWithContentsOfFile:path];
      if (data) {
      return [UIImage sd_animatedGIFWithData:data];
      }
      return [UIImage imageNamed:name];
      }
      }
    方法4:对gif按比例进行缩放
    方法名:- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
    1. 获取较大的缩放比例值,宽高等比缩放
    2. 调整位置,使缩放后的图居中
    3. 遍历self.images, 将图片缩放后导出放入数组
    4. 通过animatedImageWithImages:duration:返回image
      - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size {
      if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) {
      return self;
      }
      CGSize scaledSize = size;
      CGPoint thumbnailPoint = CGPointZero;
      //获取较大的缩放比例值,宽高等比缩放
      CGFloat widthFactor = size.width / self.size.width;
      CGFloat heightFactor = size.height / self.size.height;
      CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor;
      scaledSize.width = self.size.width * scaleFactor;
      scaledSize.height = self.size.height * scaleFactor;
      //调整位置,使缩放后的图居中
      if (widthFactor > heightFactor) {
      thumbnailPoint.y = (size.height - scaledSize.height) * 0.5;
      }
      else if (widthFactor < heightFactor) {
      thumbnailPoint.x = (size.width - scaledSize.width) * 0.5;
      }
      //遍历self.images, 将图片缩放后导出放入数组
      NSMutableArray *scaledImages = [NSMutableArray array];
      for (UIImage *image in self.images) {
      UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
      [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
      [scaledImages addObject:newImage];
      UIGraphicsEndImageContext();
      }
      return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
      }

    相关文章

      网友评论

          本文标题:iOS展示gif图

          本文链接:https://www.haomeiwen.com/subject/etmxettx.html