今年是GIF图片诞生30周年,而且一直对iOS的GIF图片比较感兴趣,前两天就花了点时间研究了一下,在此跟大家分享,共同学习,共同进步! 大家也可以直接看DEMO,里面在关键地方都有注释。
gif图片本质
GIF图片其实和jpg图片一样,是一种流行的图形文件格式。但大家不要以为GIF都是动图,它也是有静态的,只不过我们通常看到的都是动的图片,所以下意识地人为GIF都是动图。
gif动图
我们主要来研究GIF动图,其实它就是一个图片连续播放的效果而已,只不过这不是我们手动来实现的,各个平台已经对它进行了适配,只要是动图它就能动起来而已。tom猫不知大家玩过没有,它就用的是自己手动展示多张连环图片的方法来实现的动画。
gif动图制作
这里提供两种方法,一种是偏底层一点需要使用Core
框架的方法,另一种是读SDWebImage
源码找到的苹果封装好的方法.
1.
//创建gif路
NSURL * gifPath = [self gifPathURL];
//图像目标
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)gifPath, kUTTypeGIF, imagePathArray.count, NULL);
//gif设置
NSDictionary *fileProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary:
@{(__bridge id)kCGImagePropertyGIFLoopCount: @0},
(NSString*)kCGImagePropertyGIFHasGlobalColorMap:[NSNumber numberWithBool:YES],
(NSString *)kCGImagePropertyColorModel:(NSString *)kCGImagePropertyColorModelRGB,
(NSString*)kCGImagePropertyDepth:[NSNumber numberWithInt:8]};
//a float (not double!) in seconds, rounded to centiseconds in the GIF data
NSDictionary *frameProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary:
@{(__bridge id)kCGImagePropertyGIFDelayTime: [NSNumber numberWithFloat:duration]}};
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
//合成gif
for (UIImage *image in imagePathArray)
{
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)frameProperties);
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"failed to finalize image destination");
}
CFRelease(destination);
2.
UIImage *animatedImage;
CGFloat totalTime;
if (!duration) {
totalTime = (3.0f / 10.0f) * imageArr.count;
}else{
duration = duration * imageArr.count;
}
animatedImage = [UIImage animatedImageWithImages:imageArr duration:duration];
gif图片分解
GIF动图是多张图片合成的,当然也有方法将其中的图片一张一张分解出来,注释比较详细,就不多说了。代码:
//用于保存所有图片
NSMutableArray *imgObjects = [NSMutableArray array];
//1.gif转换成data
NSData *gifData=[NSData dataWithContentsOfFile:gifPath];
//2.通过data获取image的数据源
CGImageSourceRef source =CGImageSourceCreateWithData((CFDataRef)gifData, NULL);
//3.获取gif帧数
size_t count = CGImageSourceGetCount(source);
for (int i=0; i<count; i++) {
//4.获取单帧图片
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
//5.根据CGImageRef获取图片
//[UIScreen mainScreen].scale 是计算屏幕分辨率的
//UIImageOrientationUp 指定新的图像的绘制方向
UIImage *image = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
//6.释放CGImageRef对象
CGImageRelease(imageRef);
[imgObjects addObject:image];
//释放source
CFRelease(source);
gif使用tips
GIF动图的合成和分解比较简单,但使用过程中会有一些小问题,比如你想把制作的GIF放到微信中跟好友秀一下,那么你就必须要控制GIF图片的大小和质量了,否则会失败。还有如何直接用视频制作GIF,取视频中的帧图片拿来合成即可,如何取视频图片我在仿微信朋友圈视频剪切功能已经讲过。本DEMO实现了照片选取转GIF、视频选取或拍摄转GIF、GIF分解为图片等功能,有兴趣的朋友可以下载看一下,觉得不错或对您有帮助的话请star一个!!!
如有不足或缺陷敬请指正,共同学习,共同进步!