YYImage 是框架對圖片的封裝對象,它支持 GIF, APNG,WebP 格式的動(dòng)畫圖片。
初始化圖片
生成一張 YYImage 會(huì)調(diào)用
- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale;
來初始化,具體代碼如下
- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
if (data.length == 0) return nil;
if (scale <= 0) scale = [UIScreen mainScreen].scale;
_preloadedLock = dispatch_semaphore_create(1);
@autoreleasepool {
YYImageDecoder *decoder = [YYImageDecoder decoderWithData:data scale:scale];
YYImageFrame *frame = [decoder frameAtIndex:0 decodeForDisplay:YES];
UIImage *image = frame.image;
if (!image) return nil;
self = [self initWithCGImage:image.CGImage scale:decoder.scale orientation:image.imageOrientation];
if (!self) return nil;
_animatedImageType = decoder.type;
if (decoder.frameCount > 1) {
_decoder = decoder;
_bytesPerFrame = CGImageGetBytesPerRow(image.CGImage) * CGImageGetHeight(image.CGImage);
_animatedImageMemorySize = _bytesPerFrame * decoder.frameCount;
}
self.yy_isDecodedForDisplay = YES;
}
return self;
}
YYImage 內(nèi)部維護(hù)了一個(gè)YYImageDecoder對象來進(jìn)行圖片的編碼和解碼,YYImageDecoder是一個(gè)強(qiáng)大的對象,它可以提供圖片的解碼,和編碼,并且在 iOS6 級別提供 apng 和 webp 的解碼,YYImageDecoder不是本文介紹的重點(diǎn),將會(huì)在以后的文章中重點(diǎn)介紹,所以可以先忽略,知道它是一個(gè)圖片的解碼者就行啦。
展示在 YYAnimatedImageView 上
老樣子,想在 YYAnimatedImageView 上顯示需要遵守協(xié)議 YYAnimatedImage
來看看如何實(shí)現(xiàn)協(xié)議
告訴 YYAnimatedImageView 幀數(shù),播放次數(shù),每一幀的字節(jié)大小,
- (NSUInteger)animatedImageFrameCount {
return _decoder.frameCount;
}
- (NSUInteger)animatedImageLoopCount {
return _decoder.loopCount;
}
- (NSUInteger)animatedImageBytesPerFrame {
return _bytesPerFrame;
}
返回每一幀的圖片和每一幀的顯示時(shí)間
- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
if (index >= _decoder.frameCount) return nil;
dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
UIImage *image = _preloadedFrames[index];
dispatch_semaphore_signal(_preloadedLock);
if (image) return image == (id)[NSNull null] ? nil : image;
return [_decoder frameAtIndex:index decodeForDisplay:YES].image;
}
- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
NSTimeInterval duration = [_decoder frameDurationAtIndex:index];
/*
http://opensource.apple.com/source/WebCore/WebCore-7600.1.25/platform/graphics/cg/ImageSourceCG.cpp
Many annoying ads specify a 0 duration to make an image flash as quickly as
possible. We follow Safari and Firefox's behavior and use a duration of 100 ms
for any frames that specify a duration of <= 10 ms.
See <rdar://problem/7689300> and <http://webkit.org/b/36082> for more information.
See also: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser.
*/
if (duration < 0.011f) return 0.100f;
return duration;
}