今天有两个朋友问我如何直接在iOS中使用GIF图片,查了下咱们的度娘看到了简单的方法就是直接使用webView来加载。webView的好处在于每个subFrame之间的delay可以按照图片的设定显示出来。
还有个办法就是使用定时器模拟帧数,使用imageIO流来读取GIF的data。
我也尝试写个Demo来显示Gif
在demo中首先先分解出GIF的每个image,之后使用UIView动画来重现效果,在这个中使用了1/100秒作为一针
主体代码如下:
- (void)loadImageData {
// 将所有的子帧动画加入数组
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0; i < [GIF_frames count]; i++)
{
[array addObject: [self getFrameAsImageAtIndex:i]];
}
NSMutableArray *overlayArray = [[NSMutableArray alloc] init];
UIImage *firstImage = [array objectAtIndex:0];
CGSize size = firstImage.size;
CGRect rect = CGRectZero;
rect.size = size;
//获取当前的上下文
UIGraphicsBeginImageContext(size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
int i = 0;
AnimatedGifFrame *lastFrame = nil;
for (UIImage *image in array)
{
// 获取
AnimatedGifFrame *frame = [GIF_frames objectAtIndex:i];
//当前的展示
UIImage *previousCanvas = nil;
//将当前图形状态推入堆栈
CGContextSaveGState(ctx);
// 缩放比例(上下文,x的比例,y的比例(需使用负值),因为cgcontext的原点与uiview不同)
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextTranslateCTM(ctx, 0.0, -size.height);
// 显示的大小
CGRect clipRect;
// 判断是哪种显示方法
switch (frame.disposalMethod)
{
case 1: // 是否超边了
// 显示的大小
clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
CGContextClipToRect(ctx, clipRect);
break;
case 2:
clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
CGContextClipToRect(ctx, clipRect);
break;
case 3:
// 获取画板
previousCanvas = UIGraphicsGetImageFromCurrentImageContext();
clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
// Clip Context
CGContextClipToRect(ctx, clipRect);
break;
}
// 绘制实际图片实际大小
CGContextDrawImage(ctx, rect, image.CGImage);
// 重新渲染
CGContextRestoreGState(ctx);
//延迟时间要大于等于0
if (frame.delay <= 0) {
frame.delay = 10;
}
[overlayArray addObject:UIGraphicsGetImageFromCurrentImageContext()];
// 设置最后显示大小
lastFrame = frame;
//
switch (frame.disposalMethod)
{
case 2:
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextTranslateCTM(ctx, 0.0, -size.height);
// 清除上下文
CGContextClearRect(ctx, clipRect);
// 重设上下文
CGContextRestoreGState(ctx);
break;
case 3:
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextTranslateCTM(ctx, 0.0, -size.height);
CGContextClearRect(ctx, lastFrame.area);
CGContextDrawImage(ctx, rect, previousCanvas.CGImage);
CGContextRestoreGState(ctx);
break;
}
i++;
}
UIGraphicsEndImageContext();
[self setImage:[overlayArray objectAtIndex:0]];
[self setAnimationImages:overlayArray];
//gif总共播放时间
double total = 0;
for (AnimatedGifFrame *frame in GIF_frames) {
total += frame.delay;
}
// gif的针数大概为1/100一秒
// UIImage来播放
[self setAnimationDuration:total/100];
// 设置是否循环
[self setAnimationRepeatCount:0];
[self startAnimating];
}
里面使用了很多c语言,主要就是拿来判断是否为gif,和解析gif