Add SDScaledImageForScaleFactor, make the API more clear. Fix the scale factor option issue
This commit is contained in:
parent
7a84e59eb1
commit
1a3fb834a0
|
@ -485,7 +485,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
if (data) {
|
||||
UIImage *image;
|
||||
BOOL decodeFirstFrame = options & SDImageCacheDecodeFirstFrameOnly;
|
||||
CGFloat scale = [context valueForKey:SDWebImageContextImageScaleFactor] ? [[context valueForKey:SDWebImageContextImageScaleFactor] doubleValue] : SDImageScaleForKey(key);
|
||||
NSNumber *scaleValue = [context valueForKey:SDWebImageContextImageScaleFactor];
|
||||
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(key);
|
||||
if (!decodeFirstFrame) {
|
||||
// check whether we should use `SDAnimatedImage`
|
||||
if ([context valueForKey:SDWebImageContextAnimatedImageClass]) {
|
||||
|
@ -499,7 +500,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
}
|
||||
if (!image) {
|
||||
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:data options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageContextImageScaleFactor : @(scale)}];
|
||||
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:data options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
|
||||
}
|
||||
BOOL shouldDecode = YES;
|
||||
if ([image conformsToProtocol:@protocol(SDAnimatedImage)]) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#endif
|
||||
#import "NSImage+Additions.h"
|
||||
#import "UIImage+WebCache.h"
|
||||
#import "SDWebImageDefine.h"
|
||||
|
||||
@interface SDWebImageCodersManager ()
|
||||
|
||||
|
@ -100,6 +101,13 @@
|
|||
return nil;
|
||||
}
|
||||
BOOL decodeFirstFrame = [[options valueForKey:SDWebImageCoderDecodeFirstFrameOnly] boolValue];
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
UIImage *image;
|
||||
for (id<SDWebImageCoder> coder in self.coders) {
|
||||
if ([coder canDecodeFromData:data]) {
|
||||
|
@ -107,8 +115,15 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (decodeFirstFrame && image.images.count > 0) {
|
||||
image = image.images.firstObject;
|
||||
if (image) {
|
||||
// Check static image
|
||||
if (decodeFirstFrame && image.images.count > 0) {
|
||||
image = image.images.firstObject;
|
||||
}
|
||||
// Check image scale
|
||||
if (scale > 1 && scale != image.scale) {
|
||||
image = SDScaledImageForScaleFactor(scale, image);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
|
|
|
@ -16,16 +16,19 @@ typedef NSMutableDictionary<SDWebImageContextOption, id> SDWebImageMutableContex
|
|||
#pragma mark - Image scale
|
||||
|
||||
/**
|
||||
Return the image scale from the specify key, supports file name and url key
|
||||
Return the image scale factor for the specify key, supports file name and url key.
|
||||
This is the built-in way to check the scale factor when we have no context about it. Because scale factor is not stored in image data (It's typically from filename).
|
||||
However, you can also provide custom scale factor as well, see `SDWebImageContextImageScaleFactor`.
|
||||
|
||||
@param key The image cache key
|
||||
@return The scale factor for image
|
||||
*/
|
||||
FOUNDATION_EXPORT CGFloat SDImageScaleForKey(NSString * _Nullable key);
|
||||
FOUNDATION_EXPORT CGFloat SDImageScaleFactorForKey(NSString * _Nullable key);
|
||||
|
||||
/**
|
||||
Scale the image with the scale factor from the specify key. If no need to scale, return the original image
|
||||
This only works for `UIImage`(UIKit) or `NSImage`(AppKit).
|
||||
Scale the image with the scale factor for the specify key. If no need to scale, return the original image.
|
||||
This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+WebCache`.
|
||||
@note This is actually a convenience function, which firstlly call `SDImageScaleFactorForKey` and then call `SDScaledImageForScaleFactor`, kept for backward compatibility.
|
||||
|
||||
@param key The image cache key
|
||||
@param image The image
|
||||
|
@ -33,6 +36,16 @@ FOUNDATION_EXPORT CGFloat SDImageScaleForKey(NSString * _Nullable key);
|
|||
*/
|
||||
FOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image);
|
||||
|
||||
/**
|
||||
Scale the image with the scale factor. If no need to scale, return the original image.
|
||||
This works for `UIImage`(UIKit) or `NSImage`(AppKit). And this function also preserve the associated value in `UIImage+WebCache`.
|
||||
|
||||
@param scale The image scale factor
|
||||
@param image The image
|
||||
@return The scaled image
|
||||
*/
|
||||
FOUNDATION_EXPORT UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image);
|
||||
|
||||
#pragma mark - WebCache Options
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
|
||||
|
|
|
@ -16,7 +16,7 @@ static inline NSArray<NSNumber *> * _Nonnull SDImageScaleFactors() {
|
|||
return @[@2, @3];
|
||||
}
|
||||
|
||||
inline CGFloat SDImageScaleForKey(NSString * _Nullable key) {
|
||||
inline CGFloat SDImageScaleFactorForKey(NSString * _Nullable key) {
|
||||
CGFloat scale = 1;
|
||||
if (!key) {
|
||||
return scale;
|
||||
|
@ -55,46 +55,56 @@ inline CGFloat SDImageScaleForKey(NSString * _Nullable key) {
|
|||
return scale;
|
||||
}
|
||||
|
||||
inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
|
||||
inline UIImage * _Nullable SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
|
||||
if (!image) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGFloat scale = SDImageScaleForKey(key);
|
||||
if (scale > 1) {
|
||||
UIImage *scaledImage;
|
||||
if (image.sd_isAnimated) {
|
||||
UIImage *animatedImage;
|
||||
CGFloat scale = SDImageScaleFactorForKey(key);
|
||||
return SDScaledImageForScaleFactor(scale, image);
|
||||
}
|
||||
|
||||
inline UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage * _Nullable image) {
|
||||
if (!image) {
|
||||
return nil;
|
||||
}
|
||||
if (scale <= 1) {
|
||||
return image;
|
||||
}
|
||||
if (scale == image.scale) {
|
||||
return image;
|
||||
}
|
||||
UIImage *scaledImage;
|
||||
if (image.sd_isAnimated) {
|
||||
UIImage *animatedImage;
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
// `UIAnimatedImage` images share the same size and scale.
|
||||
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
|
||||
|
||||
for (UIImage *tempImage in image.images) {
|
||||
UIImage *tempScaledImage = [[UIImage alloc] initWithCGImage:tempImage.CGImage scale:scale orientation:tempImage.imageOrientation];
|
||||
[scaledImages addObject:tempScaledImage];
|
||||
}
|
||||
|
||||
animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];
|
||||
animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;
|
||||
#else
|
||||
// Animated GIF for `NSImage` need to grab `NSBitmapImageRep`
|
||||
NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale);
|
||||
animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
NSBitmapImageRep *bitmapImageRep = image.bitmapImageRep;
|
||||
[animatedImage addRepresentation:bitmapImageRep];
|
||||
#endif
|
||||
scaledImage = animatedImage;
|
||||
} else {
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
#else
|
||||
scaledImage = [[NSImage alloc] initWithCGImage:image.CGImage size:NSZeroSize];
|
||||
#endif
|
||||
// `UIAnimatedImage` images share the same size and scale.
|
||||
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
|
||||
|
||||
for (UIImage *tempImage in image.images) {
|
||||
UIImage *tempScaledImage = [[UIImage alloc] initWithCGImage:tempImage.CGImage scale:scale orientation:tempImage.imageOrientation];
|
||||
[scaledImages addObject:tempScaledImage];
|
||||
}
|
||||
|
||||
return scaledImage;
|
||||
animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];
|
||||
animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;
|
||||
#else
|
||||
// Animated GIF for `NSImage` need to grab `NSBitmapImageRep`
|
||||
NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale);
|
||||
animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
NSBitmapImageRep *bitmapImageRep = image.bitmapImageRep;
|
||||
[animatedImage addRepresentation:bitmapImageRep];
|
||||
#endif
|
||||
scaledImage = animatedImage;
|
||||
} else {
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
#else
|
||||
scaledImage = [[NSImage alloc] initWithCGImage:image.CGImage size:NSZeroSize];
|
||||
#endif
|
||||
}
|
||||
return image;
|
||||
scaledImage.sd_isIncremental = image.sd_isIncremental;
|
||||
|
||||
return scaledImage;
|
||||
}
|
||||
|
||||
#pragma mark - Context option
|
||||
|
|
|
@ -364,7 +364,8 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
// check whether we should use `SDAnimatedImage`
|
||||
UIImage *image;
|
||||
BOOL decodeFirstFrame = self.options & SDWebImageDownloaderDecodeFirstFrameOnly;
|
||||
CGFloat scale = [self.context valueForKey:SDWebImageContextImageScaleFactor] ? [[self.context valueForKey:SDWebImageContextImageScaleFactor] doubleValue] : SDImageScaleForKey(self.cacheKey);
|
||||
NSNumber *scaleValue = [self.context valueForKey:SDWebImageContextImageScaleFactor];
|
||||
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(self.cacheKey);
|
||||
if (!decodeFirstFrame) {
|
||||
// check whether we should use `SDAnimatedImage`
|
||||
if ([self.context valueForKey:SDWebImageContextAnimatedImageClass]) {
|
||||
|
@ -375,7 +376,7 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
}
|
||||
}
|
||||
if (!image) {
|
||||
image = [self.progressiveCoder incrementalDecodedImageWithOptions:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageContextImageScaleFactor : @(scale)}];
|
||||
image = [self.progressiveCoder incrementalDecodedImageWithOptions:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
|
||||
}
|
||||
if (image) {
|
||||
BOOL shouldDecode = self.shouldDecompressImages;
|
||||
|
@ -456,7 +457,8 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
// decode the image in coder queue
|
||||
dispatch_async(self.coderQueue, ^{
|
||||
BOOL decodeFirstFrame = self.options & SDWebImageDownloaderDecodeFirstFrameOnly;
|
||||
CGFloat scale = [self.context valueForKey:SDWebImageContextImageScaleFactor] ? [[self.context valueForKey:SDWebImageContextImageScaleFactor] doubleValue] : SDImageScaleForKey(self.cacheKey);
|
||||
NSNumber *scaleValue = [self.context valueForKey:SDWebImageContextImageScaleFactor];
|
||||
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(self.cacheKey);
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
|
@ -474,7 +476,7 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
}
|
||||
}
|
||||
if (!image) {
|
||||
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:imageData options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageContextImageScaleFactor : @(scale)}];
|
||||
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:imageData options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
|
||||
}
|
||||
|
||||
BOOL shouldDecode = self.shouldDecompressImages;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* UIKit:
|
||||
* Check the `images` array property
|
||||
* AppKit:
|
||||
* NSImage currently only support animated via GIF imageRep unlike UIImage. It will check all the imageRef
|
||||
* NSImage currently only support animated via GIF imageRep unlike UIImage. It will check the imageRep's frame count.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL sd_isAnimated;
|
||||
|
||||
|
|
Loading…
Reference in New Issue