美文网首页
iOS压缩 gif 图片

iOS压缩 gif 图片

作者: 摘心 | 来源:发表于2018-12-04 14:45 被阅读82次
    最近发现相册可以直接存储、浏览 gif,感觉苹果开始注意 gif,所以总结一下自己的使用方法。一般 gif 在内存比较大,在 cell 上展示会比较卡,所以做下压缩还是很有必要的。查找很多资料也没法下可以直接操作的 api,所有的压缩原理似乎都是对 gif 的每帧图片分别压缩,然后再合成 gif,所以我也是按照这个思路实现了一下。下面直接上代码:
+ (NSData *)scallGIFWithData:(NSData *)data scallSize:(CGSize)scallSize {
  if (!data) {
    return nil;
  }
  CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
  size_t count = CGImageSourceGetCount(source);
  
  // 设置 gif 文件属性 (0:无限次循环)
  NSDictionary *fileProperties = [self filePropertiesWithLoopCount:0];
  
  NSString *tempFile = [NSTemporaryDirectory() stringByAppendingString:@"scallTemp.gif"];
  NSFileManager *manager = [NSFileManager defaultManager];
  if ([manager fileExistsAtPath:tempFile]) {
    [manager removeItemAtPath:tempFile error:nil];
  }
  NSURL *fileUrl = [NSURL fileURLWithPath:tempFile];
  CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileUrl, kUTTypeGIF , count, NULL);
  
  NSTimeInterval duration = 0.0f;
  for (size_t i = 0; i < count; i++) {
    CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    UIImage *scallImage = [self scallImageWidthScallSize:scallSize];
    
    NSTimeInterval delayTime = [self frameDurationAtIndex:i source:source];
    duration += delayTime;
    // 设置 gif 每针画面属性
    NSDictionary *frameProperties = [self framePropertiesWithDelayTime:delayTime];
    CGImageDestinationAddImage(destination, scallImage.CGImage, (CFDictionaryRef)frameProperties);
    CGImageRelease(imageRef);
  }
  CGImageDestinationSetProperties(destination, (CFDictionaryRef)fileProperties);
  // Finalize the GIF
  if (!CGImageDestinationFinalize(destination)) {
    NSLog(@"Failed to finalize GIF destination");
    if (destination != nil) {
      CFRelease(destination);
    }
    return nil;
  }
  CFRelease(destination);
  CFRelease(source);
  return [NSData dataWithContentsOfFile:tempFile];
}

按照 size 压缩每帧图片

+ (UIImage *)scallImageWidthScallSize:(CGSize)scallSize{
  CGFloat width = self.size.width;
  CGFloat height = self.size.height;
  
  CGFloat scaleFactor = 0.0;
  CGFloat scaledWidth = scallSize.width;
  CGFloat scaledHeight = scallSize.height;
  CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
  
  if (!CGSizeEqualToSize(self.size, scallSize))
  {
    CGFloat widthFactor = scaledWidth / width;
    CGFloat heightFactor = scaledHeight / height;
    
    scaleFactor = MAX(widthFactor, heightFactor);
    
    scaledWidth= width * scaleFactor;
    scaledHeight = height * scaleFactor;
    
    // center the image
    if (widthFactor > heightFactor)
    {
      thumbnailPoint.y = (scallSize.height - scaledHeight) * 0.5;
    }
    else if (widthFactor < heightFactor)
    {
      thumbnailPoint.x = (scallSize.width - scaledWidth) * 0.5;
    }
  }
  CGRect rect;
  rect.origin = thumbnailPoint;
  rect.size = CGSizeMake(scaledWidth, scaledHeight);
  UIGraphicsBeginImageContext(rect.size);
  [self drawInRect:rect];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return  image;
}

读取帧率

+ (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
  float frameDuration = 0.1f;
  CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
  NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
  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];
    }
  }

  if (frameDuration < 0.011f) {
    frameDuration = 0.100f;
  }
  CFRelease(cfFrameProperties);
  frameDuration += 0.1;
  return frameDuration;
}

合成新的 gif, 设置播放属性

+ (NSDictionary *)filePropertiesWithLoopCount:(int)loopCount {
  return @{(NSString *)kCGImagePropertyGIFDictionary:
             @{(NSString *)kCGImagePropertyGIFLoopCount: @(loopCount)}
           };
}

+ (NSDictionary *)framePropertiesWithDelayTime:(NSTimeInterval)delayTime {
  
  return @{(NSString *)kCGImagePropertyGIFDictionary:
             @{(NSString *)kCGImagePropertyGIFDelayTime: @(delayTime)},
           (NSString *)kCGImagePropertyColorModel:(NSString *)kCGImagePropertyColorModelRGB
           };
}

相关文章

  • iOS压缩 gif 图片

    按照 size 压缩每帧图片 读取帧率 合成新的 gif, 设置播放属性

  • iOS Gif图片压缩

    随着表情包越来越流行,以后项目中使用到Gif图片的地方也越来越多,遇到很大的gif图片的时候,这时候移动端要首先做...

  • iOS 图片压缩方法

    iOS 图片压缩方法 更多图片处理方法见图片组件 BBWebImage iOS 图片压缩方法 两种图片压缩方法 两...

  • GIF

    imageIO介绍image解压缩图片帧延迟设置bridge gif生成 gif解析

  • 图片处理

    图片压缩 图好快:在线图片压缩!支持GIF动图压缩,PNG压缩,JPG压缩。可精确控制照片的长宽和大小。图好快出品...

  • iOS 开发时候使用到的工具资源

    图片处理 压缩图片ImageOptim(Mac客户端,免费),支持 PNG/JPEG/GIF 动画,压缩后图像质量...

  • JAVA实现多张PNG生成GIF图片

    依赖下载 animated-gif-lib-1.4.jar 多张PNG图片生成GIF图片算法(可抽帧压缩) 把PN...

  • 图片压缩,gif压缩方法

    ImageCompress.swift

  • iOS 图片压缩、滤镜、剪切、渲染等解析

    iOS 图片压缩、滤镜、剪切、渲染等解析 iOS 图片压缩、滤镜、剪切、渲染等解析

  • iOS的GIF动画效果实现

    GIF在iOS中的使用场景 GIF在iOS中的使用场景有以下三个方面。 (1)GIF图片分解为单帧图片。 (2)一...

网友评论

      本文标题:iOS压缩 gif 图片

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