diff --git a/SDWebImage/SDWebImageGIFCoder.m b/SDWebImage/SDWebImageGIFCoder.m index e4f55b1b..7ad61595 100644 --- a/SDWebImage/SDWebImageGIFCoder.m +++ b/SDWebImage/SDWebImageGIFCoder.m @@ -45,8 +45,7 @@ if (count <= 1) { animatedImage = [[UIImage alloc] initWithData:data]; - } - else { + } else { NSMutableArray *images = [NSMutableArray array]; NSTimeInterval duration = 0.0f; @@ -103,9 +102,7 @@ NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; if (delayTimeUnclampedProp) { frameDuration = [delayTimeUnclampedProp floatValue]; - } - else { - + } else { NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; if (delayTimeProp) { frameDuration = [delayTimeProp floatValue]; @@ -147,11 +144,22 @@ } NSMutableData *imageData = [NSMutableData data]; + NSUInteger frameCount = 0; // assume static images by default CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:format]; - NSUInteger frameCount = 1; - if (image.images) { - frameCount = image.images.count; +#if SD_MAC + NSBitmapImageRep *bitmapRep; + for (NSImageRep *imageRep in image.representations) { + if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) { + bitmapRep = (NSBitmapImageRep *)imageRep; + break; + } } + if (bitmapRep) { + frameCount = [[bitmapRep valueForProperty:NSImageFrameCount] unsignedIntegerValue]; + } +#else + frameCount = image.images.count; +#endif // Create an image destination. GIF does not support EXIF image orientation CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL); @@ -160,29 +168,30 @@ return nil; } -#ifdef SD_MAC - CGImageDestinationAddImage(imageDestination, image.CGImage, nil); -#else - if (!image.images) { + if (frameCount == 0) { // for static single GIF images CGImageDestinationAddImage(imageDestination, image.CGImage, nil); } else { // for animated GIF images NSUInteger loopCount = image.sd_imageLoopCount; - NSTimeInterval totalDuration = image.duration; - NSTimeInterval frameDuration = totalDuration / frameCount; NSDictionary *gifProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary: @{(__bridge_transfer NSString *)kCGImagePropertyGIFLoopCount : @(loopCount)}}; CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)gifProperties); for (size_t i = 0; i < frameCount; i++) { @autoreleasepool { - NSDictionary *frameProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary : @{(__bridge_transfer NSString *)kCGImagePropertyGIFUnclampedDelayTime : @(frameDuration)}}; +#if SD_MAC + // NSBitmapImageRep need to manually change frame. "Good taste" API + [bitmapRep setProperty:NSImageCurrentFrame withValue:@(i)]; + float frameDuration = [[bitmapRep valueForProperty:NSImageCurrentFrameDuration] floatValue]; + CGImageRef frameImageRef = bitmapRep.CGImage; +#else + float frameDuration = image.duration / frameCount; CGImageRef frameImageRef = image.images[i].CGImage; +#endif + NSDictionary *frameProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary : @{(__bridge_transfer NSString *)kCGImagePropertyGIFUnclampedDelayTime : @(frameDuration)}}; CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties); } } } -#endif - // Finalize the destination. if (CGImageDestinationFinalize(imageDestination) == NO) { // Handle failure. diff --git a/SDWebImage/SDWebImageImageIOCoder.m b/SDWebImage/SDWebImageImageIOCoder.m index 149eaa18..8601eecd 100644 --- a/SDWebImage/SDWebImageImageIOCoder.m +++ b/SDWebImage/SDWebImageImageIOCoder.m @@ -89,11 +89,11 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over return nil; } -#if SD_MAC - return [[UIImage alloc] initWithData:data]; -#else - UIImage *image = [[UIImage alloc] initWithData:data]; + +#if SD_MAC + return image; +#else if (!image) { return nil; } @@ -105,14 +105,12 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over image = [UIImage animatedImageWithImages:@[image] duration:image.duration]; return image; } -#if SD_UIKIT || SD_WATCH UIImageOrientation orientation = [[self class] sd_imageOrientationFromImageData:data]; if (orientation != UIImageOrientationUp) { image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation]; } -#endif return image; #endif