react-native-nitro-image-pipeline 1.3.2 → 1.5.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 +103 -11
- package/android/CMakeLists.txt +4 -0
- package/android/src/main/cpp/GaussianBlur.cpp +165 -0
- package/android/src/main/cpp/GaussianBlur.hpp +52 -0
- package/android/src/main/cpp/GaussianBlurJni.cpp +50 -0
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt +153 -74
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/PipelineImageLoader.kt +177 -0
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/BlurTransformation.kt +36 -81
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/HardwareBitmapTransformation.kt +45 -0
- package/ios/GaussianBlur.swift +48 -9
- package/ios/HybridNitroImagePipeline.swift +79 -33
- package/ios/PipelineImageLoader.swift +195 -0
- package/ios/RoundedCornersProcessor.swift +5 -0
- package/lib/commonjs/NativePipelineImage.js +71 -0
- package/lib/commonjs/NativePipelineImage.js.map +1 -0
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/usePipelineImageLoader.js +69 -0
- package/lib/commonjs/usePipelineImageLoader.js.map +1 -0
- package/lib/module/NativePipelineImage.js +67 -0
- package/lib/module/NativePipelineImage.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/usePipelineImageLoader.js +65 -0
- package/lib/module/usePipelineImageLoader.js.map +1 -0
- package/lib/typescript/src/NativePipelineImage.d.ts +66 -0
- package/lib/typescript/src/NativePipelineImage.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts +54 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts.map +1 -1
- package/lib/typescript/src/usePipelineImageLoader.d.ts +15 -0
- package/lib/typescript/src/usePipelineImageLoader.d.ts.map +1 -0
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.cpp +17 -0
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.hpp +2 -0
- package/nitrogen/generated/android/c++/JViewOptions.hpp +77 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipelineSpec.kt +9 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/ViewOptions.kt +66 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.cpp +10 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.hpp +53 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Umbrella.hpp +8 -0
- package/nitrogen/generated/ios/c++/HybridNitroImagePipelineSpecSwift.hpp +20 -0
- package/nitrogen/generated/ios/swift/HybridNitroImagePipelineSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridNitroImagePipelineSpec_cxx.swift +26 -0
- package/nitrogen/generated/ios/swift/ViewOptions.swift +101 -0
- package/nitrogen/generated/shared/c++/HybridNitroImagePipelineSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridNitroImagePipelineSpec.hpp +8 -0
- package/nitrogen/generated/shared/c++/ViewOptions.hpp +104 -0
- package/package.json +4 -3
- package/src/NativePipelineImage.tsx +103 -0
- package/src/index.ts +7 -0
- package/src/specs/nitro-image-toolkit.nitro.ts +56 -1
- package/src/usePipelineImageLoader.ts +82 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Image } from 'react-native-nitro-image';
|
|
1
|
+
import type { Image, ImageLoader } from 'react-native-nitro-image';
|
|
2
2
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
3
3
|
|
|
4
4
|
export type CacheOption = 'memory' | 'disk' | 'none';
|
|
@@ -65,11 +65,55 @@ export type Options = {
|
|
|
65
65
|
resize?: ResizeOptions;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Options for {@linkcode NitroImagePipeline.createImageLoader}. Unlike
|
|
70
|
+
* {@linkcode Options} (used by `loadImage`, where values are bitmap pixels),
|
|
71
|
+
* `blur` and `cornerRadius` here are in **points** (density-independent):
|
|
72
|
+
* the loader runs inside a view and converts to pixels natively with the
|
|
73
|
+
* screen scale. The one exception is {@linkcode resize}, which stays an
|
|
74
|
+
* explicit **pixel** size like everywhere else in the library.
|
|
75
|
+
*/
|
|
76
|
+
export type ViewOptions = {
|
|
77
|
+
/**
|
|
78
|
+
* Gaussian blur sigma in **points**. Multiplied by the screen scale
|
|
79
|
+
* natively, so the same value looks the same on every device.
|
|
80
|
+
* @default 0 (no blur)
|
|
81
|
+
*/
|
|
82
|
+
blur?: number;
|
|
83
|
+
cache?: CacheOption;
|
|
84
|
+
/**
|
|
85
|
+
* Corner radius in **points**, uniform or per-corner. Converted to pixels
|
|
86
|
+
* with the screen scale and baked into the bitmap at the display size.
|
|
87
|
+
* @default 0 (square corners)
|
|
88
|
+
*/
|
|
89
|
+
cornerRadius?: number | CornerRadii;
|
|
90
|
+
/**
|
|
91
|
+
* Target bitmap size in **pixels**, overriding the size measured from the
|
|
92
|
+
* view. Rarely needed — without it the loader resizes to the view's
|
|
93
|
+
* laid-out size × screen scale, which is what you want in a UI.
|
|
94
|
+
* @default undefined (measure the view)
|
|
95
|
+
*/
|
|
96
|
+
resize?: ResizeOptions;
|
|
97
|
+
};
|
|
98
|
+
|
|
68
99
|
export interface NitroImagePipeline extends HybridObject<{
|
|
69
100
|
ios: 'swift';
|
|
70
101
|
android: 'kotlin';
|
|
71
102
|
}> {
|
|
72
103
|
loadImage(url: string, options?: Options): Promise<Image>;
|
|
104
|
+
/**
|
|
105
|
+
* Creates an {@linkcode ImageLoader} for `url` that a `<NativeNitroImage>`
|
|
106
|
+
* view drives entirely natively: the request starts when the view attaches
|
|
107
|
+
* to the window — at the view's own laid-out size, with no JS round trips —
|
|
108
|
+
* and is cancelled (and the bitmap released) when it detaches, so
|
|
109
|
+
* off-screen list cells stop costing memory. Loads go through the same
|
|
110
|
+
* pipeline and caches as {@linkcode loadImage}/{@linkcode preLoadImage}.
|
|
111
|
+
*
|
|
112
|
+
* `options` are in **points** (see {@linkcode ViewOptions}); the loader
|
|
113
|
+
* applies the screen scale natively. If the view has no size yet when it
|
|
114
|
+
* attaches, the load waits for its first layout.
|
|
115
|
+
*/
|
|
116
|
+
createImageLoader(url: string, options?: ViewOptions): ImageLoader;
|
|
73
117
|
preLoadImage(url: string): Promise<void>;
|
|
74
118
|
preLoadImages(urls: string[]): Promise<void>;
|
|
75
119
|
/**
|
|
@@ -80,5 +124,16 @@ export interface NitroImagePipeline extends HybridObject<{
|
|
|
80
124
|
gaussianBlur(image: Image, radius: number): Promise<Image>;
|
|
81
125
|
// Future: brightness, saturation, tint, etc.
|
|
82
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Caps the in-memory cache of decoded bitmaps at `bytes`, evicting
|
|
129
|
+
* least-recently-used entries immediately if it is currently larger. Pass
|
|
130
|
+
* `0` to disable in-memory caching entirely (the disk cache still works).
|
|
131
|
+
*
|
|
132
|
+
* Defaults: 128 MB on iOS, 25% of the app's memory class on Android. The
|
|
133
|
+
* cache trades RAM for instant re-display; lower it (or use
|
|
134
|
+
* `cache: 'disk'` per request) in memory-constrained apps.
|
|
135
|
+
*/
|
|
136
|
+
setMemoryCacheLimit(bytes: number): void;
|
|
137
|
+
|
|
83
138
|
clearCache(): Promise<void>;
|
|
84
139
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import type { ImageLoader } from 'react-native-nitro-image';
|
|
3
|
+
|
|
4
|
+
import { NitroImagePipeline } from './NitroImagePipeline';
|
|
5
|
+
import type {
|
|
6
|
+
CornerRadii,
|
|
7
|
+
ViewOptions,
|
|
8
|
+
} from './specs/nitro-image-toolkit.nitro';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates (and memoizes) an {@linkcode ImageLoader} for `url` to pass to
|
|
12
|
+
* `<NativeNitroImage image={...} />`. The view drives it entirely natively:
|
|
13
|
+
* the request starts when the view attaches — at the view's laid-out size,
|
|
14
|
+
* with no JS round trips — and is cancelled when it detaches. See
|
|
15
|
+
* {@linkcode NitroImagePipeline.createImageLoader}.
|
|
16
|
+
*
|
|
17
|
+
* `blur`/`cornerRadius` are in **points** (unlike `useImage`, where they are
|
|
18
|
+
* bitmap pixels); the screen scale is applied natively. Inline object
|
|
19
|
+
* literals are fine — options are compared by value, not identity.
|
|
20
|
+
*/
|
|
21
|
+
export function usePipelineImageLoader(
|
|
22
|
+
url: string,
|
|
23
|
+
options?: ViewOptions,
|
|
24
|
+
): ImageLoader {
|
|
25
|
+
// Split the options into primitives (like useImage does) so an inline
|
|
26
|
+
// literal — a new identity every render — doesn't recreate the loader;
|
|
27
|
+
// recreating it would re-trigger the native load.
|
|
28
|
+
const blur = options?.blur;
|
|
29
|
+
const cache = options?.cache;
|
|
30
|
+
const cornerRadius = options?.cornerRadius;
|
|
31
|
+
const isUniformRadius = typeof cornerRadius === 'number';
|
|
32
|
+
const uniformRadius = isUniformRadius ? cornerRadius : 0;
|
|
33
|
+
const hasCornerObject = !isUniformRadius && cornerRadius !== undefined;
|
|
34
|
+
const {
|
|
35
|
+
topLeft = 0,
|
|
36
|
+
topRight = 0,
|
|
37
|
+
bottomLeft = 0,
|
|
38
|
+
bottomRight = 0,
|
|
39
|
+
} = isUniformRadius || cornerRadius === undefined ? {} : cornerRadius;
|
|
40
|
+
const resizeWidth = options?.resize?.width;
|
|
41
|
+
const resizeHeight = options?.resize?.height;
|
|
42
|
+
|
|
43
|
+
return useMemo(() => {
|
|
44
|
+
const cornerRadiusOption: number | CornerRadii | undefined = isUniformRadius
|
|
45
|
+
? uniformRadius
|
|
46
|
+
: hasCornerObject
|
|
47
|
+
? { topLeft, topRight, bottomLeft, bottomRight }
|
|
48
|
+
: undefined;
|
|
49
|
+
const stableOptions: ViewOptions = {
|
|
50
|
+
blur,
|
|
51
|
+
cache,
|
|
52
|
+
cornerRadius: cornerRadiusOption,
|
|
53
|
+
resize:
|
|
54
|
+
resizeWidth !== undefined && resizeHeight !== undefined
|
|
55
|
+
? { width: resizeWidth, height: resizeHeight }
|
|
56
|
+
: undefined,
|
|
57
|
+
};
|
|
58
|
+
const loader = NitroImagePipeline.createImageLoader(url, stableOptions);
|
|
59
|
+
// `NativeNitroImage` needs a way to tell two loader instances apart when
|
|
60
|
+
// diffing its `image` prop; tag the loader with what it will load (the
|
|
61
|
+
// same convention react-native-nitro-image's own loaders use).
|
|
62
|
+
Object.defineProperty(loader, '__source', {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
value: { url, options: stableOptions },
|
|
66
|
+
});
|
|
67
|
+
return loader;
|
|
68
|
+
}, [
|
|
69
|
+
url,
|
|
70
|
+
blur,
|
|
71
|
+
cache,
|
|
72
|
+
isUniformRadius,
|
|
73
|
+
uniformRadius,
|
|
74
|
+
hasCornerObject,
|
|
75
|
+
topLeft,
|
|
76
|
+
topRight,
|
|
77
|
+
bottomLeft,
|
|
78
|
+
bottomRight,
|
|
79
|
+
resizeWidth,
|
|
80
|
+
resizeHeight,
|
|
81
|
+
]);
|
|
82
|
+
}
|