react-native-fast-image 8.27.3 → 8.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -276,7 +276,7 @@ Changing it restarts the animation.
|
|
|
276
276
|
How the image is filtered when it's drawn smaller or larger than its size (like CSS's `image-rendering`):
|
|
277
277
|
|
|
278
278
|
- `'auto'` **(Default)** - The platform's usual filtering.
|
|
279
|
-
- `'smooth'` - iOS only. Keeps a large image drawn much smaller than its size (e.g. a big photo as a thumbnail, or fine lines and text) from looking jagged or noisy. **It uses more memory:** the image is also kept at smaller sizes for drawing, about a third more than the decoded image. On Android it's the same as `'auto'` (images are
|
|
279
|
+
- `'smooth'` - iOS only. Keeps a large image drawn much smaller than its size (e.g. a big photo as a thumbnail, or fine lines and text) from looking jagged or noisy. Such an image is already decoded at about the view's size by default (see `downsample`), so this is for images shown at less than half their size with `downsample={false}`, or a little smaller than their size. **It uses more memory:** the image is also kept at smaller sizes for drawing, about a third more than the decoded image. On Android it's the same as `'auto'` (images are always decoded at about the view's size there).
|
|
280
280
|
- `'pixelated'` - Sharp pixels, without smoothing, e.g. for pixel art drawn larger than its size. On Android, animated images are still smoothed.
|
|
281
281
|
|
|
282
282
|
---
|
|
@@ -312,9 +312,12 @@ Downloads, local files (`file://`, `content://`) and bundled images (`require()`
|
|
|
312
312
|
|
|
313
313
|
iOS only. Decodes a large image at about the size it's shown at, instead of at full size, so it takes much less memory.
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
- `true` **(Default)** - An image at least twice the size its view needs is decoded at about the view's size. If the view grows, the image is decoded again for its new size (from the disk cache).
|
|
316
|
+
- `false` - Images are decoded at full size, e.g. for an image that's zoomed in on with a transform (a pinch-to-zoom viewer), which would otherwise show the smaller copy enlarged.
|
|
316
317
|
|
|
317
|
-
|
|
318
|
+
It doesn't change `onLoad`'s width and height (the image's own size) or the cached file. Needs SDWebImage 5.19.7 or later: before 5.19 images are decoded at full size, and 5.19.0 to 5.19.6 show photos stored sideways with an EXIF orientation (most phone photos) sideways. Photo library images are always decoded this way, and on Android images are always decoded at about the view's size.
|
|
319
|
+
|
|
320
|
+
If you control the images, serve them at the size they're shown (resized on your server or by an image CDN), which also saves bandwidth.
|
|
318
321
|
|
|
319
322
|
---
|
|
320
323
|
|
package/dist/index.d.ts
CHANGED
|
@@ -161,9 +161,9 @@ export interface FastImageProps extends AccessibilityProps, ViewProps {
|
|
|
161
161
|
transition?: boolean | number | Transition | null;
|
|
162
162
|
/**
|
|
163
163
|
* iOS only. Decodes a large image at about the size it's shown at, so it
|
|
164
|
-
* takes much less memory.
|
|
165
|
-
*
|
|
166
|
-
*
|
|
164
|
+
* takes much less memory. `true` (default). `false` decodes images at
|
|
165
|
+
* full size, e.g. for an image that's zoomed in on with a transform. See
|
|
166
|
+
* the README.
|
|
167
167
|
*/
|
|
168
168
|
downsample?: boolean;
|
|
169
169
|
/**
|
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
// the image's header before it decodes, as React Native's Image does.
|
|
11
11
|
@interface FFFDownsampledImage : SDAnimatedImage
|
|
12
12
|
|
|
13
|
-
// The url to load a source's url with, when it's downsampled.
|
|
14
|
-
+ (NSURL*) loadURLForURL: (NSURL*)url;
|
|
15
|
-
|
|
16
13
|
// Sets a load's context to decode the image for a box (in pixels) to cover
|
|
17
|
-
// or fit in.
|
|
18
|
-
+ (void) addToContext: (SDWebImageMutableContext*)context
|
|
14
|
+
// or fit in.
|
|
15
|
+
+ (void) addToContext: (SDWebImageMutableContext*)context box: (CGSize)box cover: (BOOL)cover;
|
|
16
|
+
|
|
17
|
+
// Sets a load's context to decode the image at full size, through this class
|
|
18
|
+
// when it's supported. Every FastImage load uses it, so loads of the same url
|
|
19
|
+
// can share a download: SDWebImage's downloader decodes each load of a
|
|
20
|
+
// download with the first load's image class (and each with its own size),
|
|
21
|
+
// and SDWebImage's own thumbnail decoding can't cover a box.
|
|
22
|
+
+ (void) addFullSizeToContext: (SDWebImageMutableContext*)context;
|
|
19
23
|
|
|
20
24
|
// The size of the full image (in points, like UIImage's size) that an image
|
|
21
25
|
// loaded this way was decoded from, for onLoad, or zero for other images.
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
#import <ImageIO/ImageIO.h>
|
|
3
3
|
#import <SDWebImage/SDImageCoder.h>
|
|
4
4
|
#import <SDWebImage/SDImageCacheDefine.h>
|
|
5
|
-
#import <SDWebImage/SDWebImageCacheKeyFilter.h>
|
|
6
5
|
#import <SDWebImage/UIImage+Metadata.h>
|
|
6
|
+
#import <SDWebImage/NSData+ImageContentType.h>
|
|
7
|
+
#import <SDWebImage/SDImageCodersManager.h>
|
|
7
8
|
|
|
8
9
|
// The decode option that carries the full image's size to the view.
|
|
9
10
|
static SDImageCoderOption const FFFDecodeSourceSize = @"FFFDecodeSourceSize";
|
|
10
|
-
// Added to the url's fragment, which isn't sent to the server.
|
|
11
|
-
static NSString* const FFFDownsampledFragment = @"fastimage-downsampled";
|
|
12
11
|
|
|
13
12
|
// The image's size in pixels as it's shown (EXIF orientations 5 to 8 turn it
|
|
14
13
|
// sideways), from its header, or zero if ImageIO can't read it.
|
|
@@ -83,38 +82,20 @@ static CGSize FFFPixelSize(NSData* data) {
|
|
|
83
82
|
return supported;
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
+ (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// wouldn't be used, and the box would be decoded as SDWebImage does (to
|
|
91
|
-
// fill it, stretched). With its own url, a downsampled load only shares
|
|
92
|
-
// downloads with other downsampled ones. Not a photo library url, which
|
|
93
|
-
// isn't downloaded, and whose loader reads everything after ph:// as the
|
|
94
|
-
// photo's identifier.
|
|
95
|
-
if ([url.scheme isEqualToString: @"ph"]) {
|
|
96
|
-
return url;
|
|
85
|
+
+ (void) addFullSizeToContext: (SDWebImageMutableContext*)context {
|
|
86
|
+
if (![self isSupported]) {
|
|
87
|
+
context[SDWebImageContextAnimatedImageClass] = [SDAnimatedImage class];
|
|
88
|
+
return;
|
|
97
89
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return url;
|
|
101
|
-
}
|
|
102
|
-
components.fragment = components.fragment.length > 0
|
|
103
|
-
? [components.fragment stringByAppendingFormat: @"-%@", FFFDownsampledFragment]
|
|
104
|
-
: FFFDownsampledFragment;
|
|
105
|
-
return components.URL ?: url;
|
|
90
|
+
context[SDWebImageContextAnimatedImageClass] = [FFFDownsampledImage class];
|
|
91
|
+
context[SDWebImageContextImageDecodeOptions] = @{FFFDecodeSourceSize: [FFFSourceSize new]};
|
|
106
92
|
}
|
|
107
93
|
|
|
108
|
-
+ (void) addToContext: (SDWebImageMutableContext*)context
|
|
94
|
+
+ (void) addToContext: (SDWebImageMutableContext*)context box: (CGSize)box cover: (BOOL)cover {
|
|
109
95
|
context[SDWebImageContextAnimatedImageClass] = [FFFDownsampledImage class];
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
context[SDWebImageContextCacheKeyFilter] = [SDWebImageCacheKeyFilter cacheKeyFilterWithBlock: ^NSString* (NSURL* _Nonnull loadURL) {
|
|
114
|
-
return key;
|
|
115
|
-
}];
|
|
116
|
-
// The memory cache key is the url with these (SDWebImage's thumbnail
|
|
117
|
-
// key), so views of other sizes don't get this image.
|
|
96
|
+
// The memory cache key is the source's key with these (SDWebImage's
|
|
97
|
+
// thumbnail key), so views of other sizes don't get this image. The disk
|
|
98
|
+
// cache keeps the downloaded file under the source's key, for every size.
|
|
118
99
|
context[SDWebImageContextImageThumbnailPixelSize] = [NSValue valueWithCGSize: box];
|
|
119
100
|
context[SDWebImageContextImagePreserveAspectRatio] = @(!cover);
|
|
120
101
|
context[SDWebImageContextImageDecodeOptions] = @{FFFDecodeSourceSize: [FFFSourceSize new]};
|
|
@@ -129,6 +110,22 @@ static CGSize FFFPixelSize(NSData* data) {
|
|
|
129
110
|
}
|
|
130
111
|
|
|
131
112
|
- (instancetype) initWithData: (NSData*)data scale: (CGFloat)scale options: (SDImageCoderOptions*)options {
|
|
113
|
+
// An SVG isn't decoded smaller: it's a vector image, drawn at any size.
|
|
114
|
+
// This class can't decode it, and SDWebImage would then give it to the
|
|
115
|
+
// SVG coder with the box, which draws it into a bitmap that size. Decoded
|
|
116
|
+
// as without downsample instead (this init can return another image).
|
|
117
|
+
if ([NSData sd_imageFormatForImageData: data] == SDImageFormatSVG) {
|
|
118
|
+
NSMutableDictionary* vectorOptions = options ? [options mutableCopy] : [NSMutableDictionary dictionary];
|
|
119
|
+
[vectorOptions removeObjectForKey: SDImageCoderDecodeThumbnailPixelSize];
|
|
120
|
+
UIImage* image = [[SDImageCodersManager sharedManager] decodedImageWithData: data options: vectorOptions];
|
|
121
|
+
FFFSourceSize* sourceSize = options[FFFDecodeSourceSize];
|
|
122
|
+
if (image && [sourceSize isKindOfClass: [FFFSourceSize class]]) {
|
|
123
|
+
sourceSize.size = image.size;
|
|
124
|
+
}
|
|
125
|
+
self = (id) image;
|
|
126
|
+
return self;
|
|
127
|
+
}
|
|
128
|
+
|
|
132
129
|
NSValue* boxValue = options[SDImageCoderDecodeThumbnailPixelSize];
|
|
133
130
|
CGSize box = boxValue ? boxValue.CGSizeValue : CGSizeZero;
|
|
134
131
|
NSNumber* preserveAspectRatio = options[SDImageCoderDecodePreserveAspectRatio];
|
|
@@ -88,6 +88,9 @@ static UIImage* FFFBlurredImage(UIImage* image, CGFloat scale, CGFloat radius, B
|
|
|
88
88
|
// rather than dimming like the system's controls.
|
|
89
89
|
self.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
|
|
90
90
|
_loopCount = -1;
|
|
91
|
+
// Images are decoded at about the size they're shown at unless
|
|
92
|
+
// downsample is false, as on Android.
|
|
93
|
+
_downsample = YES;
|
|
91
94
|
return self;
|
|
92
95
|
}
|
|
93
96
|
|
|
@@ -991,8 +994,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
991
994
|
}
|
|
992
995
|
CGSize box = [self decodeBox];
|
|
993
996
|
SDWebImageContext* context = [self contextForSource: source box: box cover: [self decodeCovers]];
|
|
994
|
-
|
|
995
|
-
NSString* key = [manager cacheKeyForURL: url context: context];
|
|
997
|
+
NSString* key = [manager cacheKeyForURL: source.url context: context];
|
|
996
998
|
return [(SDImageCache*) manager.imageCache imageFromMemoryCacheForKey: key] != nil;
|
|
997
999
|
}
|
|
998
1000
|
|
|
@@ -1002,15 +1004,14 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
1002
1004
|
context[SDWebImageContextImageLoader] = source.imageLoader;
|
|
1003
1005
|
context[SDWebImageContextCacheKeyFilter] = source.cacheKeyFilter;
|
|
1004
1006
|
if (CGSizeEqualToSize(box, CGSizeZero)) {
|
|
1005
|
-
|
|
1007
|
+
[FFFDownsampledImage addFullSizeToContext: context];
|
|
1006
1008
|
if (!source.memoryCache) {
|
|
1007
1009
|
// Only on disk, also when it comes from there.
|
|
1008
1010
|
context[SDWebImageContextStoreCacheType] = @(SDImageCacheTypeDisk);
|
|
1009
1011
|
}
|
|
1010
1012
|
return context;
|
|
1011
1013
|
}
|
|
1012
|
-
|
|
1013
|
-
[FFFDownsampledImage addToContext: context forKey: key box: box cover: cover];
|
|
1014
|
+
[FFFDownsampledImage addToContext: context box: box cover: cover];
|
|
1014
1015
|
if ([source isPhotoLibrary]) {
|
|
1015
1016
|
// Photos makes the photo at the size asked for, with no file
|
|
1016
1017
|
// downloaded: SDWebImage would keep this smaller copy on disk as the
|
|
@@ -1058,7 +1059,7 @@ NSString *FFFErrorMessage(NSError *error)
|
|
|
1058
1059
|
};
|
|
1059
1060
|
}
|
|
1060
1061
|
CFTimeInterval startedAt = CACurrentMediaTime();
|
|
1061
|
-
NSURL* url =
|
|
1062
|
+
NSURL* url = source.url;
|
|
1062
1063
|
if (!events) {
|
|
1063
1064
|
// Only this load's image: SDWebImage would clear the view (to the
|
|
1064
1065
|
// placeholder) if it fails, and a cancelled load can still complete.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "FFFastImageViewManager.h"
|
|
2
2
|
#import "FFFastImageView.h"
|
|
3
|
+
#import "FFFDownsampledImage.h"
|
|
3
4
|
|
|
4
5
|
#import <SDWebImage/SDImageCache.h>
|
|
5
6
|
#import <SDWebImage/SDWebImageManager.h>
|
|
@@ -128,13 +129,16 @@ RCT_REMAP_VIEW_PROPERTY(tintColor, imageColor, UIColor)
|
|
|
128
129
|
static NSMutableArray<dispatch_block_t> *FFFPendingPreloads;
|
|
129
130
|
static NSUInteger FFFPreloadsInFlight;
|
|
130
131
|
|
|
131
|
-
// A preload's context: the source's headers and cache key
|
|
132
|
+
// A preload's context: the source's headers and cache key, and the image
|
|
133
|
+
// class views use, so a view of the same url can share its download (see
|
|
134
|
+
// FFFDownsampledImage).
|
|
132
135
|
static SDWebImageMutableContext *FFFPreloadContext(FFFastImageSource *source)
|
|
133
136
|
{
|
|
134
137
|
SDWebImageMutableContext *context = [NSMutableDictionary dictionary];
|
|
135
138
|
context[SDWebImageContextDownloadRequestModifier] = source.requestModifier;
|
|
136
139
|
context[SDWebImageContextImageLoader] = source.imageLoader;
|
|
137
140
|
context[SDWebImageContextCacheKeyFilter] = source.cacheKeyFilter;
|
|
141
|
+
[FFFDownsampledImage addFullSizeToContext:context];
|
|
138
142
|
return context;
|
|
139
143
|
}
|
|
140
144
|
|