Merge pull request #2590 from dreampiggy/feature_transformer_cache_phase_1
Supports store original image to cache for transformer
This commit is contained in:
commit
5997f5a641
|
@ -203,11 +203,18 @@ FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageT
|
|||
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageScaleFactor;
|
||||
|
||||
/**
|
||||
A SDImageCacheType raw value which specify the cache type when the image has just been downloaded and will be stored to the cache. Specify `SDImageCacheTypeNone` to disable cache storage; `SDImageCacheTypeDisk` to store in disk cache only; `SDImageCacheTypeMemory` to store in memory only. And `SDImageCacheTypeAll` to store in both memory cache and disk cache.
|
||||
A SDImageCacheType raw value which specify the store cache type when the image has just been downloaded and will be stored to the cache. Specify `SDImageCacheTypeNone` to disable cache storage; `SDImageCacheTypeDisk` to store in disk cache only; `SDImageCacheTypeMemory` to store in memory only. And `SDImageCacheTypeAll` to store in both memory cache and disk cache.
|
||||
If you use image transformer feature, this actually apply for the transformed image, but not the original image itself. Use `SDWebImageContextOriginalStoreCacheType` if you want to control the original image's store cache type at the same time.
|
||||
If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber)
|
||||
*/
|
||||
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextStoreCacheType;
|
||||
|
||||
/**
|
||||
The same behavior like `SDWebImageContextStoreCacheType`, but control the store cache type for the original image when you use image transformer feature. This allows the detail control of cache storage for these two images. For example, if you want to store the transformed image into both memory/disk cache, store the original image into disk cache only, use `[.storeCacheType : .all, .originalStoreCacheType : .disk]`
|
||||
If not provide or the value is invalid, we will use `SDImageCacheTypeNone`, which does not store the original image into cache. (NSNumber)
|
||||
*/
|
||||
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextOriginalStoreCacheType;
|
||||
|
||||
/**
|
||||
A Class object which the instance is a `UIImage/NSImage` subclass and adopt `SDAnimatedImage` protocol. We will call `initWithData:scale:options:` to create the instance (or `initWithAnimatedCoder:scale:` when using progressive download) . If the instance create failed, fallback to normal `UIImage/NSImage`.
|
||||
This can be used to improve animated images rendering performance (especially memory usage on big animated images) with `SDAnimatedImageView` (Class).
|
||||
|
|
|
@ -123,6 +123,7 @@ SDWebImageContextOption const SDWebImageContextCustomManager = @"customManager";
|
|||
SDWebImageContextOption const SDWebImageContextImageTransformer = @"imageTransformer";
|
||||
SDWebImageContextOption const SDWebImageContextImageScaleFactor = @"imageScaleFactor";
|
||||
SDWebImageContextOption const SDWebImageContextStoreCacheType = @"storeCacheType";
|
||||
SDWebImageContextOption const SDWebImageContextOriginalStoreCacheType = @"originalStoreCacheType";
|
||||
SDWebImageContextOption const SDWebImageContextAnimatedImageClass = @"animatedImageClass";
|
||||
SDWebImageContextOption const SDWebImageContextDownloadRequestModifier = @"downloadRequestModifier";
|
||||
SDWebImageContextOption const SDWebImageContextCacheKeyFilter = @"cacheKeyFilter";
|
||||
|
|
|
@ -289,15 +289,41 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
finished:(BOOL)finished
|
||||
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||
// the target image store cache type
|
||||
SDImageCacheType storeCacheType = SDImageCacheTypeAll;
|
||||
if (context[SDWebImageContextStoreCacheType]) {
|
||||
storeCacheType = [context[SDWebImageContextStoreCacheType] integerValue];
|
||||
}
|
||||
// the original store image cache type
|
||||
SDImageCacheType originalStoreCacheType = SDImageCacheTypeNone;
|
||||
if (context[SDWebImageContextOriginalStoreCacheType]) {
|
||||
originalStoreCacheType = [context[SDWebImageContextOriginalStoreCacheType] integerValue];
|
||||
}
|
||||
id<SDWebImageCacheKeyFilter> cacheKeyFilter = context[SDWebImageContextCacheKeyFilter];
|
||||
NSString *key = [self cacheKeyForURL:url cacheKeyFilter:cacheKeyFilter];
|
||||
id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];
|
||||
id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];
|
||||
if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) {
|
||||
|
||||
BOOL shouldTransformImage = downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer;
|
||||
BOOL shouldCacheOriginal = downloadedImage && finished;
|
||||
|
||||
// if available, store original image to cache
|
||||
if (shouldCacheOriginal) {
|
||||
// normally use the store cache type, but if target image is transformed, use original store cache type instead
|
||||
SDImageCacheType targetStoreCacheType = shouldTransformImage ? originalStoreCacheType : storeCacheType;
|
||||
if (cacheSerializer && (targetStoreCacheType == SDImageCacheTypeDisk || targetStoreCacheType == SDImageCacheTypeAll)) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
@autoreleasepool {
|
||||
NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url];
|
||||
[self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key cacheType:targetStoreCacheType completion:nil];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
[self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key cacheType:targetStoreCacheType completion:nil];
|
||||
}
|
||||
}
|
||||
// if available, store transformed image to cache
|
||||
if (shouldTransformImage) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
@autoreleasepool {
|
||||
UIImage *transformedImage = [transformer transformedImageWithImage:downloadedImage forKey:key];
|
||||
|
@ -319,18 +345,6 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
}
|
||||
});
|
||||
} else {
|
||||
if (downloadedImage && finished) {
|
||||
if (cacheSerializer && (storeCacheType == SDImageCacheTypeDisk || storeCacheType == SDImageCacheTypeAll)) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
@autoreleasepool {
|
||||
NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url];
|
||||
[self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key cacheType:storeCacheType completion:nil];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
[self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key cacheType:storeCacheType completion:nil];
|
||||
}
|
||||
}
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:downloadedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,6 +212,40 @@
|
|||
[self waitForExpectationsWithCommonTimeout];
|
||||
}
|
||||
|
||||
- (void)test12ThatStoreCacheTypeWork {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"Image store cache type (including transformer) work"];
|
||||
|
||||
// Use a fresh manager && cache to avoid get effected by other test cases
|
||||
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"SDWebImageStoreCacheType"];
|
||||
SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:cache loader:SDWebImageDownloader.sharedDownloader];
|
||||
SDWebImageTestTransformer *transformer = [[SDWebImageTestTransformer alloc] init];
|
||||
transformer.testImage = [[UIImage alloc] initWithContentsOfFile:[self testJPEGPath]];
|
||||
manager.transformer = transformer;
|
||||
|
||||
// test: original image -> disk only, transformed image -> memory only
|
||||
SDWebImageContext *context = @{SDWebImageContextOriginalStoreCacheType : @(SDImageCacheTypeDisk), SDWebImageContextStoreCacheType : @(SDImageCacheTypeMemory)};
|
||||
NSURL *url = [NSURL URLWithString:kTestJPEGURL];
|
||||
NSString *originalKey = [manager cacheKeyForURL:url];
|
||||
NSString *transformedKey = SDTransformedKeyForKey(originalKey, transformer.transformerKey);
|
||||
|
||||
[manager loadImageWithURL:url options:SDWebImageTransformAnimatedImage context:context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||||
expect(image).equal(transformer.testImage);
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2*kMinDelayNanosecond), dispatch_get_main_queue(), ^{
|
||||
// original -> disk only
|
||||
[manager.imageCache containsImageForKey:originalKey cacheType:SDImageCacheTypeAll completion:^(SDImageCacheType originalCacheType) {
|
||||
expect(originalCacheType).equal(SDImageCacheTypeDisk);
|
||||
// transformed -> memory only
|
||||
[manager.imageCache containsImageForKey:transformedKey cacheType:SDImageCacheTypeAll completion:^(SDImageCacheType transformedCacheType) {
|
||||
expect(transformedCacheType).equal(SDImageCacheTypeMemory);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
}];
|
||||
});
|
||||
}];
|
||||
|
||||
[self waitForExpectationsWithCommonTimeout];
|
||||
}
|
||||
|
||||
- (NSString *)testJPEGPath {
|
||||
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
|
||||
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
|
||||
|
|
Loading…
Reference in New Issue