Merge pull request #3626 from dreampiggy/behavior/sdanimatedimage_jpeg_nonnil
SDAnimatedImage now supports static image like JPEG data
This commit is contained in:
commit
7550aa759c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -115,7 +114,19 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
|
|||
|
||||
- (instancetype)initWithContentsOfFile:(NSString *)path {
|
||||
NSData *data = [NSData dataWithContentsOfFile:path];
|
||||
return [self initWithData:data scale:SDImageScaleFromPath(path)];
|
||||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
CGFloat scale = SDImageScaleFromPath(path);
|
||||
// path extension may be useful for coder like raw-image
|
||||
NSString *fileExtensionHint = path.pathExtension; // without dot
|
||||
if (fileExtensionHint.length == 0) {
|
||||
// Ignore file extension which is empty
|
||||
fileExtensionHint = nil;
|
||||
}
|
||||
SDImageCoderMutableOptions *mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
mutableCoderOptions[SDImageCoderDecodeFileExtensionHint] = fileExtensionHint;
|
||||
return [self initWithData:data scale:scale options:[mutableCoderOptions copy]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData *)data {
|
||||
|
@ -131,21 +142,38 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
|
|||
return nil;
|
||||
}
|
||||
id<SDAnimatedImageCoder> animatedCoder = nil;
|
||||
SDImageCoderMutableOptions *mutableCoderOptions;
|
||||
if (options != nil) {
|
||||
mutableCoderOptions = [NSMutableDictionary dictionaryWithDictionary:options];
|
||||
} else {
|
||||
mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
}
|
||||
mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);
|
||||
options = [mutableCoderOptions copy];
|
||||
for (id<SDImageCoder>coder in [SDImageCodersManager sharedManager].coders.reverseObjectEnumerator) {
|
||||
if ([coder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) {
|
||||
if ([coder canDecodeFromData:data]) {
|
||||
if (!options) {
|
||||
options = @{SDImageCoderDecodeScaleFactor : @(scale)};
|
||||
}
|
||||
animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:data options:options];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!animatedCoder) {
|
||||
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;
|
||||
}
|
||||
return [self initWithAnimatedCoder:animatedCoder scale:scale];
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithAnimatedCoder:(id<SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale {
|
||||
|
@ -166,13 +194,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 +234,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 +260,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))];
|
||||
|
|
Loading…
Reference in New Issue