Added sd_isThumbnail to mark metadata, avoid the case when full size image request re-use the image from thumbnail decoding for the same URL
I think this is a temp workaround
This commit is contained in:
parent
e7e9268a7e
commit
2c9290f109
|
@ -14,6 +14,8 @@
|
||||||
#import "SDInternalMacros.h"
|
#import "SDInternalMacros.h"
|
||||||
|
|
||||||
UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
|
UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
|
||||||
|
NSCParameterAssert(imageData);
|
||||||
|
NSCParameterAssert(cacheKey);
|
||||||
UIImage *image;
|
UIImage *image;
|
||||||
BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);
|
BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);
|
||||||
NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];
|
NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];
|
||||||
|
@ -79,6 +81,8 @@ UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSS
|
||||||
if (shouldDecode) {
|
if (shouldDecode) {
|
||||||
image = [SDImageCoderHelper decodedImageWithImage:image];
|
image = [SDImageCoderHelper decodedImageWithImage:image];
|
||||||
}
|
}
|
||||||
|
// mark the image as thumbnail, to let manager check whether to re-decode if needed
|
||||||
|
image.sd_isThumbnail = thumbnailSizeValue != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
|
@ -311,11 +311,14 @@ static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestination
|
||||||
// Which decode frames in time and reduce memory usage
|
// Which decode frames in time and reduce memory usage
|
||||||
if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {
|
if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {
|
||||||
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
|
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
|
||||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
if (imageRep) {
|
||||||
imageRep.size = size;
|
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
imageRep.size = size;
|
||||||
[animatedImage addRepresentation:imageRep];
|
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
||||||
return animatedImage;
|
[animatedImage addRepresentation:imageRep];
|
||||||
|
animatedImage.sd_imageFormat = self.class.imageFormat;
|
||||||
|
return animatedImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NS
|
||||||
if (shouldDecode) {
|
if (shouldDecode) {
|
||||||
image = [SDImageCoderHelper decodedImageWithImage:image];
|
image = [SDImageCoderHelper decodedImageWithImage:image];
|
||||||
}
|
}
|
||||||
|
// mark the image as thumbnail, to let manager check whether to re-decode if needed
|
||||||
|
image.sd_isThumbnail = thumbnailSizeValue != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
@ -204,6 +206,8 @@ UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull im
|
||||||
}
|
}
|
||||||
// mark the image as progressive (completed one are not mark as progressive)
|
// mark the image as progressive (completed one are not mark as progressive)
|
||||||
image.sd_isIncremental = !finished;
|
image.sd_isIncremental = !finished;
|
||||||
|
// mark the image as thumbnail, to let manager check whether to re-decode if needed
|
||||||
|
image.sd_isThumbnail = thumbnailSizeValue != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
|
@ -510,7 +510,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
// normally use the store cache type, but if target image is transformed, use original store cache type instead
|
// normally use the store cache type, but if target image is transformed, use original store cache type instead
|
||||||
SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType;
|
SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType;
|
||||||
UIImage *originalImage = downloadedImage;
|
UIImage *originalImage = downloadedImage;
|
||||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize];
|
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize] != nil;
|
||||||
if (thumbnailed) {
|
if (thumbnailed) {
|
||||||
// Thumbnail decoding does not keep original image
|
// Thumbnail decoding does not keep original image
|
||||||
// Here we only store the original data to disk for original cache key
|
// Here we only store the original data to disk for original cache key
|
||||||
|
@ -560,10 +560,16 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
}
|
}
|
||||||
id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];
|
id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];
|
||||||
|
|
||||||
|
// transformer check
|
||||||
BOOL shouldTransformImage = originalImage && transformer;
|
BOOL shouldTransformImage = originalImage && transformer;
|
||||||
shouldTransformImage = shouldTransformImage && (!originalImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage));
|
shouldTransformImage = shouldTransformImage && (!originalImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage));
|
||||||
shouldTransformImage = shouldTransformImage && (!originalImage.sd_isVector || (options & SDWebImageTransformVectorImage));
|
shouldTransformImage = shouldTransformImage && (!originalImage.sd_isVector || (options & SDWebImageTransformVectorImage));
|
||||||
// if available, store transformed image to cache
|
|
||||||
|
// thumbnail check
|
||||||
|
// This exist when previous thumbnail pipeline callback into next full size pipeline, because we share the same URL download but need different image
|
||||||
|
// Actually this is a hack, we attach the metadata into image object, which should design a better concept like `ImageInfo` and keep that around
|
||||||
|
BOOL shouldDecodeFullImage = originalImage.sd_isThumbnail && context[SDWebImageContextImageThumbnailPixelSize] == nil;
|
||||||
|
|
||||||
if (shouldTransformImage) {
|
if (shouldTransformImage) {
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
@ -587,6 +593,19 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (shouldDecodeFullImage) {
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||||
|
@autoreleasepool {
|
||||||
|
// transformed/thumbnailed cache key
|
||||||
|
NSString *key = [self cacheKeyForURL:url context:context];
|
||||||
|
// disable thumbnail decoding
|
||||||
|
SDWebImageMutableContext *tempContext = [context mutableCopy];
|
||||||
|
tempContext[SDWebImageContextImageThumbnailPixelSize] = nil;
|
||||||
|
UIImage *originalImage = SDImageCacheDecodeImageData(originalData, key, options, tempContext);
|
||||||
|
// Continue store transform cache process
|
||||||
|
[self callStoreTransformCacheProcessForOperation:operation url:url options:options context:context image:originalImage data:originalData cacheType:cacheType transformed:NO finished:finished completed:completedBlock];
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Continue store transform cache process
|
// Continue store transform cache process
|
||||||
[self callStoreTransformCacheProcessForOperation:operation url:url options:options context:context image:originalImage data:originalData cacheType:cacheType transformed:NO finished:finished completed:completedBlock];
|
[self callStoreTransformCacheProcessForOperation:operation url:url options:options context:context image:originalImage data:originalData cacheType:cacheType transformed:NO finished:finished completed:completedBlock];
|
||||||
|
@ -620,7 +639,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
// but the storeImage does not handle the thumbnail context option
|
// but the storeImage does not handle the thumbnail context option
|
||||||
// to keep exist SDImageCache's impl compatible, we introduce this helper
|
// to keep exist SDImageCache's impl compatible, we introduce this helper
|
||||||
NSData *cacheData = data;
|
NSData *cacheData = data;
|
||||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize];
|
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize] != nil;
|
||||||
if (thumbnailed) {
|
if (thumbnailed) {
|
||||||
// Thumbnail decoding already stored original data before in `storeCacheProcess`
|
// Thumbnail decoding already stored original data before in `storeCacheProcess`
|
||||||
// Here we only store the thumbnail image to memory for thumbnail cache key
|
// Here we only store the thumbnail image to memory for thumbnail cache key
|
||||||
|
|
|
@ -65,4 +65,9 @@
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign) BOOL sd_isIncremental;
|
@property (nonatomic, assign) BOOL sd_isIncremental;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A bool value indicating whether the image is from thumbnail decoding and may be smaller than the full image data pixel size.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, assign) BOOL sd_isThumbnail;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -186,4 +186,13 @@
|
||||||
return value.boolValue;
|
return value.boolValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setSd_isThumbnail:(BOOL)sd_isThumbnail {
|
||||||
|
objc_setAssociatedObject(self, @selector(sd_isThumbnail), @(sd_isThumbnail), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)sd_isThumbnail {
|
||||||
|
NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isThumbnail));
|
||||||
|
return value.boolValue;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -18,6 +18,7 @@ void SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable
|
||||||
}
|
}
|
||||||
// Image Metadata
|
// Image Metadata
|
||||||
target.sd_isIncremental = source.sd_isIncremental;
|
target.sd_isIncremental = source.sd_isIncremental;
|
||||||
|
target.sd_isThumbnail = source.sd_isThumbnail;
|
||||||
target.sd_imageLoopCount = source.sd_imageLoopCount;
|
target.sd_imageLoopCount = source.sd_imageLoopCount;
|
||||||
target.sd_imageFormat = source.sd_imageFormat;
|
target.sd_imageFormat = source.sd_imageFormat;
|
||||||
// Force Decode
|
// Force Decode
|
||||||
|
|
Loading…
Reference in New Issue