SDAnimatedImage now supports static image like JPEG data

This previously will only return nil for static image, so this may be a behavior changes
For example, SDAnimatedImageView loading url will cache the `SDAnimatedImage` instead of `UIImage`
This commit is contained in:
DreamPiggy 2023-10-21 17:52:10 +08:00
parent 1f06ef5007
commit 42f35ca3f6
2 changed files with 23 additions and 11 deletions

View File

@ -72,7 +72,8 @@
// This class override these methods from UIImage(NSImage), and it supports NSSecureCoding.
// You should use these methods to create a new animated image. Use other methods just call super instead.
// Pay attention, when the animated image frame count <= 1, all the `SDAnimatedImageProvider` protocol methods will return nil or 0 value, you'd better check the frame count before usage and keep fallback.
// @note Before 5.19, these initializer will return nil for static image (when all candidate SDAnimatedImageCoder returns nil instance), like JPEG data. After 5.19, these initializer will retry for static image as well, so JPEG data will return non-nil instance.
// @note When the animated image frame count <= 1, all the `SDAnimatedImageProvider` protocol methods will return nil or 0 value, you'd better check the frame count before usage and keep fallback.
+ (nullable instancetype)imageNamed:(nonnull NSString *)name; // Cache in memory, no Asset Catalog support
#if __has_include(<UIKit/UITraitCollection.h>)
+ (nullable instancetype)imageNamed:(nonnull NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection; // Cache in memory, no Asset Catalog support
@ -88,7 +89,8 @@
/**
Current animated image format.
@note This format is only valid when `animatedImageData` not nil
@note This format is only valid when `animatedImageData` not nil.
@note This actually just call `[NSData sd_imageFormatForImageData:self.animatedImageData]`
*/
@property (nonatomic, assign, readonly) SDImageFormat animatedImageFormat;

View File

@ -34,7 +34,6 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
@interface SDAnimatedImage ()
@property (nonatomic, strong) id<SDAnimatedImageCoder> animatedCoder;
@property (nonatomic, assign, readwrite) SDImageFormat animatedImageFormat;
@property (atomic, copy) NSArray<SDImageFrame *> *loadedAnimatedImageFrames; // Mark as atomic to keep thread-safe
@property (nonatomic, assign, getter=isAllFramesLoaded) BOOL allFramesLoaded;
@ -142,10 +141,22 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
}
}
}
if (!animatedCoder) {
return nil;
if (animatedCoder) {
// Animated Image
return [self initWithAnimatedCoder:animatedCoder scale:scale];
} else {
// Static Image (Before 5.19 this code path return nil)
UIImage *image = [[SDImageCodersManager sharedManager] decodedImageWithData:data options:options];
if (!image) {
return nil;
}
#if SD_MAC
self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:kCGImagePropertyOrientationUp];
#else
self = [super initWithCGImage:image.CGImage scale:MAX(scale, 1) orientation:image.imageOrientation];
#endif
return self;
}
return [self initWithAnimatedCoder:animatedCoder scale:scale];
}
- (instancetype)initWithAnimatedCoder:(id<SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale {
@ -166,13 +177,14 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
if (animatedCoder.animatedImageFrameCount > 1) {
_animatedCoder = animatedCoder;
}
NSData *data = [animatedCoder animatedImageData];
SDImageFormat format = [NSData sd_imageFormatForImageData:data];
_animatedImageFormat = format;
}
return self;
}
- (SDImageFormat)animatedImageFormat {
return [NSData sd_imageFormatForImageData:self.animatedImageData];
}
#pragma mark - Preload
- (void)preloadAllFrames {
if (!_animatedCoder) {
@ -205,7 +217,6 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_animatedImageFormat = [aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(animatedImageFormat))];
NSData *animatedImageData = [aDecoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(animatedImageData))];
if (!animatedImageData) {
return self;
@ -232,7 +243,6 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
[aCoder encodeInteger:self.animatedImageFormat forKey:NSStringFromSelector(@selector(animatedImageFormat))];
NSData *animatedImageData = self.animatedImageData;
if (animatedImageData) {
[aCoder encodeObject:animatedImageData forKey:NSStringFromSelector(@selector(animatedImageData))];