YYImage之YYImage

YYImage 是框架对图片的封装对象,它支持 GIF, APNG,WebP 格式的动画图片。

初始化图片

生成一张 YYImage 会调用

- (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 内部维护了一个YYImageDecoder对象来进行图片的编码和解码,YYImageDecoder是一个强大的对象,它可以提供图片的解码,和编码,并且在 iOS6 级别提供 apng 和 webp 的解码,YYImageDecoder不是本文介绍的重点,将会在以后的文章中重点介绍,所以可以先忽略,知道它是一个图片的解码者就行啦。

展示在 YYAnimatedImageView 上

老样子,想在 YYAnimatedImageView 上显示需要遵守协议 YYAnimatedImage
来看看如何实现协议

告诉 YYAnimatedImageView 帧数,播放次数,每一帧的字节大小,

- (NSUInteger)animatedImageFrameCount {
    return _decoder.frameCount;
}

- (NSUInteger)animatedImageLoopCount {
    return _decoder.loopCount;
}

- (NSUInteger)animatedImageBytesPerFrame {
    return _bytesPerFrame;
}

返回每一帧的图片和每一帧的显示时间

- (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  and  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;
}

你可能感兴趣的:(YYImage之YYImage)