react-native-nitro-image-pipeline 1.1.0 → 1.2.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 +15 -6
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt +19 -0
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/ResizeTransformation.kt +59 -0
- package/ios/HybridNitroImagePipeline.swift +11 -0
- package/ios/RoundedCornersProcessor.swift +5 -2
- package/lib/commonjs/index.js +8 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +15 -8
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts +33 -5
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.cpp +4 -0
- package/nitrogen/generated/android/c++/JOptions.hpp +9 -3
- package/nitrogen/generated/android/c++/JResizeOptions.hpp +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/Options.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/ResizeOptions.kt +56 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.hpp +18 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridNitroImagePipelineSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/swift/Options.swift +12 -1
- package/nitrogen/generated/ios/swift/ResizeOptions.swift +34 -0
- package/nitrogen/generated/shared/c++/Options.hpp +9 -2
- package/nitrogen/generated/shared/c++/ResizeOptions.hpp +87 -0
- package/package.json +1 -1
- package/src/index.ts +23 -6
- package/src/specs/nitro-image-toolkit.nitro.ts +34 -5
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ A high-performance image loading, caching, and processing library for React Nati
|
|
|
10
10
|
|
|
11
11
|
- Load remote images with built-in memory and disk caching
|
|
12
12
|
- Prefetch single or multiple images in the background
|
|
13
|
-
-
|
|
13
|
+
- Resize (aspect-fill, center-crop) and apply Gaussian blur and rounded corners (uniform or per-corner) at load time
|
|
14
14
|
- Apply Gaussian blur to already-loaded images
|
|
15
15
|
- Clear the image cache on demand
|
|
16
16
|
- `useImage` hook for declarative image loading in components
|
|
@@ -46,10 +46,14 @@ The simplest way to load an image in a component:
|
|
|
46
46
|
import { useImage } from 'react-native-nitro-image-pipeline';
|
|
47
47
|
|
|
48
48
|
function MyComponent() {
|
|
49
|
+
const px = PixelRatio.get();
|
|
49
50
|
const { image, error } = useImage({
|
|
50
51
|
url: 'https://example.com/photo.jpg',
|
|
51
|
-
blur: 4, // Gaussian sigma in
|
|
52
|
-
|
|
52
|
+
blur: 4, // Gaussian sigma in bitmap pixels — same result on iOS and Android
|
|
53
|
+
// Resize to the size you display (points × screen scale) so the corner
|
|
54
|
+
// radii apply 1:1 to what you see instead of the full-resolution source.
|
|
55
|
+
resize: { width: 300 * px, height: 200 * px },
|
|
56
|
+
cornerRadius: 12 * px,
|
|
53
57
|
});
|
|
54
58
|
|
|
55
59
|
if (error) return <Text>Failed to load image</Text>;
|
|
@@ -65,9 +69,12 @@ function MyComponent() {
|
|
|
65
69
|
```ts
|
|
66
70
|
import { NitroImagePipeline } from 'react-native-nitro-image-pipeline';
|
|
67
71
|
|
|
68
|
-
// Load an image with options
|
|
72
|
+
// Load an image with options. resize and cornerRadius are in pixels of the
|
|
73
|
+
// produced bitmap: without resize, the radius applies to the full-resolution
|
|
74
|
+
// source and shrinks along with it when displayed small.
|
|
69
75
|
const image = await NitroImagePipeline.loadImage('https://example.com/photo.jpg', {
|
|
70
|
-
blur: 4, // Gaussian sigma in
|
|
76
|
+
blur: 4, // Gaussian sigma in bitmap pixels — see "Blur units"
|
|
77
|
+
resize: { width: 600, height: 400 }, // aspect-fill + center-crop, exact output size
|
|
71
78
|
cornerRadius: 12,
|
|
72
79
|
cache: 'disk',
|
|
73
80
|
});
|
|
@@ -75,6 +82,7 @@ const image = await NitroImagePipeline.loadImage('https://example.com/photo.jpg'
|
|
|
75
82
|
// Per-corner radii — e.g. a "ticket" shape with larger bottom corners.
|
|
76
83
|
// The rounding is baked into the bitmap, so no view-layer masking is needed.
|
|
77
84
|
const ticket = await NitroImagePipeline.loadImage('https://example.com/photo.jpg', {
|
|
85
|
+
resize: { width: 600, height: 400 },
|
|
78
86
|
cornerRadius: { topLeft: 24, topRight: 24, bottomLeft: 48, bottomRight: 48 },
|
|
79
87
|
});
|
|
80
88
|
|
|
@@ -103,7 +111,8 @@ Loads an image from a URL and returns a `Promise<Image>`.
|
|
|
103
111
|
| Option | Type | Default | Description |
|
|
104
112
|
|---|---|---|---|
|
|
105
113
|
| `blur` | `number` | `0` | Gaussian blur strength applied at load time — see [Blur units](#blur-units) |
|
|
106
|
-
| `
|
|
114
|
+
| `resize` | `{ width, height }` | source size | Target bitmap size in pixels. Scales to fill and center-crops (CSS `object-fit: cover`, upscaling if needed) before `blur`/`cornerRadius` run, so their pixel units refer to this final size. Typically your display size in points × `PixelRatio.get()` |
|
|
115
|
+
| `cornerRadius` | `number \| CornerRadii` | `0` | Corner radius in pixels of the produced bitmap — a single number for all four corners, or `{ topLeft?, topRight?, bottomLeft?, bottomRight? }` for independent per-corner radii (omitted corners stay square). Pair with `resize` for radii that match your layout |
|
|
107
116
|
| `cache` | `'memory' \| 'disk' \| 'none'` | platform default | Caching strategy |
|
|
108
117
|
|
|
109
118
|
### `preLoadImage(url)`
|
package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt
CHANGED
|
@@ -14,6 +14,7 @@ import coil3.request.ImageRequest
|
|
|
14
14
|
import coil3.request.SuccessResult
|
|
15
15
|
import coil3.request.allowHardware
|
|
16
16
|
import coil3.request.transformations
|
|
17
|
+
import coil3.size.Scale
|
|
17
18
|
import coil3.size.Size
|
|
18
19
|
import coil3.transform.RoundedCornersTransformation
|
|
19
20
|
import com.google.net.cronet.okhttptransport.CronetInterceptor
|
|
@@ -22,6 +23,8 @@ import com.margelo.nitro.core.Promise
|
|
|
22
23
|
import com.margelo.nitro.image.HybridImage
|
|
23
24
|
import com.margelo.nitro.image.HybridImageSpec
|
|
24
25
|
import com.margelo.nitro.nitroimagepipeline.transform.BlurTransformation
|
|
26
|
+
import com.margelo.nitro.nitroimagepipeline.transform.ResizeTransformation
|
|
27
|
+
import kotlin.math.roundToInt
|
|
25
28
|
import kotlinx.coroutines.Dispatchers
|
|
26
29
|
import kotlinx.coroutines.async
|
|
27
30
|
import kotlinx.coroutines.awaitAll
|
|
@@ -40,7 +43,16 @@ class HybridNitroImagePipeline : HybridNitroImagePipelineSpec() {
|
|
|
40
43
|
|
|
41
44
|
override fun loadImage(url: String, options: Options?): Promise<HybridImageSpec> = Promise.async {
|
|
42
45
|
val blur = options?.blur?.toFloat() ?: 0f
|
|
46
|
+
val resize =
|
|
47
|
+
options?.resize?.let { r ->
|
|
48
|
+
val width = r.width.roundToInt()
|
|
49
|
+
val height = r.height.roundToInt()
|
|
50
|
+
if (width > 0 && height > 0) width to height else null
|
|
51
|
+
}
|
|
43
52
|
val transformations = buildList {
|
|
53
|
+
// Resize first: blur sigma and corner radii are in pixels of the bitmap
|
|
54
|
+
// they run on, so they must see the final size.
|
|
55
|
+
resize?.let { (width, height) -> add(ResizeTransformation(width, height)) }
|
|
44
56
|
if (blur > 0f) add(BlurTransformation(context, blur))
|
|
45
57
|
options?.cornerRadius?.match(
|
|
46
58
|
first = { radius ->
|
|
@@ -77,6 +89,13 @@ class HybridNitroImagePipeline : HybridNitroImagePipelineSpec() {
|
|
|
77
89
|
}
|
|
78
90
|
null -> Unit // Coil defaults: both enabled
|
|
79
91
|
}
|
|
92
|
+
// Ask the decoder for the target size so a large source is
|
|
93
|
+
// subsampled near it instead of decoded at full resolution;
|
|
94
|
+
// ResizeTransformation then makes the size exact.
|
|
95
|
+
resize?.let { (width, height) ->
|
|
96
|
+
size(width, height)
|
|
97
|
+
scale(Scale.FILL)
|
|
98
|
+
}
|
|
80
99
|
}
|
|
81
100
|
.allowHardware(true)
|
|
82
101
|
.transformations(transformations)
|
package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/ResizeTransformation.kt
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package com.margelo.nitro.nitroimagepipeline.transform
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Matrix
|
|
6
|
+
import android.graphics.Paint
|
|
7
|
+
import coil3.size.Size
|
|
8
|
+
import coil3.transform.Transformation
|
|
9
|
+
import kotlin.math.max
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Scales the input to fill exactly [width] × [height] pixels and center-crops the overflow (CSS
|
|
13
|
+
* `object-fit: cover`), upscaling smaller sources. It runs before [BlurTransformation] and rounded
|
|
14
|
+
* corners so their pixel units refer to the final bitmap — matching Nuke's
|
|
15
|
+
* `ImageProcessors.Resize(contentMode: .aspectFill, crop: true)` on iOS.
|
|
16
|
+
*/
|
|
17
|
+
class ResizeTransformation(
|
|
18
|
+
private val width: Int,
|
|
19
|
+
private val height: Int,
|
|
20
|
+
) : Transformation() {
|
|
21
|
+
|
|
22
|
+
init {
|
|
23
|
+
require(width > 0 && height > 0) { "width and height must be > 0." }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override val cacheKey = "${ResizeTransformation::class.java.name}-$width-$height"
|
|
27
|
+
|
|
28
|
+
override suspend fun transform(input: Bitmap, size: Size): Bitmap {
|
|
29
|
+
val softwareInput =
|
|
30
|
+
if (input.config == Bitmap.Config.HARDWARE) input.copy(Bitmap.Config.ARGB_8888, false)
|
|
31
|
+
else input
|
|
32
|
+
if (softwareInput.width == width && softwareInput.height == height) return softwareInput
|
|
33
|
+
|
|
34
|
+
val scale =
|
|
35
|
+
max(width.toFloat() / softwareInput.width, height.toFloat() / softwareInput.height)
|
|
36
|
+
val matrix =
|
|
37
|
+
Matrix().apply {
|
|
38
|
+
setScale(scale, scale)
|
|
39
|
+
postTranslate(
|
|
40
|
+
(width - softwareInput.width * scale) / 2f,
|
|
41
|
+
(height - softwareInput.height * scale) / 2f,
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
val config = softwareInput.config ?: Bitmap.Config.ARGB_8888
|
|
45
|
+
val output = Bitmap.createBitmap(width, height, config)
|
|
46
|
+
Canvas(output)
|
|
47
|
+
.drawBitmap(softwareInput, matrix, Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG))
|
|
48
|
+
return output
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override fun equals(other: Any?): Boolean {
|
|
52
|
+
if (this === other) return true
|
|
53
|
+
return other is ResizeTransformation && width == other.width && height == other.height
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override fun hashCode(): Int = 31 * width + height
|
|
57
|
+
|
|
58
|
+
override fun toString() = "ResizeTransformation(width=$width, height=$height)"
|
|
59
|
+
}
|
|
@@ -117,6 +117,17 @@ class HybridNitroImagePipeline: HybridNitroImagePipelineSpec {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
var processors: [any ImageProcessing] = []
|
|
120
|
+
// Resize first: blur sigma and corner radii are defined in pixels
|
|
121
|
+
// of the bitmap they run on, so they must see the final size.
|
|
122
|
+
if let resize = options?.resize, resize.width > 0, resize.height > 0 {
|
|
123
|
+
processors.append(ImageProcessors.Resize(
|
|
124
|
+
size: CGSize(width: resize.width, height: resize.height),
|
|
125
|
+
unit: .pixels,
|
|
126
|
+
contentMode: .aspectFill,
|
|
127
|
+
crop: true,
|
|
128
|
+
upscale: true
|
|
129
|
+
))
|
|
130
|
+
}
|
|
120
131
|
if let blur = options?.blur, blur > 0 {
|
|
121
132
|
processors.append(GaussianBlurProcessor(sigma: blur))
|
|
122
133
|
}
|
|
@@ -12,8 +12,11 @@ import Foundation
|
|
|
12
12
|
import Nuke
|
|
13
13
|
import UIKit
|
|
14
14
|
|
|
15
|
-
/// Nuke processor that rounds each corner with its own radius
|
|
16
|
-
/// like `ImageProcessors.RoundedCorners`
|
|
15
|
+
/// Nuke processor that rounds each corner with its own radius, measured in
|
|
16
|
+
/// pixels of the bitmap it receives (like `ImageProcessors.RoundedCorners`
|
|
17
|
+
/// with `unit: .points` on the scale-1 images the pipeline decodes). Runs
|
|
18
|
+
/// after `ImageProcessors.Resize` when `Options.resize` is set, so the radii
|
|
19
|
+
/// refer to the final output size.
|
|
17
20
|
struct RoundedCornersProcessor: ImageProcessing {
|
|
18
21
|
let topLeft: CGFloat
|
|
19
22
|
let topRight: CGFloat
|
package/lib/commonjs/index.js
CHANGED
|
@@ -20,6 +20,7 @@ function useImage({
|
|
|
20
20
|
url,
|
|
21
21
|
blur = 0,
|
|
22
22
|
cornerRadius = 0,
|
|
23
|
+
resize,
|
|
23
24
|
cache
|
|
24
25
|
}) {
|
|
25
26
|
const [image, setImage] = (0, _react.useState)({
|
|
@@ -38,6 +39,8 @@ function useImage({
|
|
|
38
39
|
bottomLeft = 0,
|
|
39
40
|
bottomRight = 0
|
|
40
41
|
} = isUniformRadius ? {} : cornerRadius;
|
|
42
|
+
const resizeWidth = resize?.width ?? 0;
|
|
43
|
+
const resizeHeight = resize?.height ?? 0;
|
|
41
44
|
(0, _react.useEffect)(() => {
|
|
42
45
|
let cancelled = false;
|
|
43
46
|
// Only reset to the loading state when the URL changes; for same-URL
|
|
@@ -60,6 +63,10 @@ function useImage({
|
|
|
60
63
|
bottomLeft,
|
|
61
64
|
bottomRight
|
|
62
65
|
},
|
|
66
|
+
resize: resizeWidth > 0 && resizeHeight > 0 ? {
|
|
67
|
+
width: resizeWidth,
|
|
68
|
+
height: resizeHeight
|
|
69
|
+
} : undefined,
|
|
63
70
|
cache
|
|
64
71
|
});
|
|
65
72
|
if (!cancelled) {
|
|
@@ -81,7 +88,7 @@ function useImage({
|
|
|
81
88
|
return () => {
|
|
82
89
|
cancelled = true;
|
|
83
90
|
};
|
|
84
|
-
}, [url, blur, isUniformRadius, uniformRadius, topLeft, topRight, bottomLeft, bottomRight, cache]);
|
|
91
|
+
}, [url, blur, isUniformRadius, uniformRadius, topLeft, topRight, bottomLeft, bottomRight, resizeWidth, resizeHeight, cache]);
|
|
85
92
|
return image;
|
|
86
93
|
}
|
|
87
94
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNativeNitroModules","NitroImagePipeline","exports","NitroModules","createHybridObject","useImage","url","blur","cornerRadius","cache","image","setImage","useState","undefined","error","loadedUrlRef","useRef","isUniformRadius","uniformRadius","topLeft","topRight","bottomLeft","bottomRight","useEffect","cancelled","current","result","loadImage","e","Error"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,wBAAA,GAAAD,OAAA;
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNativeNitroModules","NitroImagePipeline","exports","NitroModules","createHybridObject","useImage","url","blur","cornerRadius","resize","cache","image","setImage","useState","undefined","error","loadedUrlRef","useRef","isUniformRadius","uniformRadius","topLeft","topRight","bottomLeft","bottomRight","resizeWidth","width","resizeHeight","height","useEffect","cancelled","current","result","loadImage","e","Error"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,wBAAA,GAAAD,OAAA;AAYO,MAAME,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,GAC7BE,qCAAY,CAACC,kBAAkB,CAAyB,oBAAoB,CAAC;AAmB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,QAAQA,CAAC;EACvBC,GAAG;EACHC,IAAI,GAAG,CAAC;EACRC,YAAY,GAAG,CAAC;EAChBC,MAAM;EACNC;AAuBF,CAAC,EAAU;EACT,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAG,IAAAC,eAAQ,EAAS;IACzCF,KAAK,EAAEG,SAAS;IAChBC,KAAK,EAAED;EACT,CAAC,CAAC;EACF,MAAME,YAAY,GAAG,IAAAC,aAAM,EAACX,GAAG,CAAC;;EAEhC;EACA;EACA,MAAMY,eAAe,GAAG,OAAOV,YAAY,KAAK,QAAQ;EACxD,MAAMW,aAAa,GAAGD,eAAe,GAAGV,YAAY,GAAG,CAAC;EACxD,MAAM;IACJY,OAAO,GAAG,CAAC;IACXC,QAAQ,GAAG,CAAC;IACZC,UAAU,GAAG,CAAC;IACdC,WAAW,GAAG;EAChB,CAAC,GAAGL,eAAe,GAAG,CAAC,CAAC,GAAGV,YAAY;EACvC,MAAMgB,WAAW,GAAGf,MAAM,EAAEgB,KAAK,IAAI,CAAC;EACtC,MAAMC,YAAY,GAAGjB,MAAM,EAAEkB,MAAM,IAAI,CAAC;EAExC,IAAAC,gBAAS,EAAC,MAAM;IACd,IAAIC,SAAS,GAAG,KAAK;IACrB;IACA;IACA;IACA,IAAIb,YAAY,CAACc,OAAO,KAAKxB,GAAG,EAAE;MAChCU,YAAY,CAACc,OAAO,GAAGxB,GAAG;MAC1BM,QAAQ,CAAC;QAAED,KAAK,EAAEG,SAAS;QAAEC,KAAK,EAAED;MAAU,CAAC,CAAC;IAClD;IAEA,CAAC,YAAY;MACX,IAAI;QACF,MAAMiB,MAAM,GAAG,MAAM9B,kBAAkB,CAAC+B,SAAS,CAAC1B,GAAG,EAAE;UACrDC,IAAI;UACJC,YAAY,EAAEU,eAAe,GACzBC,aAAa,GACb;YAAEC,OAAO;YAAEC,QAAQ;YAAEC,UAAU;YAAEC;UAAY,CAAC;UAClDd,MAAM,EACJe,WAAW,GAAG,CAAC,IAAIE,YAAY,GAAG,CAAC,GAC/B;YAAED,KAAK,EAAED,WAAW;YAAEG,MAAM,EAAED;UAAa,CAAC,GAC5CZ,SAAS;UACfJ;QACF,CAAC,CAAC;QAEF,IAAI,CAACmB,SAAS,EAAE;UACdjB,QAAQ,CAAC;YAAED,KAAK,EAAEoB,MAAM;YAAEhB,KAAK,EAAED;UAAU,CAAC,CAAC;QAC/C;MACF,CAAC,CAAC,OAAOmB,CAAC,EAAE;QACV,MAAMlB,KAAK,GAAGkB,CAAC,YAAYC,KAAK,GAAGD,CAAC,GAAG,IAAIC,KAAK,CAAC,GAAGD,CAAC,EAAE,CAAC;QACxD,IAAI,CAACJ,SAAS,EAAE;UACdjB,QAAQ,CAAC;YAAED,KAAK,EAAEG,SAAS;YAAEC,KAAK,EAAEA;UAAM,CAAC,CAAC;QAC9C;MACF;IACF,CAAC,EAAE,CAAC;IAEJ,OAAO,MAAM;MACXc,SAAS,GAAG,IAAI;IAClB,CAAC;EACH,CAAC,EAAE,CACDvB,GAAG,EACHC,IAAI,EACJW,eAAe,EACfC,aAAa,EACbC,OAAO,EACPC,QAAQ,EACRC,UAAU,EACVC,WAAW,EACXC,WAAW,EACXE,YAAY,EACZhB,KAAK,CACN,CAAC;EAEF,OAAOC,KAAK;AACd","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export function useImage({
|
|
|
15
15
|
url,
|
|
16
16
|
blur = 0,
|
|
17
17
|
cornerRadius = 0,
|
|
18
|
+
resize,
|
|
18
19
|
cache
|
|
19
20
|
}) {
|
|
20
21
|
const [image, setImage] = useState({
|
|
@@ -33,6 +34,8 @@ export function useImage({
|
|
|
33
34
|
bottomLeft = 0,
|
|
34
35
|
bottomRight = 0
|
|
35
36
|
} = isUniformRadius ? {} : cornerRadius;
|
|
37
|
+
const resizeWidth = resize?.width ?? 0;
|
|
38
|
+
const resizeHeight = resize?.height ?? 0;
|
|
36
39
|
useEffect(() => {
|
|
37
40
|
let cancelled = false;
|
|
38
41
|
// Only reset to the loading state when the URL changes; for same-URL
|
|
@@ -55,6 +58,10 @@ export function useImage({
|
|
|
55
58
|
bottomLeft,
|
|
56
59
|
bottomRight
|
|
57
60
|
},
|
|
61
|
+
resize: resizeWidth > 0 && resizeHeight > 0 ? {
|
|
62
|
+
width: resizeWidth,
|
|
63
|
+
height: resizeHeight
|
|
64
|
+
} : undefined,
|
|
58
65
|
cache
|
|
59
66
|
});
|
|
60
67
|
if (!cancelled) {
|
|
@@ -76,7 +83,7 @@ export function useImage({
|
|
|
76
83
|
return () => {
|
|
77
84
|
cancelled = true;
|
|
78
85
|
};
|
|
79
|
-
}, [url, blur, isUniformRadius, uniformRadius, topLeft, topRight, bottomLeft, bottomRight, cache]);
|
|
86
|
+
}, [url, blur, isUniformRadius, uniformRadius, topLeft, topRight, bottomLeft, bottomRight, resizeWidth, resizeHeight, cache]);
|
|
80
87
|
return image;
|
|
81
88
|
}
|
|
82
89
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","useState","NitroModules","NitroImagePipeline","createHybridObject","useImage","url","blur","cornerRadius","cache","image","setImage","undefined","error","loadedUrlRef","isUniformRadius","uniformRadius","topLeft","topRight","bottomLeft","bottomRight","cancelled","current","result","loadImage","e","Error"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAEnD,SAASC,YAAY,QAAQ,4BAA4B;
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","useState","NitroModules","NitroImagePipeline","createHybridObject","useImage","url","blur","cornerRadius","resize","cache","image","setImage","undefined","error","loadedUrlRef","isUniformRadius","uniformRadius","topLeft","topRight","bottomLeft","bottomRight","resizeWidth","width","resizeHeight","height","cancelled","current","result","loadImage","e","Error"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAEnD,SAASC,YAAY,QAAQ,4BAA4B;AAYzD,OAAO,MAAMC,kBAAkB,GAC7BD,YAAY,CAACE,kBAAkB,CAAyB,oBAAoB,CAAC;AAmB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,QAAQA,CAAC;EACvBC,GAAG;EACHC,IAAI,GAAG,CAAC;EACRC,YAAY,GAAG,CAAC;EAChBC,MAAM;EACNC;AAuBF,CAAC,EAAU;EACT,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGX,QAAQ,CAAS;IACzCU,KAAK,EAAEE,SAAS;IAChBC,KAAK,EAAED;EACT,CAAC,CAAC;EACF,MAAME,YAAY,GAAGf,MAAM,CAACM,GAAG,CAAC;;EAEhC;EACA;EACA,MAAMU,eAAe,GAAG,OAAOR,YAAY,KAAK,QAAQ;EACxD,MAAMS,aAAa,GAAGD,eAAe,GAAGR,YAAY,GAAG,CAAC;EACxD,MAAM;IACJU,OAAO,GAAG,CAAC;IACXC,QAAQ,GAAG,CAAC;IACZC,UAAU,GAAG,CAAC;IACdC,WAAW,GAAG;EAChB,CAAC,GAAGL,eAAe,GAAG,CAAC,CAAC,GAAGR,YAAY;EACvC,MAAMc,WAAW,GAAGb,MAAM,EAAEc,KAAK,IAAI,CAAC;EACtC,MAAMC,YAAY,GAAGf,MAAM,EAAEgB,MAAM,IAAI,CAAC;EAExC1B,SAAS,CAAC,MAAM;IACd,IAAI2B,SAAS,GAAG,KAAK;IACrB;IACA;IACA;IACA,IAAIX,YAAY,CAACY,OAAO,KAAKrB,GAAG,EAAE;MAChCS,YAAY,CAACY,OAAO,GAAGrB,GAAG;MAC1BM,QAAQ,CAAC;QAAED,KAAK,EAAEE,SAAS;QAAEC,KAAK,EAAED;MAAU,CAAC,CAAC;IAClD;IAEA,CAAC,YAAY;MACX,IAAI;QACF,MAAMe,MAAM,GAAG,MAAMzB,kBAAkB,CAAC0B,SAAS,CAACvB,GAAG,EAAE;UACrDC,IAAI;UACJC,YAAY,EAAEQ,eAAe,GACzBC,aAAa,GACb;YAAEC,OAAO;YAAEC,QAAQ;YAAEC,UAAU;YAAEC;UAAY,CAAC;UAClDZ,MAAM,EACJa,WAAW,GAAG,CAAC,IAAIE,YAAY,GAAG,CAAC,GAC/B;YAAED,KAAK,EAAED,WAAW;YAAEG,MAAM,EAAED;UAAa,CAAC,GAC5CX,SAAS;UACfH;QACF,CAAC,CAAC;QAEF,IAAI,CAACgB,SAAS,EAAE;UACdd,QAAQ,CAAC;YAAED,KAAK,EAAEiB,MAAM;YAAEd,KAAK,EAAED;UAAU,CAAC,CAAC;QAC/C;MACF,CAAC,CAAC,OAAOiB,CAAC,EAAE;QACV,MAAMhB,KAAK,GAAGgB,CAAC,YAAYC,KAAK,GAAGD,CAAC,GAAG,IAAIC,KAAK,CAAC,GAAGD,CAAC,EAAE,CAAC;QACxD,IAAI,CAACJ,SAAS,EAAE;UACdd,QAAQ,CAAC;YAAED,KAAK,EAAEE,SAAS;YAAEC,KAAK,EAAEA;UAAM,CAAC,CAAC;QAC9C;MACF;IACF,CAAC,EAAE,CAAC;IAEJ,OAAO,MAAM;MACXY,SAAS,GAAG,IAAI;IAClB,CAAC;EACH,CAAC,EAAE,CACDpB,GAAG,EACHC,IAAI,EACJS,eAAe,EACfC,aAAa,EACbC,OAAO,EACPC,QAAQ,EACRC,UAAU,EACVC,WAAW,EACXC,WAAW,EACXE,YAAY,EACZd,KAAK,CACN,CAAC;EAEF,OAAOC,KAAK;AACd","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Image } from 'react-native-nitro-image';
|
|
2
|
-
import type { CacheOption, CornerRadii, NitroImagePipeline as NitroImagePipelineSpec, Options } from './specs/nitro-image-toolkit.nitro';
|
|
3
|
-
export type { CacheOption, CornerRadii, Options };
|
|
2
|
+
import type { CacheOption, CornerRadii, NitroImagePipeline as NitroImagePipelineSpec, Options, ResizeOptions } from './specs/nitro-image-toolkit.nitro';
|
|
3
|
+
export type { CacheOption, CornerRadii, Options, ResizeOptions };
|
|
4
4
|
export declare const NitroImagePipeline: NitroImagePipelineSpec;
|
|
5
5
|
type Result = {
|
|
6
6
|
image: undefined;
|
|
@@ -20,20 +20,27 @@ type Result = {
|
|
|
20
20
|
* const { image, error } = useImage({ filePath: '/tmp/image.jpg' })
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
export declare function useImage({ url, blur, cornerRadius, cache, }: {
|
|
23
|
+
export declare function useImage({ url, blur, cornerRadius, resize, cache, }: {
|
|
24
24
|
url: string;
|
|
25
25
|
/**
|
|
26
26
|
* Gaussian blur strength, as the standard deviation (sigma) of the blur in
|
|
27
|
-
* source-image pixels
|
|
28
|
-
* React Native's `blurRadius`.
|
|
27
|
+
* source-image pixels (of the resized bitmap when `resize` is set). Matches
|
|
28
|
+
* across iOS and Android; roughly half of React Native's `blurRadius`.
|
|
29
29
|
*/
|
|
30
30
|
blur?: number;
|
|
31
31
|
/**
|
|
32
|
-
* Corner radius in
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Corner radius in pixels of the loaded bitmap. Pass a single number for
|
|
33
|
+
* uniform rounding, or per-corner radii (inline object literals are fine —
|
|
34
|
+
* the hook compares the radii by value, not identity). Pair with `resize`
|
|
35
|
+
* so the radii apply at the size you display instead of the source size.
|
|
35
36
|
*/
|
|
36
37
|
cornerRadius?: number | CornerRadii;
|
|
38
|
+
/**
|
|
39
|
+
* Resize the bitmap to exactly this size in pixels (aspect-fill,
|
|
40
|
+
* center-crop) before blur/rounding. Typically your display size in points
|
|
41
|
+
* multiplied by `PixelRatio.get()`. Inline object literals are fine.
|
|
42
|
+
*/
|
|
43
|
+
resize?: ResizeOptions;
|
|
37
44
|
cache?: CacheOption;
|
|
38
45
|
}): Result;
|
|
39
46
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAGtD,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,IAAI,sBAAsB,EAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAGtD,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,IAAI,sBAAsB,EAC5C,OAAO,EACP,aAAa,EACd,MAAM,mCAAmC,CAAC;AAE3C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;AAEjE,eAAO,MAAM,kBAAkB,wBACgD,CAAC;AAEhF,KAAK,MAAM,GAEP;IACE,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;CAClB,GAED;IACE,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;CAClB,GAED;IACE,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,IAAQ,EACR,YAAgB,EAChB,MAAM,EACN,KAAK,GACN,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACpC;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,MAAM,CAyET"}
|
|
@@ -2,7 +2,8 @@ import type { Image } from 'react-native-nitro-image';
|
|
|
2
2
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
3
3
|
export type CacheOption = 'memory' | 'disk' | 'none';
|
|
4
4
|
/**
|
|
5
|
-
* Independent corner radii in
|
|
5
|
+
* Independent corner radii, in pixels of the loaded bitmap (see
|
|
6
|
+
* {@linkcode Options.cornerRadius}). Omitted corners stay square.
|
|
6
7
|
*/
|
|
7
8
|
export interface CornerRadii {
|
|
8
9
|
topLeft?: number;
|
|
@@ -10,12 +11,24 @@ export interface CornerRadii {
|
|
|
10
11
|
bottomLeft?: number;
|
|
11
12
|
bottomRight?: number;
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Target bitmap size in pixels. The image is scaled to fill this size and
|
|
16
|
+
* center-cropped (like CSS `object-fit: cover`), upscaling if needed, so the
|
|
17
|
+
* result is exactly `width` × `height` pixels.
|
|
18
|
+
*/
|
|
19
|
+
export interface ResizeOptions {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
}
|
|
13
23
|
export type Options = {
|
|
14
24
|
/**
|
|
15
25
|
* Gaussian blur strength, given as the standard deviation (sigma) of the
|
|
16
26
|
* blur in **source-image pixels**. The same value on the same source image
|
|
17
27
|
* produces the same result on iOS and Android.
|
|
18
28
|
*
|
|
29
|
+
* When {@linkcode resize} is set, the blur runs after resizing, so sigma is
|
|
30
|
+
* in pixels of the resized bitmap instead.
|
|
31
|
+
*
|
|
19
32
|
* React Native's `<Image blurRadius={n} />` is roughly `blur: n / 2`.
|
|
20
33
|
*
|
|
21
34
|
* @default 0 (no blur)
|
|
@@ -23,14 +36,29 @@ export type Options = {
|
|
|
23
36
|
blur?: number;
|
|
24
37
|
cache?: CacheOption;
|
|
25
38
|
/**
|
|
26
|
-
* Corner radius
|
|
27
|
-
* number to round all four corners uniformly, or a
|
|
28
|
-
* object to round each corner independently (e.g. a
|
|
29
|
-
* larger bottom corners).
|
|
39
|
+
* Corner radius baked into the loaded bitmap, in **pixels of that bitmap**.
|
|
40
|
+
* Pass a single number to round all four corners uniformly, or a
|
|
41
|
+
* {@linkcode CornerRadii} object to round each corner independently (e.g. a
|
|
42
|
+
* "ticket" shape with larger bottom corners).
|
|
43
|
+
*
|
|
44
|
+
* Without {@linkcode resize} the radius applies to the full-resolution
|
|
45
|
+
* source image, so on a large photo displayed small the rounding shrinks
|
|
46
|
+
* along with it. To get corners sized for your layout, pass `resize` with
|
|
47
|
+
* your display size in pixels (points × screen scale) — the radii then
|
|
48
|
+
* apply to that final bitmap, 1:1 with what you see.
|
|
30
49
|
*
|
|
31
50
|
* @default 0 (square corners)
|
|
32
51
|
*/
|
|
33
52
|
cornerRadius?: number | CornerRadii;
|
|
53
|
+
/**
|
|
54
|
+
* Resize the image to exactly this size in pixels (aspect-fill,
|
|
55
|
+
* center-crop) before `blur` and `cornerRadius` are applied. Besides making
|
|
56
|
+
* `cornerRadius` predictable, this avoids decoding and processing
|
|
57
|
+
* full-resolution bitmaps you only display small.
|
|
58
|
+
*
|
|
59
|
+
* @default undefined (keep the source size)
|
|
60
|
+
*/
|
|
61
|
+
resize?: ResizeOptions;
|
|
34
62
|
};
|
|
35
63
|
export interface NitroImagePipeline extends HybridObject<{
|
|
36
64
|
ios: 'swift';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nitro-image-toolkit.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/nitro-image-toolkit.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"nitro-image-toolkit.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/nitro-image-toolkit.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,OAAO,GAAG;IACpB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACpC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,kBAAmB,SAAQ,YAAY,CAAC;IACvD,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,QAAQ,CAAC;CACnB,CAAC;IACA,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAG3D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B"}
|
|
@@ -15,6 +15,8 @@ namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
|
15
15
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
16
16
|
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
17
17
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
18
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
19
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
18
20
|
|
|
19
21
|
#include <memory>
|
|
20
22
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
@@ -32,6 +34,8 @@ namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
|
32
34
|
#include <variant>
|
|
33
35
|
#include "JVariant_Double_CornerRadii.hpp"
|
|
34
36
|
#include "JCornerRadii.hpp"
|
|
37
|
+
#include "ResizeOptions.hpp"
|
|
38
|
+
#include "JResizeOptions.hpp"
|
|
35
39
|
#include <vector>
|
|
36
40
|
|
|
37
41
|
namespace margelo::nitro::nitroimagepipeline {
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
#include "CornerRadii.hpp"
|
|
15
15
|
#include "JCacheOption.hpp"
|
|
16
16
|
#include "JCornerRadii.hpp"
|
|
17
|
+
#include "JResizeOptions.hpp"
|
|
17
18
|
#include "JVariant_Double_CornerRadii.hpp"
|
|
19
|
+
#include "ResizeOptions.hpp"
|
|
18
20
|
#include <optional>
|
|
19
21
|
#include <variant>
|
|
20
22
|
|
|
@@ -43,10 +45,13 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
43
45
|
jni::local_ref<JCacheOption> cache = this->getFieldValue(fieldCache);
|
|
44
46
|
static const auto fieldCornerRadius = clazz->getField<JVariant_Double_CornerRadii>("cornerRadius");
|
|
45
47
|
jni::local_ref<JVariant_Double_CornerRadii> cornerRadius = this->getFieldValue(fieldCornerRadius);
|
|
48
|
+
static const auto fieldResize = clazz->getField<JResizeOptions>("resize");
|
|
49
|
+
jni::local_ref<JResizeOptions> resize = this->getFieldValue(fieldResize);
|
|
46
50
|
return Options(
|
|
47
51
|
blur != nullptr ? std::make_optional(blur->value()) : std::nullopt,
|
|
48
52
|
cache != nullptr ? std::make_optional(cache->toCpp()) : std::nullopt,
|
|
49
|
-
cornerRadius != nullptr ? std::make_optional(cornerRadius->toCpp()) : std::nullopt
|
|
53
|
+
cornerRadius != nullptr ? std::make_optional(cornerRadius->toCpp()) : std::nullopt,
|
|
54
|
+
resize != nullptr ? std::make_optional(resize->toCpp()) : std::nullopt
|
|
50
55
|
);
|
|
51
56
|
}
|
|
52
57
|
|
|
@@ -56,14 +61,15 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
56
61
|
*/
|
|
57
62
|
[[maybe_unused]]
|
|
58
63
|
static jni::local_ref<JOptions::javaobject> fromCpp(const Options& value) {
|
|
59
|
-
using JSignature = JOptions(jni::alias_ref<jni::JDouble>, jni::alias_ref<JCacheOption>, jni::alias_ref<JVariant_Double_CornerRadii>);
|
|
64
|
+
using JSignature = JOptions(jni::alias_ref<jni::JDouble>, jni::alias_ref<JCacheOption>, jni::alias_ref<JVariant_Double_CornerRadii>, jni::alias_ref<JResizeOptions>);
|
|
60
65
|
static const auto clazz = javaClassStatic();
|
|
61
66
|
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
62
67
|
return create(
|
|
63
68
|
clazz,
|
|
64
69
|
value.blur.has_value() ? jni::JDouble::valueOf(value.blur.value()) : nullptr,
|
|
65
70
|
value.cache.has_value() ? JCacheOption::fromCpp(value.cache.value()) : nullptr,
|
|
66
|
-
value.cornerRadius.has_value() ? JVariant_Double_CornerRadii::fromCpp(value.cornerRadius.value()) : nullptr
|
|
71
|
+
value.cornerRadius.has_value() ? JVariant_Double_CornerRadii::fromCpp(value.cornerRadius.value()) : nullptr,
|
|
72
|
+
value.resize.has_value() ? JResizeOptions::fromCpp(value.resize.value()) : nullptr
|
|
67
73
|
);
|
|
68
74
|
}
|
|
69
75
|
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JResizeOptions.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "ResizeOptions.hpp"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
namespace margelo::nitro::nitroimagepipeline {
|
|
16
|
+
|
|
17
|
+
using namespace facebook;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The C++ JNI bridge between the C++ struct "ResizeOptions" and the Kotlin data class "ResizeOptions".
|
|
21
|
+
*/
|
|
22
|
+
struct JResizeOptions final: public jni::JavaClass<JResizeOptions> {
|
|
23
|
+
public:
|
|
24
|
+
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/nitroimagepipeline/ResizeOptions;";
|
|
25
|
+
|
|
26
|
+
public:
|
|
27
|
+
/**
|
|
28
|
+
* Convert this Java/Kotlin-based struct to the C++ struct ResizeOptions by copying all values to C++.
|
|
29
|
+
*/
|
|
30
|
+
[[maybe_unused]]
|
|
31
|
+
[[nodiscard]]
|
|
32
|
+
ResizeOptions toCpp() const {
|
|
33
|
+
static const auto clazz = javaClassStatic();
|
|
34
|
+
static const auto fieldWidth = clazz->getField<double>("width");
|
|
35
|
+
double width = this->getFieldValue(fieldWidth);
|
|
36
|
+
static const auto fieldHeight = clazz->getField<double>("height");
|
|
37
|
+
double height = this->getFieldValue(fieldHeight);
|
|
38
|
+
return ResizeOptions(
|
|
39
|
+
width,
|
|
40
|
+
height
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public:
|
|
45
|
+
/**
|
|
46
|
+
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
|
|
47
|
+
*/
|
|
48
|
+
[[maybe_unused]]
|
|
49
|
+
static jni::local_ref<JResizeOptions::javaobject> fromCpp(const ResizeOptions& value) {
|
|
50
|
+
using JSignature = JResizeOptions(double, double);
|
|
51
|
+
static const auto clazz = javaClassStatic();
|
|
52
|
+
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
53
|
+
return create(
|
|
54
|
+
clazz,
|
|
55
|
+
value.width,
|
|
56
|
+
value.height
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
} // namespace margelo::nitro::nitroimagepipeline
|
|
@@ -26,7 +26,10 @@ data class Options(
|
|
|
26
26
|
val cache: CacheOption?,
|
|
27
27
|
@DoNotStrip
|
|
28
28
|
@Keep
|
|
29
|
-
val cornerRadius: Variant_Double_CornerRadii
|
|
29
|
+
val cornerRadius: Variant_Double_CornerRadii?,
|
|
30
|
+
@DoNotStrip
|
|
31
|
+
@Keep
|
|
32
|
+
val resize: ResizeOptions?
|
|
30
33
|
) {
|
|
31
34
|
/* primary constructor */
|
|
32
35
|
|
|
@@ -36,13 +39,15 @@ data class Options(
|
|
|
36
39
|
return Objects.deepEquals(this.blur, other.blur)
|
|
37
40
|
&& Objects.deepEquals(this.cache, other.cache)
|
|
38
41
|
&& Objects.deepEquals(this.cornerRadius, other.cornerRadius)
|
|
42
|
+
&& Objects.deepEquals(this.resize, other.resize)
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
override fun hashCode(): Int {
|
|
42
46
|
return arrayOf<Any?>(
|
|
43
47
|
blur,
|
|
44
48
|
cache,
|
|
45
|
-
cornerRadius
|
|
49
|
+
cornerRadius,
|
|
50
|
+
resize
|
|
46
51
|
).contentDeepHashCode()
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -54,8 +59,8 @@ data class Options(
|
|
|
54
59
|
@Keep
|
|
55
60
|
@Suppress("unused")
|
|
56
61
|
@JvmStatic
|
|
57
|
-
private fun fromCpp(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?): Options {
|
|
58
|
-
return Options(blur, cache, cornerRadius)
|
|
62
|
+
private fun fromCpp(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?, resize: ResizeOptions?): Options {
|
|
63
|
+
return Options(blur, cache, cornerRadius, resize)
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
}
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/ResizeOptions.kt
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ResizeOptions.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.nitroimagepipeline
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
import java.util.Objects
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Represents the JavaScript object/struct "ResizeOptions".
|
|
17
|
+
*/
|
|
18
|
+
@DoNotStrip
|
|
19
|
+
@Keep
|
|
20
|
+
data class ResizeOptions(
|
|
21
|
+
@DoNotStrip
|
|
22
|
+
@Keep
|
|
23
|
+
val width: Double,
|
|
24
|
+
@DoNotStrip
|
|
25
|
+
@Keep
|
|
26
|
+
val height: Double
|
|
27
|
+
) {
|
|
28
|
+
/* primary constructor */
|
|
29
|
+
|
|
30
|
+
override fun equals(other: Any?): Boolean {
|
|
31
|
+
if (this === other) return true
|
|
32
|
+
if (other !is ResizeOptions) return false
|
|
33
|
+
return Objects.deepEquals(this.width, other.width)
|
|
34
|
+
&& Objects.deepEquals(this.height, other.height)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun hashCode(): Int {
|
|
38
|
+
return arrayOf<Any?>(
|
|
39
|
+
width,
|
|
40
|
+
height
|
|
41
|
+
).contentDeepHashCode()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
companion object {
|
|
45
|
+
/**
|
|
46
|
+
* Constructor called from C++
|
|
47
|
+
*/
|
|
48
|
+
@DoNotStrip
|
|
49
|
+
@Keep
|
|
50
|
+
@Suppress("unused")
|
|
51
|
+
@JvmStatic
|
|
52
|
+
private fun fromCpp(width: Double, height: Double): ResizeOptions {
|
|
53
|
+
return ResizeOptions(width, height)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -18,6 +18,8 @@ namespace margelo::nitro::image { class HybridImageSpec; }
|
|
|
18
18
|
namespace margelo::nitro::nitroimagepipeline { class HybridNitroImagePipelineSpec; }
|
|
19
19
|
// Forward declaration of `Options` to properly resolve imports.
|
|
20
20
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
21
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
21
23
|
|
|
22
24
|
// Forward declarations of Swift defined types
|
|
23
25
|
// Forward declaration of `HybridImageSpec_cxx` to properly resolve imports.
|
|
@@ -30,6 +32,7 @@ namespace NitroImagePipeline { class HybridNitroImagePipelineSpec_cxx; }
|
|
|
30
32
|
#include "CornerRadii.hpp"
|
|
31
33
|
#include "HybridNitroImagePipelineSpec.hpp"
|
|
32
34
|
#include "Options.hpp"
|
|
35
|
+
#include "ResizeOptions.hpp"
|
|
33
36
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
34
37
|
#include <NitroModules/Promise.hpp>
|
|
35
38
|
#include <NitroModules/PromiseHolder.hpp>
|
|
@@ -190,6 +193,21 @@ namespace margelo::nitro::nitroimagepipeline::bridge::swift {
|
|
|
190
193
|
return optional.value();
|
|
191
194
|
}
|
|
192
195
|
|
|
196
|
+
// pragma MARK: std::optional<ResizeOptions>
|
|
197
|
+
/**
|
|
198
|
+
* Specialized version of `std::optional<ResizeOptions>`.
|
|
199
|
+
*/
|
|
200
|
+
using std__optional_ResizeOptions_ = std::optional<ResizeOptions>;
|
|
201
|
+
inline std::optional<ResizeOptions> create_std__optional_ResizeOptions_(const ResizeOptions& value) noexcept {
|
|
202
|
+
return std::optional<ResizeOptions>(value);
|
|
203
|
+
}
|
|
204
|
+
inline bool has_value_std__optional_ResizeOptions_(const std::optional<ResizeOptions>& optional) noexcept {
|
|
205
|
+
return optional.has_value();
|
|
206
|
+
}
|
|
207
|
+
inline ResizeOptions get_std__optional_ResizeOptions_(const std::optional<ResizeOptions>& optional) noexcept {
|
|
208
|
+
return optional.value();
|
|
209
|
+
}
|
|
210
|
+
|
|
193
211
|
// pragma MARK: std::optional<Options>
|
|
194
212
|
/**
|
|
195
213
|
* Specialized version of `std::optional<Options>`.
|
|
@@ -18,12 +18,15 @@ namespace margelo::nitro::image { class HybridImageSpec; }
|
|
|
18
18
|
namespace margelo::nitro::nitroimagepipeline { class HybridNitroImagePipelineSpec; }
|
|
19
19
|
// Forward declaration of `Options` to properly resolve imports.
|
|
20
20
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
21
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
21
23
|
|
|
22
24
|
// Include C++ defined types
|
|
23
25
|
#include "CacheOption.hpp"
|
|
24
26
|
#include "CornerRadii.hpp"
|
|
25
27
|
#include "HybridNitroImagePipelineSpec.hpp"
|
|
26
28
|
#include "Options.hpp"
|
|
29
|
+
#include "ResizeOptions.hpp"
|
|
27
30
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
28
31
|
#include <NitroModules/Promise.hpp>
|
|
29
32
|
#include <NitroModules/Result.hpp>
|
|
@@ -20,6 +20,8 @@ namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
|
20
20
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
21
21
|
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
22
22
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
23
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
24
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
23
25
|
|
|
24
26
|
#include <memory>
|
|
25
27
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
@@ -30,6 +32,7 @@ namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
|
30
32
|
#include "CacheOption.hpp"
|
|
31
33
|
#include "CornerRadii.hpp"
|
|
32
34
|
#include <variant>
|
|
35
|
+
#include "ResizeOptions.hpp"
|
|
33
36
|
#include <vector>
|
|
34
37
|
|
|
35
38
|
#include "NitroImagePipeline-Swift-Cxx-Umbrella.hpp"
|
|
@@ -18,7 +18,7 @@ public extension Options {
|
|
|
18
18
|
/**
|
|
19
19
|
* Create a new instance of `Options`.
|
|
20
20
|
*/
|
|
21
|
-
init(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?) {
|
|
21
|
+
init(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?, resize: ResizeOptions?) {
|
|
22
22
|
self.init({ () -> bridge.std__optional_double_ in
|
|
23
23
|
if let __unwrappedValue = blur {
|
|
24
24
|
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
@@ -44,6 +44,12 @@ public extension Options {
|
|
|
44
44
|
} else {
|
|
45
45
|
return .init()
|
|
46
46
|
}
|
|
47
|
+
}(), { () -> bridge.std__optional_ResizeOptions_ in
|
|
48
|
+
if let __unwrappedValue = resize {
|
|
49
|
+
return bridge.create_std__optional_ResizeOptions_(__unwrappedValue)
|
|
50
|
+
} else {
|
|
51
|
+
return .init()
|
|
52
|
+
}
|
|
47
53
|
}())
|
|
48
54
|
}
|
|
49
55
|
|
|
@@ -87,4 +93,9 @@ public extension Options {
|
|
|
87
93
|
}
|
|
88
94
|
}()
|
|
89
95
|
}
|
|
96
|
+
|
|
97
|
+
@inline(__always)
|
|
98
|
+
var resize: ResizeOptions? {
|
|
99
|
+
return self.__resize.value
|
|
100
|
+
}
|
|
90
101
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ResizeOptions.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
import NitroModules
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Represents an instance of `ResizeOptions`, backed by a C++ struct.
|
|
12
|
+
*/
|
|
13
|
+
public typealias ResizeOptions = margelo.nitro.nitroimagepipeline.ResizeOptions
|
|
14
|
+
|
|
15
|
+
public extension ResizeOptions {
|
|
16
|
+
private typealias bridge = margelo.nitro.nitroimagepipeline.bridge.swift
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new instance of `ResizeOptions`.
|
|
20
|
+
*/
|
|
21
|
+
init(width: Double, height: Double) {
|
|
22
|
+
self.init(width, height)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@inline(__always)
|
|
26
|
+
var width: Double {
|
|
27
|
+
return self.__width
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@inline(__always)
|
|
31
|
+
var height: Double {
|
|
32
|
+
return self.__height
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -32,11 +32,14 @@
|
|
|
32
32
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
33
33
|
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
34
34
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
35
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
35
37
|
|
|
36
38
|
#include <optional>
|
|
37
39
|
#include "CacheOption.hpp"
|
|
38
40
|
#include "CornerRadii.hpp"
|
|
39
41
|
#include <variant>
|
|
42
|
+
#include "ResizeOptions.hpp"
|
|
40
43
|
|
|
41
44
|
namespace margelo::nitro::nitroimagepipeline {
|
|
42
45
|
|
|
@@ -48,10 +51,11 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
48
51
|
std::optional<double> blur SWIFT_PRIVATE;
|
|
49
52
|
std::optional<CacheOption> cache SWIFT_PRIVATE;
|
|
50
53
|
std::optional<std::variant<double, CornerRadii>> cornerRadius SWIFT_PRIVATE;
|
|
54
|
+
std::optional<ResizeOptions> resize SWIFT_PRIVATE;
|
|
51
55
|
|
|
52
56
|
public:
|
|
53
57
|
Options() = default;
|
|
54
|
-
explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<std::variant<double, CornerRadii>> cornerRadius): blur(blur), cache(cache), cornerRadius(cornerRadius) {}
|
|
58
|
+
explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<std::variant<double, CornerRadii>> cornerRadius, std::optional<ResizeOptions> resize): blur(blur), cache(cache), cornerRadius(cornerRadius), resize(resize) {}
|
|
55
59
|
|
|
56
60
|
public:
|
|
57
61
|
friend bool operator==(const Options& lhs, const Options& rhs) = default;
|
|
@@ -69,7 +73,8 @@ namespace margelo::nitro {
|
|
|
69
73
|
return margelo::nitro::nitroimagepipeline::Options(
|
|
70
74
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur"))),
|
|
71
75
|
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache"))),
|
|
72
|
-
JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))
|
|
76
|
+
JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"))),
|
|
77
|
+
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))
|
|
73
78
|
);
|
|
74
79
|
}
|
|
75
80
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::Options& arg) {
|
|
@@ -77,6 +82,7 @@ namespace margelo::nitro {
|
|
|
77
82
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "blur"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.blur));
|
|
78
83
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cache"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::toJSI(runtime, arg.cache));
|
|
79
84
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::toJSI(runtime, arg.cornerRadius));
|
|
85
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "resize"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::toJSI(runtime, arg.resize));
|
|
80
86
|
return obj;
|
|
81
87
|
}
|
|
82
88
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -90,6 +96,7 @@ namespace margelo::nitro {
|
|
|
90
96
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur")))) return false;
|
|
91
97
|
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache")))) return false;
|
|
92
98
|
if (!JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))) return false;
|
|
99
|
+
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))) return false;
|
|
93
100
|
return true;
|
|
94
101
|
}
|
|
95
102
|
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ResizeOptions.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro::nitroimagepipeline {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A struct which can be represented as a JavaScript object (ResizeOptions).
|
|
39
|
+
*/
|
|
40
|
+
struct ResizeOptions final {
|
|
41
|
+
public:
|
|
42
|
+
double width SWIFT_PRIVATE;
|
|
43
|
+
double height SWIFT_PRIVATE;
|
|
44
|
+
|
|
45
|
+
public:
|
|
46
|
+
ResizeOptions() = default;
|
|
47
|
+
explicit ResizeOptions(double width, double height): width(width), height(height) {}
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
friend bool operator==(const ResizeOptions& lhs, const ResizeOptions& rhs) = default;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
} // namespace margelo::nitro::nitroimagepipeline
|
|
54
|
+
|
|
55
|
+
namespace margelo::nitro {
|
|
56
|
+
|
|
57
|
+
// C++ ResizeOptions <> JS ResizeOptions (object)
|
|
58
|
+
template <>
|
|
59
|
+
struct JSIConverter<margelo::nitro::nitroimagepipeline::ResizeOptions> final {
|
|
60
|
+
static inline margelo::nitro::nitroimagepipeline::ResizeOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
61
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
62
|
+
return margelo::nitro::nitroimagepipeline::ResizeOptions(
|
|
63
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
|
|
64
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::ResizeOptions& arg) {
|
|
68
|
+
jsi::Object obj(runtime);
|
|
69
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<double>::toJSI(runtime, arg.width));
|
|
70
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<double>::toJSI(runtime, arg.height));
|
|
71
|
+
return obj;
|
|
72
|
+
}
|
|
73
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
74
|
+
if (!value.isObject()) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
jsi::Object obj = value.getObject(runtime);
|
|
78
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
|
|
82
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-image-pipeline",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "High-performance image loading, caching, and processing for React Native, built with Nitro Modules",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
package/src/index.ts
CHANGED
|
@@ -7,9 +7,10 @@ import type {
|
|
|
7
7
|
CornerRadii,
|
|
8
8
|
NitroImagePipeline as NitroImagePipelineSpec,
|
|
9
9
|
Options,
|
|
10
|
+
ResizeOptions,
|
|
10
11
|
} from './specs/nitro-image-toolkit.nitro';
|
|
11
12
|
|
|
12
|
-
export type { CacheOption, CornerRadii, Options };
|
|
13
|
+
export type { CacheOption, CornerRadii, Options, ResizeOptions };
|
|
13
14
|
|
|
14
15
|
export const NitroImagePipeline =
|
|
15
16
|
NitroModules.createHybridObject<NitroImagePipelineSpec>('NitroImagePipeline');
|
|
@@ -43,21 +44,29 @@ export function useImage({
|
|
|
43
44
|
url,
|
|
44
45
|
blur = 0,
|
|
45
46
|
cornerRadius = 0,
|
|
47
|
+
resize,
|
|
46
48
|
cache,
|
|
47
49
|
}: {
|
|
48
50
|
url: string;
|
|
49
51
|
/**
|
|
50
52
|
* Gaussian blur strength, as the standard deviation (sigma) of the blur in
|
|
51
|
-
* source-image pixels
|
|
52
|
-
* React Native's `blurRadius`.
|
|
53
|
+
* source-image pixels (of the resized bitmap when `resize` is set). Matches
|
|
54
|
+
* across iOS and Android; roughly half of React Native's `blurRadius`.
|
|
53
55
|
*/
|
|
54
56
|
blur?: number;
|
|
55
57
|
/**
|
|
56
|
-
* Corner radius in
|
|
57
|
-
*
|
|
58
|
-
*
|
|
58
|
+
* Corner radius in pixels of the loaded bitmap. Pass a single number for
|
|
59
|
+
* uniform rounding, or per-corner radii (inline object literals are fine —
|
|
60
|
+
* the hook compares the radii by value, not identity). Pair with `resize`
|
|
61
|
+
* so the radii apply at the size you display instead of the source size.
|
|
59
62
|
*/
|
|
60
63
|
cornerRadius?: number | CornerRadii;
|
|
64
|
+
/**
|
|
65
|
+
* Resize the bitmap to exactly this size in pixels (aspect-fill,
|
|
66
|
+
* center-crop) before blur/rounding. Typically your display size in points
|
|
67
|
+
* multiplied by `PixelRatio.get()`. Inline object literals are fine.
|
|
68
|
+
*/
|
|
69
|
+
resize?: ResizeOptions;
|
|
61
70
|
cache?: CacheOption;
|
|
62
71
|
}): Result {
|
|
63
72
|
const [image, setImage] = useState<Result>({
|
|
@@ -76,6 +85,8 @@ export function useImage({
|
|
|
76
85
|
bottomLeft = 0,
|
|
77
86
|
bottomRight = 0,
|
|
78
87
|
} = isUniformRadius ? {} : cornerRadius;
|
|
88
|
+
const resizeWidth = resize?.width ?? 0;
|
|
89
|
+
const resizeHeight = resize?.height ?? 0;
|
|
79
90
|
|
|
80
91
|
useEffect(() => {
|
|
81
92
|
let cancelled = false;
|
|
@@ -94,6 +105,10 @@ export function useImage({
|
|
|
94
105
|
cornerRadius: isUniformRadius
|
|
95
106
|
? uniformRadius
|
|
96
107
|
: { topLeft, topRight, bottomLeft, bottomRight },
|
|
108
|
+
resize:
|
|
109
|
+
resizeWidth > 0 && resizeHeight > 0
|
|
110
|
+
? { width: resizeWidth, height: resizeHeight }
|
|
111
|
+
: undefined,
|
|
97
112
|
cache,
|
|
98
113
|
});
|
|
99
114
|
|
|
@@ -120,6 +135,8 @@ export function useImage({
|
|
|
120
135
|
topRight,
|
|
121
136
|
bottomLeft,
|
|
122
137
|
bottomRight,
|
|
138
|
+
resizeWidth,
|
|
139
|
+
resizeHeight,
|
|
123
140
|
cache,
|
|
124
141
|
]);
|
|
125
142
|
|
|
@@ -4,7 +4,8 @@ import type { HybridObject } from 'react-native-nitro-modules';
|
|
|
4
4
|
export type CacheOption = 'memory' | 'disk' | 'none';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Independent corner radii in
|
|
7
|
+
* Independent corner radii, in pixels of the loaded bitmap (see
|
|
8
|
+
* {@linkcode Options.cornerRadius}). Omitted corners stay square.
|
|
8
9
|
*/
|
|
9
10
|
export interface CornerRadii {
|
|
10
11
|
topLeft?: number;
|
|
@@ -13,12 +14,25 @@ export interface CornerRadii {
|
|
|
13
14
|
bottomRight?: number;
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Target bitmap size in pixels. The image is scaled to fill this size and
|
|
19
|
+
* center-cropped (like CSS `object-fit: cover`), upscaling if needed, so the
|
|
20
|
+
* result is exactly `width` × `height` pixels.
|
|
21
|
+
*/
|
|
22
|
+
export interface ResizeOptions {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
16
27
|
export type Options = {
|
|
17
28
|
/**
|
|
18
29
|
* Gaussian blur strength, given as the standard deviation (sigma) of the
|
|
19
30
|
* blur in **source-image pixels**. The same value on the same source image
|
|
20
31
|
* produces the same result on iOS and Android.
|
|
21
32
|
*
|
|
33
|
+
* When {@linkcode resize} is set, the blur runs after resizing, so sigma is
|
|
34
|
+
* in pixels of the resized bitmap instead.
|
|
35
|
+
*
|
|
22
36
|
* React Native's `<Image blurRadius={n} />` is roughly `blur: n / 2`.
|
|
23
37
|
*
|
|
24
38
|
* @default 0 (no blur)
|
|
@@ -26,14 +40,29 @@ export type Options = {
|
|
|
26
40
|
blur?: number;
|
|
27
41
|
cache?: CacheOption;
|
|
28
42
|
/**
|
|
29
|
-
* Corner radius
|
|
30
|
-
* number to round all four corners uniformly, or a
|
|
31
|
-
* object to round each corner independently (e.g. a
|
|
32
|
-
* larger bottom corners).
|
|
43
|
+
* Corner radius baked into the loaded bitmap, in **pixels of that bitmap**.
|
|
44
|
+
* Pass a single number to round all four corners uniformly, or a
|
|
45
|
+
* {@linkcode CornerRadii} object to round each corner independently (e.g. a
|
|
46
|
+
* "ticket" shape with larger bottom corners).
|
|
47
|
+
*
|
|
48
|
+
* Without {@linkcode resize} the radius applies to the full-resolution
|
|
49
|
+
* source image, so on a large photo displayed small the rounding shrinks
|
|
50
|
+
* along with it. To get corners sized for your layout, pass `resize` with
|
|
51
|
+
* your display size in pixels (points × screen scale) — the radii then
|
|
52
|
+
* apply to that final bitmap, 1:1 with what you see.
|
|
33
53
|
*
|
|
34
54
|
* @default 0 (square corners)
|
|
35
55
|
*/
|
|
36
56
|
cornerRadius?: number | CornerRadii;
|
|
57
|
+
/**
|
|
58
|
+
* Resize the image to exactly this size in pixels (aspect-fill,
|
|
59
|
+
* center-crop) before `blur` and `cornerRadius` are applied. Besides making
|
|
60
|
+
* `cornerRadius` predictable, this avoids decoding and processing
|
|
61
|
+
* full-resolution bitmaps you only display small.
|
|
62
|
+
*
|
|
63
|
+
* @default undefined (keep the source size)
|
|
64
|
+
*/
|
|
65
|
+
resize?: ResizeOptions;
|
|
37
66
|
};
|
|
38
67
|
|
|
39
68
|
export interface NitroImagePipeline extends HybridObject<{
|