Merge pull request #3047 from dreampiggy/behavior_sdanimatedimage_encoding_animation

Add the support for that UIImage+MultiFormat methods on SDAnimartedImage, which supports encoding the animation like GIF/APNG/WebP with lower compression quality.
This commit is contained in:
DreamPiggy 2020-07-02 10:42:54 +08:00 committed by GitHub
commit 8a57e935b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 0 deletions

View File

@ -13,6 +13,8 @@
#import "SDImageFrame.h"
#import "UIImage+MemoryCacheCost.h"
#import "UIImage+Metadata.h"
#import "UIImage+MultiFormat.h"
#import "SDImageCoderHelper.h"
#import "SDImageAssetManager.h"
#import "objc/runtime.h"
@ -327,3 +329,62 @@ static CGFloat SDImageScaleFromPath(NSString *string) {
}
@end
@implementation SDAnimatedImage (MultiFormat)
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {
return [self sd_imageWithData:data scale:1];
}
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale {
return [self sd_imageWithData:data scale:scale firstFrameOnly:NO];
}
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data scale:(CGFloat)scale firstFrameOnly:(BOOL)firstFrameOnly {
if (!data) {
return nil;
}
return [[self alloc] initWithData:data scale:scale options:@{SDImageCoderDecodeFirstFrameOnly : @(firstFrameOnly)}];
}
- (nullable NSData *)sd_imageData {
NSData *imageData = self.animatedImageData;
if (imageData) {
return imageData;
} else {
return [self sd_imageDataAsFormat:self.animatedImageFormat];
}
}
- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat {
return [self sd_imageDataAsFormat:imageFormat compressionQuality:1];
}
- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality {
return [self sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:NO];
}
- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat compressionQuality:(double)compressionQuality firstFrameOnly:(BOOL)firstFrameOnly {
if (firstFrameOnly) {
// First frame, use super implementation
return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];
}
NSUInteger frameCount = self.animatedImageFrameCount;
if (frameCount <= 1) {
// Static image, use super implementation
return [super sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];
}
// Keep animated image encoding, loop each frame.
NSMutableArray<SDImageFrame *> *frames = [NSMutableArray arrayWithCapacity:frameCount];
for (size_t i = 0; i < frameCount; i++) {
UIImage *image = [self animatedImageFrameAtIndex:i];
NSTimeInterval duration = [self animatedImageDurationAtIndex:i];
SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration];
[frames addObject:frame];
}
UIImage *animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames];
NSData *imageData = [animatedImage sd_imageDataAsFormat:imageFormat compressionQuality:compressionQuality firstFrameOnly:firstFrameOnly];
return imageData;
}
@end

View File

@ -45,6 +45,7 @@
/**
Encode the current image to the data, the image format is unspecified
@note If the receiver is `SDAnimatedImage`, this will return the animated image data if available. No more extra encoding process.
@return The encoded data. If can't encode, return nil
*/
- (nullable NSData *)sd_imageData;