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"
|
||||
|
||||
UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSString * _Nonnull cacheKey, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
|
||||
NSCParameterAssert(imageData);
|
||||
NSCParameterAssert(cacheKey);
|
||||
UIImage *image;
|
||||
BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);
|
||||
NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];
|
||||
|
@ -79,6 +81,8 @@ UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSS
|
|||
if (shouldDecode) {
|
||||
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;
|
||||
|
|
|
@ -311,11 +311,14 @@ static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestination
|
|||
// Which decode frames in time and reduce memory usage
|
||||
if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {
|
||||
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
imageRep.size = size;
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:imageRep];
|
||||
return animatedImage;
|
||||
if (imageRep) {
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
imageRep.size = size;
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:imageRep];
|
||||
animatedImage.sd_imageFormat = self.class.imageFormat;
|
||||
return animatedImage;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -106,6 +106,8 @@ UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NS
|
|||
if (shouldDecode) {
|
||||
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;
|
||||
|
@ -204,6 +206,8 @@ UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull im
|
|||
}
|
||||
// mark the image as progressive (completed one are not mark as progressive)
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType;
|
||||
UIImage *originalImage = downloadedImage;
|
||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize];
|
||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize] != nil;
|
||||
if (thumbnailed) {
|
||||
// Thumbnail decoding does not keep original image
|
||||
// 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];
|
||||
|
||||
// transformer check
|
||||
BOOL shouldTransformImage = originalImage && transformer;
|
||||
shouldTransformImage = shouldTransformImage && (!originalImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage));
|
||||
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) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
@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 {
|
||||
// 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];
|
||||
|
@ -620,7 +639,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
// but the storeImage does not handle the thumbnail context option
|
||||
// to keep exist SDImageCache's impl compatible, we introduce this helper
|
||||
NSData *cacheData = data;
|
||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize];
|
||||
BOOL thumbnailed = context[SDWebImageContextImageThumbnailPixelSize] != nil;
|
||||
if (thumbnailed) {
|
||||
// Thumbnail decoding already stored original data before in `storeCacheProcess`
|
||||
// Here we only store the thumbnail image to memory for thumbnail cache key
|
||||
|
|
|
@ -65,4 +65,9 @@
|
|||
*/
|
||||
@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
|
||||
|
|
|
@ -186,4 +186,13 @@
|
|||
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
|
||||
|
|
|
@ -18,6 +18,7 @@ void SDImageCopyAssociatedObject(UIImage * _Nullable source, UIImage * _Nullable
|
|||
}
|
||||
// Image Metadata
|
||||
target.sd_isIncremental = source.sd_isIncremental;
|
||||
target.sd_isThumbnail = source.sd_isThumbnail;
|
||||
target.sd_imageLoopCount = source.sd_imageLoopCount;
|
||||
target.sd_imageFormat = source.sd_imageFormat;
|
||||
// Force Decode
|
||||
|
|
Loading…
Reference in New Issue