expo-image-manipulator 13.0.2 → 13.0.4
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/CHANGELOG.md +12 -0
- package/android/build.gradle +2 -2
- package/build/ImageManipulator.d.ts +2 -1
- package/build/ImageManipulator.d.ts.map +1 -1
- package/build/ImageManipulator.types.d.ts +2 -1
- package/build/ImageManipulator.types.d.ts.map +1 -1
- package/build/NativeImageManipulatorModule.web.d.ts +2 -1
- package/build/NativeImageManipulatorModule.web.d.ts.map +1 -1
- package/build/web/ImageManipulatorContext.web.d.ts.map +1 -1
- package/build/web/ImageManipulatorImageRef.web.d.ts +3 -2
- package/build/web/ImageManipulatorImageRef.web.d.ts.map +1 -1
- package/build/web/utils.web.d.ts +1 -2
- package/build/web/utils.web.d.ts.map +1 -1
- package/ios/ImageManipulatorModule.swift +8 -2
- package/package.json +2 -2
- package/src/ImageManipulator.ts +3 -2
- package/src/ImageManipulator.types.ts +2 -1
- package/src/NativeImageManipulatorModule.web.ts +12 -2
- package/src/web/ImageManipulatorContext.web.ts +8 -1
- package/src/web/ImageManipulatorImageRef.web.ts +18 -9
- package/src/web/utils.web.ts +9 -21
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 13.0.4 — 2024-10-28
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- [iOS][Web] Added support for image refs in `ImageManipulator.manipulate` and `useImageManipulator`. ([#32346](https://github.com/expo/expo/pull/32346), [#32354](https://github.com/expo/expo/pull/32354) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
|
|
19
|
+
## 13.0.3 — 2024-10-25
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- [iOS] Added support for image refs in `ImageManipulator.manipulate` and `useImageManipulator`. ([#32346](https://github.com/expo/expo/pull/32346) by [@tsapeta](https://github.com/tsapeta))
|
|
24
|
+
|
|
13
25
|
## 13.0.2 — 2024-10-24
|
|
14
26
|
|
|
15
27
|
### 💡 Others
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'host.exp.exponent'
|
|
4
|
-
version = '13.0.
|
|
4
|
+
version = '13.0.4'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -14,7 +14,7 @@ android {
|
|
|
14
14
|
namespace "expo.modules.imagemanipulator"
|
|
15
15
|
defaultConfig {
|
|
16
16
|
versionCode 23
|
|
17
|
-
versionName "13.0.
|
|
17
|
+
versionName "13.0.4"
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
1
2
|
import { Action, ImageResult, SaveOptions } from './ImageManipulator.types';
|
|
2
3
|
import { ImageManipulatorContext } from './ImageManipulatorContext';
|
|
3
4
|
import ExpoImageManipulator from './NativeImageManipulatorModule';
|
|
@@ -15,6 +16,6 @@ import ExpoImageManipulator from './NativeImageManipulatorModule';
|
|
|
15
16
|
* Use [`ImageManipulator.manipulate`](#manipulateuri) or [`useImageManipulator`](#useimagemanipulatoruri) instead.
|
|
16
17
|
*/
|
|
17
18
|
export declare function manipulateAsync(uri: string, actions?: Action[], saveOptions?: SaveOptions): Promise<ImageResult>;
|
|
18
|
-
export declare function useImageManipulator(
|
|
19
|
+
export declare function useImageManipulator(source: string | SharedRef<'image'>): ImageManipulatorContext;
|
|
19
20
|
export { ExpoImageManipulator as ImageManipulator };
|
|
20
21
|
//# sourceMappingURL=ImageManipulator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManipulator.d.ts","sourceRoot":"","sources":["../src/ImageManipulator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageManipulator.d.ts","sourceRoot":"","sources":["../src/ImageManipulator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAc,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,oBAAoB,MAAM,gCAAgC,CAAC;AAIlE;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,EAAO,EACtB,WAAW,GAAE,WAAgB,GAC5B,OAAO,CAAC,WAAW,CAAC,CA2BtB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,uBAAuB,CAEhG;AAED,OAAO,EAAE,oBAAoB,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NativeModule } from 'expo';
|
|
2
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
2
3
|
import type { ImageManipulatorContext } from './ImageManipulatorContext';
|
|
3
4
|
import ImageRef from './ImageRef';
|
|
4
5
|
export type ImageResult = {
|
|
@@ -114,6 +115,6 @@ export declare class ImageManipulator extends NativeModule {
|
|
|
114
115
|
/**
|
|
115
116
|
* Loads an image from the given URI and creates a new image manipulation context.
|
|
116
117
|
*/
|
|
117
|
-
manipulate(
|
|
118
|
+
manipulate(source: string | SharedRef<'image'>): ImageManipulatorContext;
|
|
118
119
|
}
|
|
119
120
|
//# sourceMappingURL=ImageManipulator.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManipulator.types.d.ts","sourceRoot":"","sources":["../src/ImageManipulator.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageManipulator.types.d.ts","sourceRoot":"","sources":["../src/ImageManipulator.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,QAAQ,MAAM,YAAY,CAAC;AAGlC,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,MAAM,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,oBAAY,QAAQ;IAClB,QAAQ,aAAa;IACrB,UAAU,eAAe;CAC1B;AAGD,MAAM,MAAM,UAAU,GAAG;IACvB;;;OAGG;IACH,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;OAKG;IACH,MAAM,EAAE;QACN,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;AAG1F,oBAAY,UAAU;IACpB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAGD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,YAAY;IACxD;;OAEG;IACH,OAAO,EAAE,OAAO,uBAAuB,CAAC;IAExC;;OAEG;IACH,KAAK,EAAE,OAAO,QAAQ,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,uBAAuB;CACzE"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { NativeModule } from 'expo';
|
|
2
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
2
3
|
import ImageManipulatorContext from './web/ImageManipulatorContext.web';
|
|
3
4
|
import ImageManipulatorImageRef from './web/ImageManipulatorImageRef.web';
|
|
4
5
|
declare class ImageManipulator extends NativeModule {
|
|
5
6
|
Context: typeof ImageManipulatorContext;
|
|
6
7
|
Image: typeof ImageManipulatorImageRef;
|
|
7
|
-
manipulate(
|
|
8
|
+
manipulate(source: string | SharedRef<'image'>): ImageManipulatorContext;
|
|
8
9
|
}
|
|
9
10
|
declare const _default: typeof ImageManipulator;
|
|
10
11
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeImageManipulatorModule.web.d.ts","sourceRoot":"","sources":["../src/NativeImageManipulatorModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeImageManipulatorModule.web.d.ts","sourceRoot":"","sources":["../src/NativeImageManipulatorModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,uBAAuB,MAAM,mCAAmC,CAAC;AACxE,OAAO,wBAAwB,MAAM,oCAAoC,CAAC;AAG1E,cAAM,gBAAiB,SAAQ,YAAY;IACzC,OAAO,iCAA2B;IAClC,KAAK,kCAA4B;IAEjC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,uBAAuB;CAYzE;;AAED,wBAAmD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManipulatorContext.web.d.ts","sourceRoot":"","sources":["../../src/web/ImageManipulatorContext.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,wBAAwB,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG/E,KAAK,aAAa,GAAG,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,YAAY;IAC/D,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,CAAC,EAAE,aAAa;IAMlC,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,uBAAuB;IAIxE,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB;IAIhD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB;IAIjD,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,uBAAuB;IAIvD,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,uBAAuB;IAIhE,KAAK,IAAI,uBAAuB;IAK1B,WAAW,IAAI,OAAO,CAAC,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageManipulatorContext.web.d.ts","sourceRoot":"","sources":["../../src/web/ImageManipulatorContext.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,wBAAwB,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG/E,KAAK,aAAa,GAAG,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,YAAY;IAC/D,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,CAAC,EAAE,aAAa;IAMlC,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,uBAAuB;IAIxE,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB;IAIhD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB;IAIjD,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,uBAAuB;IAIvD,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,uBAAuB;IAIhE,KAAK,IAAI,uBAAuB;IAK1B,WAAW,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAYtD,OAAO,CAAC,OAAO;CAQhB"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { SharedRef } from 'expo';
|
|
2
2
|
import { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
3
3
|
export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
4
|
-
|
|
4
|
+
readonly nativeRefType: string;
|
|
5
|
+
readonly uri: string;
|
|
5
6
|
readonly width: number;
|
|
6
7
|
readonly height: number;
|
|
7
|
-
constructor(
|
|
8
|
+
constructor(uri: string, width: number, height: number);
|
|
8
9
|
saveAsync(options?: SaveOptions): Promise<ImageResult>;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=ImageManipulatorImageRef.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManipulatorImageRef.web.d.ts","sourceRoot":"","sources":["../../src/web/ImageManipulatorImageRef.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageManipulatorImageRef.web.d.ts","sourceRoot":"","sources":["../../src/web/ImageManipulatorImageRef.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGrE,MAAM,CAAC,OAAO,OAAO,wBAAyB,SAAQ,SAAS,CAAC,OAAO,CAAC;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAW;IAEzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAOhD,SAAS,CAAC,OAAO,GAAE,WAA+B,GAAG,OAAO,CAAC,WAAW,CAAC;CAUhF"}
|
package/build/web/utils.web.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
2
1
|
export declare function getContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D;
|
|
3
|
-
export declare function
|
|
2
|
+
export declare function blobToBase64String(blob: Blob): Promise<string>;
|
|
4
3
|
export declare function loadImageAsync(uri: string): Promise<HTMLCanvasElement>;
|
|
5
4
|
//# sourceMappingURL=utils.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.web.d.ts","sourceRoot":"","sources":["../../src/web/utils.web.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"utils.web.d.ts","sourceRoot":"","sources":["../../src/web/utils.web.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,wBAAwB,CAM9E;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CASpE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiBtE"}
|
|
@@ -10,12 +10,18 @@ public class ImageManipulatorModule: Module {
|
|
|
10
10
|
public func definition() -> ModuleDefinition {
|
|
11
11
|
Name("ExpoImageManipulator")
|
|
12
12
|
|
|
13
|
-
Function("manipulate") { (
|
|
13
|
+
Function("manipulate") { (source: Either<URL, SharedRef<UIImage>>) -> ImageManipulatorContext in
|
|
14
14
|
let context = ImageManipulatorContext { [weak appContext] in
|
|
15
15
|
guard let appContext else {
|
|
16
16
|
throw Exceptions.AppContextLost()
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
if let url: URL = source.get() {
|
|
19
|
+
return try await loadImage(atUrl: url, appContext: appContext)
|
|
20
|
+
}
|
|
21
|
+
if let image: SharedRef<UIImage> = source.get() {
|
|
22
|
+
return image.ref
|
|
23
|
+
}
|
|
24
|
+
throw Exceptions.RuntimeLost()
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
// Immediately try to fix the orientation once the image is loaded
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-image-manipulator",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.4",
|
|
4
4
|
"description": "Provides functions that let you manipulation images on the local file system, eg: resize, crop.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"expo": "*"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "fc8a1408cab82e003dd2424db2994d7dea958067"
|
|
43
43
|
}
|
package/src/ImageManipulator.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useReleasingSharedObject } from 'expo-modules-core';
|
|
2
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
2
3
|
|
|
3
4
|
import { Action, ImageResult, SaveFormat, SaveOptions } from './ImageManipulator.types';
|
|
4
5
|
import { ImageManipulatorContext } from './ImageManipulatorContext';
|
|
@@ -52,8 +53,8 @@ export async function manipulateAsync(
|
|
|
52
53
|
return result;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export function useImageManipulator(
|
|
56
|
-
return useReleasingSharedObject(() => ExpoImageManipulator.manipulate(
|
|
56
|
+
export function useImageManipulator(source: string | SharedRef<'image'>): ImageManipulatorContext {
|
|
57
|
+
return useReleasingSharedObject(() => ExpoImageManipulator.manipulate(source), [source]);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export { ExpoImageManipulator as ImageManipulator };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NativeModule } from 'expo';
|
|
2
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
2
3
|
|
|
3
4
|
import type { ImageManipulatorContext } from './ImageManipulatorContext';
|
|
4
5
|
import ImageRef from './ImageRef';
|
|
@@ -138,5 +139,5 @@ export declare class ImageManipulator extends NativeModule {
|
|
|
138
139
|
/**
|
|
139
140
|
* Loads an image from the given URI and creates a new image manipulation context.
|
|
140
141
|
*/
|
|
141
|
-
manipulate(
|
|
142
|
+
manipulate(source: string | SharedRef<'image'>): ImageManipulatorContext;
|
|
142
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NativeModule } from 'expo';
|
|
2
2
|
import { registerWebModule } from 'expo-modules-core';
|
|
3
|
+
import { SharedRef } from 'expo-modules-core/types';
|
|
3
4
|
|
|
4
5
|
import ImageManipulatorContext from './web/ImageManipulatorContext.web';
|
|
5
6
|
import ImageManipulatorImageRef from './web/ImageManipulatorImageRef.web';
|
|
@@ -9,8 +10,17 @@ class ImageManipulator extends NativeModule {
|
|
|
9
10
|
Context = ImageManipulatorContext;
|
|
10
11
|
Image = ImageManipulatorImageRef;
|
|
11
12
|
|
|
12
|
-
manipulate(
|
|
13
|
-
return new ImageManipulatorContext(() =>
|
|
13
|
+
manipulate(source: string | SharedRef<'image'>): ImageManipulatorContext {
|
|
14
|
+
return new ImageManipulatorContext(() => {
|
|
15
|
+
if (typeof source === 'string') {
|
|
16
|
+
return loadImageAsync(source);
|
|
17
|
+
}
|
|
18
|
+
// Image refs should provide the `uri` property on Web. It could be either remote url, blob or data url.
|
|
19
|
+
if (typeof source === 'object' && 'uri' in source && typeof source.uri === 'string') {
|
|
20
|
+
return loadImageAsync(source.uri);
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`Source not supported: ${source}`);
|
|
23
|
+
});
|
|
14
24
|
}
|
|
15
25
|
}
|
|
16
26
|
|
|
@@ -43,7 +43,14 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
43
43
|
|
|
44
44
|
async renderAsync(): Promise<ImageManipulatorImageRef> {
|
|
45
45
|
const canvas = await this.currentTask;
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
return new Promise((resolve) => {
|
|
48
|
+
canvas.toBlob((blob) => {
|
|
49
|
+
const url = blob ? URL.createObjectURL(blob) : canvas.toDataURL();
|
|
50
|
+
|
|
51
|
+
resolve(new ImageManipulatorImageRef(url, canvas.width, canvas.height));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
private addTask(
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import { SharedRef } from 'expo';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
4
|
+
import { blobToBase64String } from './utils.web';
|
|
5
5
|
|
|
6
6
|
export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
7
|
-
|
|
7
|
+
readonly nativeRefType: string = 'image';
|
|
8
|
+
|
|
9
|
+
readonly uri: string;
|
|
8
10
|
readonly width: number;
|
|
9
11
|
readonly height: number;
|
|
10
12
|
|
|
11
|
-
constructor(
|
|
13
|
+
constructor(uri: string, width: number, height: number) {
|
|
12
14
|
super();
|
|
13
|
-
this.
|
|
14
|
-
this.width =
|
|
15
|
-
this.height =
|
|
15
|
+
this.uri = uri;
|
|
16
|
+
this.width = width;
|
|
17
|
+
this.height = height;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
async saveAsync(options: SaveOptions = {
|
|
19
|
-
return
|
|
20
|
+
async saveAsync(options: SaveOptions = { base64: false }): Promise<ImageResult> {
|
|
21
|
+
return {
|
|
22
|
+
uri: this.uri,
|
|
23
|
+
width: this.width,
|
|
24
|
+
height: this.height,
|
|
25
|
+
base64: options.base64
|
|
26
|
+
? await blobToBase64String(await fetch(this.uri).then((response) => response.blob()))
|
|
27
|
+
: undefined,
|
|
28
|
+
};
|
|
20
29
|
}
|
|
21
30
|
}
|
package/src/web/utils.web.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { CodedError } from 'expo-modules-core';
|
|
2
2
|
|
|
3
|
-
import { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
4
|
-
|
|
5
3
|
export function getContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D {
|
|
6
4
|
const ctx = canvas.getContext('2d');
|
|
7
5
|
if (!ctx) {
|
|
@@ -10,25 +8,15 @@ export function getContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D
|
|
|
10
8
|
return ctx;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
export function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
} else {
|
|
23
|
-
// defaults to PNG with no loss
|
|
24
|
-
uri = canvas.toDataURL();
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
uri,
|
|
28
|
-
width: canvas.width,
|
|
29
|
-
height: canvas.height,
|
|
30
|
-
base64: uri.replace(/^data:image\/\w+;base64,/, ''),
|
|
31
|
-
};
|
|
11
|
+
export async function blobToBase64String(blob: Blob): Promise<string> {
|
|
12
|
+
const dataURL = await new Promise<string>((resolve, reject) => {
|
|
13
|
+
const reader = new FileReader();
|
|
14
|
+
reader.onloadend = () => resolve(reader.result as string);
|
|
15
|
+
reader.onerror = () =>
|
|
16
|
+
reject(new Error(`Unable to convert blob to base64 string: ${reader.error}`));
|
|
17
|
+
reader.readAsDataURL(blob);
|
|
18
|
+
});
|
|
19
|
+
return dataURL.replace(/^data:image\/\w+;base64,/, '');
|
|
32
20
|
}
|
|
33
21
|
|
|
34
22
|
export function loadImageAsync(uri: string): Promise<HTMLCanvasElement> {
|