expo-image-manipulator 58.0.4 → 58.0.6
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 +9 -0
- package/android/build.gradle +2 -2
- package/build/web/ImageManipulatorContext.web.d.ts +4 -0
- package/build/web/ImageManipulatorContext.web.js +41 -6
- package/build/web/ImageManipulatorContext.web.js.map +1 -1
- package/build/web/ImageManipulatorImageRef.web.d.ts +3 -0
- package/build/web/ImageManipulatorImageRef.web.js +26 -4
- package/build/web/ImageManipulatorImageRef.web.js.map +1 -1
- package/build/web/utils.web.d.ts +1 -0
- package/build/web/utils.web.js +8 -1
- package/build/web/utils.web.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.module → 58.0.6/expo.modules.imagemanipulator-58.0.6.module} +7 -7
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.pom → 58.0.6/expo.modules.imagemanipulator-58.0.6.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.6/expo.modules.imagemanipulator-58.0.6.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha512 +1 -1
- package/package.json +4 -4
- package/prebuilds/output/debug/xcframeworks/ExpoImageManipulator.tar.gz +0 -0
- package/prebuilds/output/release/xcframeworks/ExpoImageManipulator.tar.gz +0 -0
- package/prebuilds/spm-deps/SDWebImage/debug/SDWebImage.xcframework/Info.plist +5 -5
- package/prebuilds/spm-deps/SDWebImage/debug/SDWebImage.xcframework/ios-arm64/SDWebImage.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImage/debug/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImage/debug/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/SDWebImage +0 -0
- package/prebuilds/spm-deps/SDWebImage/debug/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/_CodeSignature/CodeResources +1 -1
- package/prebuilds/spm-deps/SDWebImage/release/SDWebImage.xcframework/ios-arm64/SDWebImage.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImage/release/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImage/release/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/SDWebImage +0 -0
- package/prebuilds/spm-deps/SDWebImage/release/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework/_CodeSignature/CodeResources +1 -1
- package/prebuilds/spm-deps/SDWebImageWebPCoder/debug/SDWebImageWebPCoder.xcframework/ios-arm64/SDWebImageWebPCoder.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/debug/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/debug/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/SDWebImageWebPCoder +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/debug/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/_CodeSignature/CodeResources +1 -1
- package/prebuilds/spm-deps/SDWebImageWebPCoder/release/SDWebImageWebPCoder.xcframework/ios-arm64/SDWebImageWebPCoder.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/release/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/Info.plist +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/release/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/SDWebImageWebPCoder +0 -0
- package/prebuilds/spm-deps/SDWebImageWebPCoder/release/SDWebImageWebPCoder.xcframework/ios-arm64_x86_64-simulator/SDWebImageWebPCoder.framework/_CodeSignature/CodeResources +1 -1
- package/src/web/ImageManipulatorContext.web.ts +51 -9
- package/src/web/ImageManipulatorImageRef.web.ts +32 -4
- package/src/web/utils.web.ts +14 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/58.0.4/expo.modules.imagemanipulator-58.0.4.pom.sha512 +0 -1
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4-sources.jar → 58.0.6/expo.modules.imagemanipulator-58.0.6-sources.jar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4-sources.jar.md5 → 58.0.6/expo.modules.imagemanipulator-58.0.6-sources.jar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4-sources.jar.sha1 → 58.0.6/expo.modules.imagemanipulator-58.0.6-sources.jar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4-sources.jar.sha256 → 58.0.6/expo.modules.imagemanipulator-58.0.6-sources.jar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4-sources.jar.sha512 → 58.0.6/expo.modules.imagemanipulator-58.0.6-sources.jar.sha512} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.aar → 58.0.6/expo.modules.imagemanipulator-58.0.6.aar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.aar.md5 → 58.0.6/expo.modules.imagemanipulator-58.0.6.aar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.aar.sha1 → 58.0.6/expo.modules.imagemanipulator-58.0.6.aar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.aar.sha256 → 58.0.6/expo.modules.imagemanipulator-58.0.6.aar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/{58.0.4/expo.modules.imagemanipulator-58.0.4.aar.sha512 → 58.0.6/expo.modules.imagemanipulator-58.0.6.aar.sha512} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 58.0.6 — 2026-09-22
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
17
|
+
## 58.0.5 — 2026-09-21
|
|
18
|
+
|
|
19
|
+
_This version does not introduce any user-facing changes._
|
|
20
|
+
|
|
13
21
|
## 58.0.4 — 2026-09-16
|
|
14
22
|
|
|
15
23
|
_This version does not introduce any user-facing changes._
|
|
@@ -34,6 +42,7 @@ _This version does not introduce any user-facing changes._
|
|
|
34
42
|
|
|
35
43
|
### 🐛 Bug fixes
|
|
36
44
|
|
|
45
|
+
- [Web] Fixed `release()` not releasing image manipulation resources. ([#49831](https://github.com/expo/expo/pull/49831) by [@mozzius](https://github.com/mozzius))
|
|
37
46
|
- Fixed `ImageManipulator.Image` being typed as an `ImageRef` instance rather than the class it holds at runtime, which rejected `instanceof` checks and made instance members appear to exist on it. ([#48613](https://github.com/expo/expo/pull/48613) by [@vonovak](https://github.com/vonovak))
|
|
38
47
|
|
|
39
48
|
### 💡 Others
|
package/android/build.gradle
CHANGED
|
@@ -4,6 +4,7 @@ import ImageManipulatorImageRef from './ImageManipulatorImageRef.web';
|
|
|
4
4
|
type ContextLoader = () => HTMLCanvasElement | Promise<HTMLCanvasElement>;
|
|
5
5
|
export default class ImageManipulatorContext extends SharedObject {
|
|
6
6
|
private loader;
|
|
7
|
+
private isReleased;
|
|
7
8
|
private _currentTask;
|
|
8
9
|
get currentTask(): Promise<HTMLCanvasElement>;
|
|
9
10
|
set currentTask(task: Promise<HTMLCanvasElement>);
|
|
@@ -17,7 +18,10 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
17
18
|
crop(rect: ActionCrop['crop']): ImageManipulatorContext;
|
|
18
19
|
extent(options: ActionExtent['extent']): ImageManipulatorContext;
|
|
19
20
|
reset(): ImageManipulatorContext;
|
|
21
|
+
release(): void;
|
|
20
22
|
renderAsync(): Promise<ImageManipulatorImageRef>;
|
|
21
23
|
private addTask;
|
|
24
|
+
private ensureNotReleased;
|
|
25
|
+
private releaseTask;
|
|
22
26
|
}
|
|
23
27
|
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { SharedObject } from 'expo';
|
|
1
|
+
import { CodedError, SharedObject } from 'expo';
|
|
2
2
|
import ImageManipulatorImageRef from './ImageManipulatorImageRef.web';
|
|
3
3
|
import { crop, extent, flip, resize, rotate } from './actions/index.web';
|
|
4
|
+
import { releaseCanvas } from './utils.web';
|
|
4
5
|
export default class ImageManipulatorContext extends SharedObject {
|
|
5
6
|
loader;
|
|
7
|
+
isReleased = false;
|
|
6
8
|
_currentTask;
|
|
7
9
|
get currentTask() {
|
|
10
|
+
this.ensureNotReleased();
|
|
8
11
|
if (this._currentTask) {
|
|
9
12
|
return this._currentTask;
|
|
10
13
|
}
|
|
@@ -12,6 +15,7 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
12
15
|
return this._currentTask;
|
|
13
16
|
}
|
|
14
17
|
set currentTask(task) {
|
|
18
|
+
this.ensureNotReleased();
|
|
15
19
|
this._currentTask = task;
|
|
16
20
|
}
|
|
17
21
|
constructor(loader){
|
|
@@ -34,9 +38,22 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
34
38
|
return this.addTask((canvas)=>extent(canvas, options));
|
|
35
39
|
}
|
|
36
40
|
reset() {
|
|
41
|
+
this.ensureNotReleased();
|
|
42
|
+
const previousTask = this._currentTask;
|
|
37
43
|
this.currentTask = new Promise((resolve)=>resolve(this.loader()));
|
|
44
|
+
this.releaseTask(previousTask);
|
|
38
45
|
return this;
|
|
39
46
|
}
|
|
47
|
+
release() {
|
|
48
|
+
if (this.isReleased) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.isReleased = true;
|
|
52
|
+
this.releaseTask(this._currentTask);
|
|
53
|
+
this._currentTask = undefined;
|
|
54
|
+
this.loader = undefined;
|
|
55
|
+
super.release();
|
|
56
|
+
}
|
|
40
57
|
async renderAsync() {
|
|
41
58
|
const canvas = await this.currentTask;
|
|
42
59
|
// We're copying the canvas so ref's `saveAsync` can safely use `toBlob` again with the desired format and quality.
|
|
@@ -47,9 +64,9 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
47
64
|
clonedCanvas.height = canvas.height;
|
|
48
65
|
clonedCanvasCtx?.drawImage(canvas, 0, 0);
|
|
49
66
|
return new Promise((resolve)=>{
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
const url = blob ? URL.createObjectURL(blob) :
|
|
67
|
+
// Encode the clone, which remains valid if the context is released or reset.
|
|
68
|
+
clonedCanvas.toBlob((blob)=>{
|
|
69
|
+
const url = blob ? URL.createObjectURL(blob) : clonedCanvas.toDataURL();
|
|
53
70
|
const image = new ImageManipulatorImageRef(url, clonedCanvas);
|
|
54
71
|
resolve(image);
|
|
55
72
|
}, // Use PNG format so the result is of the best quality.
|
|
@@ -58,11 +75,29 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
58
75
|
});
|
|
59
76
|
}
|
|
60
77
|
addTask(task) {
|
|
61
|
-
this.currentTask = this.currentTask.then((canvas)=>{
|
|
62
|
-
|
|
78
|
+
this.currentTask = this.currentTask.then(async (canvas)=>{
|
|
79
|
+
try {
|
|
80
|
+
const result = await task(canvas);
|
|
81
|
+
if (result !== canvas) {
|
|
82
|
+
releaseCanvas(canvas);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
releaseCanvas(canvas);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
63
89
|
});
|
|
64
90
|
return this;
|
|
65
91
|
}
|
|
92
|
+
ensureNotReleased() {
|
|
93
|
+
if (this.isReleased) {
|
|
94
|
+
throw new CodedError('ERR_IMAGE_MANIPULATOR_RELEASED', 'This image manipulation context was released by release() or by useImageManipulator when its source changed or its component unmounted. Create a new context with ImageManipulator.manipulate(...).');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
releaseTask(task) {
|
|
98
|
+
// Failed tasks clean up their own canvases.
|
|
99
|
+
task?.then(releaseCanvas, ()=>{});
|
|
100
|
+
}
|
|
66
101
|
}
|
|
67
102
|
|
|
68
103
|
//# sourceMappingURL=ImageManipulatorContext.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["web/ImageManipulatorContext.web.ts"],"sourcesContent":[null],"names":["SharedObject","ImageManipulatorImageRef","crop","extent","flip","resize","rotate","ImageManipulatorContext","loader","_currentTask","currentTask","Promise","resolve","task","document","createElement","size","addTask","canvas","degrees","flipType","rect","options","reset","renderAsync","clonedCanvas","clonedCanvasCtx","getContext","width","height","drawImage","toBlob","blob","url","URL","createObjectURL","toDataURL","image","then"],"mappings":"AAAA,SAASA,YAAY,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"sources":["web/ImageManipulatorContext.web.ts"],"sourcesContent":[null],"names":["CodedError","SharedObject","ImageManipulatorImageRef","crop","extent","flip","resize","rotate","releaseCanvas","ImageManipulatorContext","loader","isReleased","_currentTask","currentTask","ensureNotReleased","Promise","resolve","task","document","createElement","size","addTask","canvas","degrees","flipType","rect","options","reset","previousTask","releaseTask","release","undefined","renderAsync","clonedCanvas","clonedCanvasCtx","getContext","width","height","drawImage","toBlob","blob","url","URL","createObjectURL","toDataURL","image","then","result","error"],"mappings":"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"}
|
|
@@ -2,10 +2,13 @@ import { SharedRef } from 'expo';
|
|
|
2
2
|
import type { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
3
3
|
export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
4
4
|
readonly nativeRefType: string;
|
|
5
|
+
private isReleased;
|
|
5
6
|
readonly uri: string;
|
|
6
7
|
readonly canvas: HTMLCanvasElement;
|
|
7
8
|
constructor(uri: string, canvas: HTMLCanvasElement);
|
|
8
9
|
get width(): number;
|
|
9
10
|
get height(): number;
|
|
10
11
|
saveAsync(options?: SaveOptions): Promise<ImageResult>;
|
|
12
|
+
release(): void;
|
|
13
|
+
private ensureNotReleased;
|
|
11
14
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { SharedRef } from 'expo';
|
|
1
|
+
import { CodedError, SharedRef } from 'expo';
|
|
2
2
|
import { SaveFormat } from '../ImageManipulator.types';
|
|
3
|
-
import { blobToBase64String } from './utils.web';
|
|
3
|
+
import { blobToBase64String, releaseCanvas } from './utils.web';
|
|
4
4
|
export default class ImageManipulatorImageRef extends SharedRef {
|
|
5
5
|
nativeRefType = 'image';
|
|
6
|
+
isReleased = false;
|
|
6
7
|
uri;
|
|
7
8
|
canvas;
|
|
8
9
|
constructor(uri, canvas){
|
|
@@ -11,14 +12,19 @@ export default class ImageManipulatorImageRef extends SharedRef {
|
|
|
11
12
|
this.canvas = canvas;
|
|
12
13
|
}
|
|
13
14
|
get width() {
|
|
15
|
+
this.ensureNotReleased();
|
|
14
16
|
return this.canvas.width;
|
|
15
17
|
}
|
|
16
18
|
get height() {
|
|
19
|
+
this.ensureNotReleased();
|
|
17
20
|
return this.canvas.height;
|
|
18
21
|
}
|
|
19
22
|
async saveAsync(options = {
|
|
20
23
|
base64: false
|
|
21
24
|
}) {
|
|
25
|
+
this.ensureNotReleased();
|
|
26
|
+
const width = this.width;
|
|
27
|
+
const height = this.height;
|
|
22
28
|
return new Promise((resolve, reject)=>{
|
|
23
29
|
const requestedType = `image/${options.format ?? SaveFormat.JPEG}`;
|
|
24
30
|
this.canvas.toBlob(async (blob)=>{
|
|
@@ -32,13 +38,29 @@ export default class ImageManipulatorImageRef extends SharedRef {
|
|
|
32
38
|
const uri = URL.createObjectURL(blob);
|
|
33
39
|
resolve({
|
|
34
40
|
uri,
|
|
35
|
-
width
|
|
36
|
-
height
|
|
41
|
+
width,
|
|
42
|
+
height,
|
|
37
43
|
base64
|
|
38
44
|
});
|
|
39
45
|
}, requestedType, options.compress);
|
|
40
46
|
});
|
|
41
47
|
}
|
|
48
|
+
release() {
|
|
49
|
+
if (this.isReleased) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.isReleased = true;
|
|
53
|
+
if (this.uri.toLowerCase().startsWith('blob:')) {
|
|
54
|
+
URL.revokeObjectURL(this.uri);
|
|
55
|
+
}
|
|
56
|
+
releaseCanvas(this.canvas);
|
|
57
|
+
super.release();
|
|
58
|
+
}
|
|
59
|
+
ensureNotReleased() {
|
|
60
|
+
if (this.isReleased) {
|
|
61
|
+
throw new CodedError('ERR_IMAGE_MANIPULATOR_RELEASED', 'This image was released by release(). Render a new image with ImageManipulatorContext.renderAsync().');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
42
64
|
}
|
|
43
65
|
|
|
44
66
|
//# sourceMappingURL=ImageManipulatorImageRef.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["web/ImageManipulatorImageRef.web.ts"],"sourcesContent":[null],"names":["SharedRef","SaveFormat","blobToBase64String","ImageManipulatorImageRef","nativeRefType","uri","canvas","width","height","saveAsync","options","base64","Promise","resolve","reject","requestedType","format","JPEG","toBlob","blob","Error","type","undefined","URL","createObjectURL","compress"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"sources":["web/ImageManipulatorImageRef.web.ts"],"sourcesContent":[null],"names":["CodedError","SharedRef","SaveFormat","blobToBase64String","releaseCanvas","ImageManipulatorImageRef","nativeRefType","isReleased","uri","canvas","width","ensureNotReleased","height","saveAsync","options","base64","Promise","resolve","reject","requestedType","format","JPEG","toBlob","blob","Error","type","undefined","URL","createObjectURL","compress","release","toLowerCase","startsWith","revokeObjectURL"],"mappings":"AAAA,SAASA,UAAU,EAAEC,SAAS,QAAQ,OAAO;AAG7C,SAASC,UAAU,QAAQ,4BAA4B;AACvD,SAASC,kBAAkB,EAAEC,aAAa,QAAQ,cAAc;AAEhE,eAAe,MAAMC,iCAAiCJ;IAC3CK,gBAAwB,QAAQ;IACjCC,aAAa,MAAM;IAElBC,IAAY;IACZC,OAA0B;IAEnC,YAAYD,GAAW,EAAEC,MAAyB,CAAE;QAClD,KAAK;QACL,IAAI,CAACD,GAAG,GAAGA;QACX,IAAI,CAACC,MAAM,GAAGA;IAChB;IAEA,IAAIC,QAAQ;QACV,IAAI,CAACC,iBAAiB;QACtB,OAAO,IAAI,CAACF,MAAM,CAACC,KAAK;IAC1B;IAEA,IAAIE,SAAS;QACX,IAAI,CAACD,iBAAiB;QACtB,OAAO,IAAI,CAACF,MAAM,CAACG,MAAM;IAC3B;IAEA,MAAMC,UAAUC,UAAuB;QAAEC,QAAQ;IAAM,CAAC,EAAwB;QAC9E,IAAI,CAACJ,iBAAiB;QACtB,MAAMD,QAAQ,IAAI,CAACA,KAAK;QACxB,MAAME,SAAS,IAAI,CAACA,MAAM;QAC1B,OAAO,IAAII,QAAQ,CAACC,SAASC;YAC3B,MAAMC,gBAAgB,CAAC,MAAM,EAAEL,QAAQM,MAAM,IAAIlB,WAAWmB,IAAI,EAAE;YAClE,IAAI,CAACZ,MAAM,CAACa,MAAM,CAChB,OAAOC;gBACL,IAAI,CAACA,MAAM;oBACT,OAAOL,OAAO,IAAIM,MAAM,CAAC,sBAAsB,EAAE,IAAI,CAAChB,GAAG,EAAE;gBAC7D;gBACA,IAAIe,KAAKE,IAAI,KAAKN,eAAe;oBAC/B,OAAOD,OACL,IAAIM,MACF,CAAC,uCAAuC,EAAEL,cAAc,eAAe,EAAEI,KAAKE,IAAI,CAAC,mDAAmD,CAAC;gBAG7I;gBACA,MAAMV,SAASD,QAAQC,MAAM,GAAG,MAAMZ,mBAAmBoB,QAAQG;gBACjE,MAAMlB,MAAMmB,IAAIC,eAAe,CAACL;gBAEhCN,QAAQ;oBACNT;oBACAE;oBACAE;oBACAG;gBACF;YACF,GACAI,eACAL,QAAQe,QAAQ;QAEpB;IACF;IAEAC,UAAgB;QACd,IAAI,IAAI,CAACvB,UAAU,EAAE;YACnB;QACF;QACA,IAAI,CAACA,UAAU,GAAG;QAElB,IAAI,IAAI,CAACC,GAAG,CAACuB,WAAW,GAAGC,UAAU,CAAC,UAAU;YAC9CL,IAAIM,eAAe,CAAC,IAAI,CAACzB,GAAG;QAC9B;QACAJ,cAAc,IAAI,CAACK,MAAM;QACzB,KAAK,CAACqB;IACR;IAEQnB,oBAA0B;QAChC,IAAI,IAAI,CAACJ,UAAU,EAAE;YACnB,MAAM,IAAIP,WACR,kCACA;QAEJ;IACF;AACF"}
|
package/build/web/utils.web.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ImageLoadOptions } from '../ImageManipulator.types';
|
|
2
2
|
export declare function getContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D;
|
|
3
3
|
export declare function blobToBase64String(blob: Blob): Promise<string>;
|
|
4
|
+
export declare function releaseCanvas(canvas: HTMLCanvasElement): void;
|
|
4
5
|
export declare function loadImageAsync(uri: string, options?: ImageLoadOptions): Promise<HTMLCanvasElement>;
|
|
5
6
|
/**
|
|
6
7
|
* Computes the size that bounds an image of the given dimensions to `maxWidth`/`maxHeight`,
|
package/build/web/utils.web.js
CHANGED
|
@@ -15,6 +15,10 @@ export async function blobToBase64String(blob) {
|
|
|
15
15
|
});
|
|
16
16
|
return dataURL.replace(/^data:image\/\w+;base64,/, '');
|
|
17
17
|
}
|
|
18
|
+
export function releaseCanvas(canvas) {
|
|
19
|
+
canvas.width = 0;
|
|
20
|
+
canvas.height = 0;
|
|
21
|
+
}
|
|
18
22
|
export function loadImageAsync(uri, options) {
|
|
19
23
|
return new Promise((resolve, reject)=>{
|
|
20
24
|
const imageSource = new Image();
|
|
@@ -28,7 +32,10 @@ export function loadImageAsync(uri, options) {
|
|
|
28
32
|
context.drawImage(imageSource, 0, 0, width, height);
|
|
29
33
|
resolve(canvas);
|
|
30
34
|
};
|
|
31
|
-
imageSource.onerror = ()=>
|
|
35
|
+
imageSource.onerror = ()=>{
|
|
36
|
+
releaseCanvas(canvas);
|
|
37
|
+
reject(new CodedError('ERR_IMAGE_MANIPULATOR_LOAD', 'Failed to load the image. Make sure the source URI is accessible and has not been revoked or released.'));
|
|
38
|
+
};
|
|
32
39
|
imageSource.src = uri;
|
|
33
40
|
});
|
|
34
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["web/utils.web.ts"],"sourcesContent":[null],"names":["CodedError","getContext","canvas","ctx","blobToBase64String","blob","dataURL","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","Error","error","readAsDataURL","replace","loadImageAsync","uri","options","imageSource","Image","crossOrigin","document","createElement","onload","
|
|
1
|
+
{"version":3,"sources":["web/utils.web.ts"],"sourcesContent":[null],"names":["CodedError","getContext","canvas","ctx","blobToBase64String","blob","dataURL","Promise","resolve","reject","reader","FileReader","onloadend","result","onerror","Error","error","readAsDataURL","replace","releaseCanvas","width","height","loadImageAsync","uri","options","imageSource","Image","crossOrigin","document","createElement","onload","boundedSize","naturalWidth","naturalHeight","maxWidth","maxHeight","context","drawImage","src","scale","Math","min","max","round"],"mappings":"AAAA,SAASA,UAAU,QAAQ,OAAO;AAIlC,OAAO,SAASC,WAAWC,MAAyB;IAClD,MAAMC,MAAMD,OAAOD,UAAU,CAAC;IAC9B,IAAI,CAACE,KAAK;QACR,MAAM,IAAIH,WAAW,yBAAyB;IAChD;IACA,OAAOG;AACT;AAEA,OAAO,eAAeC,mBAAmBC,IAAU;IACjD,MAAMC,UAAU,MAAM,IAAIC,QAAgB,CAACC,SAASC;QAClD,MAAMC,SAAS,IAAIC;QACnBD,OAAOE,SAAS,GAAG,IAAMJ,QAAQE,OAAOG,MAAM;QAC9CH,OAAOI,OAAO,GAAG,IACfL,OAAO,IAAIM,MAAM,CAAC,yCAAyC,EAAEL,OAAOM,KAAK,EAAE;QAC7EN,OAAOO,aAAa,CAACZ;IACvB;IACA,OAAOC,QAAQY,OAAO,CAAC,4BAA4B;AACrD;AAEA,OAAO,SAASC,cAAcjB,MAAyB;IACrDA,OAAOkB,KAAK,GAAG;IACflB,OAAOmB,MAAM,GAAG;AAClB;AAEA,OAAO,SAASC,eACdC,GAAW,EACXC,OAA0B;IAE1B,OAAO,IAAIjB,QAAQ,CAACC,SAASC;QAC3B,MAAMgB,cAAc,IAAIC;QACxBD,YAAYE,WAAW,GAAG;QAC1B,MAAMzB,SAAS0B,SAASC,aAAa,CAAC;QACtCJ,YAAYK,MAAM,GAAG;YACnB,MAAM,EAAEV,KAAK,EAAEC,MAAM,EAAE,GAAGU,YACxBN,YAAYO,YAAY,EACxBP,YAAYQ,aAAa,EACzBT,SAASU,UACTV,SAASW;YAEXjC,OAAOkB,KAAK,GAAGA;YACflB,OAAOmB,MAAM,GAAGA;YAEhB,MAAMe,UAAUnC,WAAWC;YAC3BkC,QAAQC,SAAS,CAACZ,aAAa,GAAG,GAAGL,OAAOC;YAE5Cb,QAAQN;QACV;QACAuB,YAAYX,OAAO,GAAG;YACpBK,cAAcjB;YACdO,OACE,IAAIT,WACF,8BACA;QAGN;QACAyB,YAAYa,GAAG,GAAGf;IACpB;AACF;AAEA;;;CAGC,GACD,OAAO,SAASQ,YACdX,KAAa,EACbC,MAAc,EACda,QAA4B,EAC5BC,SAA6B;IAE7B,IAAII,QAAQ;IACZ,IAAIL,YAAYA,WAAW,GAAG;QAC5BK,QAAQC,KAAKC,GAAG,CAACF,OAAOL,WAAWd;IACrC;IACA,IAAIe,aAAaA,YAAY,GAAG;QAC9BI,QAAQC,KAAKC,GAAG,CAACF,OAAOJ,YAAYd;IACtC;IACA,IAAIkB,SAAS,GAAG;QACd,OAAO;YAAEnB;YAAOC;QAAO;IACzB;IACA,OAAO;QACLD,OAAOoB,KAAKE,GAAG,CAAC,GAAGF,KAAKG,KAAK,CAACvB,QAAQmB;QACtClB,QAAQmB,KAAKE,GAAG,CAAC,GAAGF,KAAKG,KAAK,CAACtB,SAASkB;IAC1C;AACF"}
|
package/expo-module.config.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.imagemanipulator",
|
|
6
|
-
"version": "58.0.
|
|
6
|
+
"version": "58.0.6",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
|
-
"name": "expo.modules.imagemanipulator-58.0.
|
|
28
|
-
"url": "expo.modules.imagemanipulator-58.0.
|
|
27
|
+
"name": "expo.modules.imagemanipulator-58.0.6.aar",
|
|
28
|
+
"url": "expo.modules.imagemanipulator-58.0.6.aar",
|
|
29
29
|
"size": 95460,
|
|
30
30
|
"sha512": "475e3a2be447c03f0182047320a23b69785edafa143644db1af90f31a267e9ec2f15ea6a6abaab9b18cefaea03e23cb152aa20a0f7137643f61b8a4c10947b14",
|
|
31
31
|
"sha256": "250d1ca6a5dd0d9c32dce53a3e615221cd6be59d1352fd37e6b35d346142fa7e",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
],
|
|
68
68
|
"files": [
|
|
69
69
|
{
|
|
70
|
-
"name": "expo.modules.imagemanipulator-58.0.
|
|
71
|
-
"url": "expo.modules.imagemanipulator-58.0.
|
|
70
|
+
"name": "expo.modules.imagemanipulator-58.0.6.aar",
|
|
71
|
+
"url": "expo.modules.imagemanipulator-58.0.6.aar",
|
|
72
72
|
"size": 95460,
|
|
73
73
|
"sha512": "475e3a2be447c03f0182047320a23b69785edafa143644db1af90f31a267e9ec2f15ea6a6abaab9b18cefaea03e23cb152aa20a0f7137643f61b8a4c10947b14",
|
|
74
74
|
"sha256": "250d1ca6a5dd0d9c32dce53a3e615221cd6be59d1352fd37e6b35d346142fa7e",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
},
|
|
88
88
|
"files": [
|
|
89
89
|
{
|
|
90
|
-
"name": "expo.modules.imagemanipulator-58.0.
|
|
91
|
-
"url": "expo.modules.imagemanipulator-58.0.
|
|
90
|
+
"name": "expo.modules.imagemanipulator-58.0.6-sources.jar",
|
|
91
|
+
"url": "expo.modules.imagemanipulator-58.0.6-sources.jar",
|
|
92
92
|
"size": 8679,
|
|
93
93
|
"sha512": "4cda13902745f76d0135333dd19c5f8ab5e953146d9340d67c46aa834fb8aa4f5deab6dcdcbd8df516ac629e05f42b4ebee165fd3b254ffd8f995c0339611995",
|
|
94
94
|
"sha256": "5443d494e986ec5a39b06bf9f24e7cd9ec96f4e9d97a1b04d177ecf5d0d8162b",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b7be11d20bc3be57fc09cc7a7e508ba0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ae13a73481426af0c29de4169e890641fb97746e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
08c806fc0b1444884f5faf5f9873c4214cca20ff16f0333dcf6efb2e2cf25483
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6693aca8d804feb554bc1cdacc17d0e87d1ec44a48e39cc9bd0559d781ce98029852d1e41cccb4e4a6dcbaa75c67a3de3fbc44ab135d7528849c9c916425a98f
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.imagemanipulator</artifactId>
|
|
12
|
-
<version>58.0.
|
|
12
|
+
<version>58.0.6</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.imagemanipulator</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
74e7e599bca3bb0c44adee1320db8cbd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f1ce6af019735d3a10c18b1c913f2b36d24e4c10
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9f6884a045e079a7197bdd8e3f92d56431074927eddc4ce37232b3af4eb6d366
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
25219120b2804ded42181345358e5004930968460fe82b2e2a9de0547d6dcd2de8a2ed896d867a3a654c12738a885aabad58da1ca9526b0ebc9e7214952dfd83
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>host.exp.exponent</groupId>
|
|
4
4
|
<artifactId>expo.modules.imagemanipulator</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>58.0.
|
|
7
|
-
<release>58.0.
|
|
6
|
+
<latest>58.0.6</latest>
|
|
7
|
+
<release>58.0.6</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>58.0.
|
|
9
|
+
<version>58.0.6</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20260922160128</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.md5
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
42020f3c836447d7ec7e1dc1f57b47e7
|
package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha1
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ba600e6658b683c084da15e014fd13070d617a08
|
package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
30759caaebe64b12c772c4ab19e59b5af2cf6fe1ed59a8804e013755ecb960a6
|
package/local-maven-repo/host/exp/exponent/expo.modules.imagemanipulator/maven-metadata.xml.sha512
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d0e5c38f9d726dd7677db106728827757871a67e55a05f6cc042a474108fc0dc18feefd8e6777e3d31696c7d240e07663c78dc6d7e9212a44b1bac1569c6281c
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-image-manipulator",
|
|
3
|
-
"version": "58.0.
|
|
3
|
+
"version": "58.0.6",
|
|
4
4
|
"description": "Provides functions that let you manipulation images on the local file system, eg: resize, crop.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"expo",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"expo-image-loader": "~58.0.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/react": "~19.
|
|
40
|
-
"expo": "58.0.0-preview.
|
|
39
|
+
"@types/react": "~19.3.0",
|
|
40
|
+
"expo": "58.0.0-preview.5",
|
|
41
41
|
"expo-module-scripts": "56.0.3"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"jest": {
|
|
49
49
|
"preset": "expo-module-scripts"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "add8cbf49f477cfd2283ae05af35b4713a773c55",
|
|
52
52
|
"scripts": {
|
|
53
53
|
"precompile-ios": "et prebuild-package-for-publish",
|
|
54
54
|
"build": "expo-build src",
|
|
Binary file
|
|
Binary file
|
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>SDWebImage.framework/SDWebImage</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-
|
|
11
|
+
<string>ios-arm64</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>SDWebImage.framework</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
15
15
|
<array>
|
|
16
16
|
<string>arm64</string>
|
|
17
|
-
<string>x86_64</string>
|
|
18
17
|
</array>
|
|
19
18
|
<key>SupportedPlatform</key>
|
|
20
19
|
<string>ios</string>
|
|
21
|
-
<key>SupportedPlatformVariant</key>
|
|
22
|
-
<string>simulator</string>
|
|
23
20
|
</dict>
|
|
24
21
|
<dict>
|
|
25
22
|
<key>BinaryPath</key>
|
|
26
23
|
<string>SDWebImage.framework/SDWebImage</string>
|
|
27
24
|
<key>LibraryIdentifier</key>
|
|
28
|
-
<string>ios-
|
|
25
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
29
26
|
<key>LibraryPath</key>
|
|
30
27
|
<string>SDWebImage.framework</string>
|
|
31
28
|
<key>SupportedArchitectures</key>
|
|
32
29
|
<array>
|
|
33
30
|
<string>arm64</string>
|
|
31
|
+
<string>x86_64</string>
|
|
34
32
|
</array>
|
|
35
33
|
<key>SupportedPlatform</key>
|
|
36
34
|
<string>ios</string>
|
|
35
|
+
<key>SupportedPlatformVariant</key>
|
|
36
|
+
<string>simulator</string>
|
|
37
37
|
</dict>
|
|
38
38
|
</array>
|
|
39
39
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { SharedObject } from 'expo';
|
|
1
|
+
import { CodedError, SharedObject } from 'expo';
|
|
2
2
|
|
|
3
3
|
import type { ActionCrop, ActionExtent, FlipType } from '../ImageManipulator.types';
|
|
4
4
|
import ImageManipulatorImageRef from './ImageManipulatorImageRef.web';
|
|
5
5
|
import { crop, extent, flip, resize, rotate } from './actions/index.web';
|
|
6
|
+
import { releaseCanvas } from './utils.web';
|
|
6
7
|
|
|
7
8
|
type ContextLoader = () => HTMLCanvasElement | Promise<HTMLCanvasElement>;
|
|
8
9
|
|
|
9
10
|
export default class ImageManipulatorContext extends SharedObject {
|
|
10
|
-
private loader: ContextLoader;
|
|
11
|
+
private loader: ContextLoader | undefined;
|
|
12
|
+
private isReleased = false;
|
|
11
13
|
|
|
12
14
|
private _currentTask: Promise<HTMLCanvasElement> | undefined;
|
|
13
15
|
get currentTask() {
|
|
16
|
+
this.ensureNotReleased();
|
|
14
17
|
if (this._currentTask) {
|
|
15
18
|
return this._currentTask;
|
|
16
19
|
}
|
|
17
|
-
this._currentTask = new Promise((resolve) => resolve(this.loader()));
|
|
20
|
+
this._currentTask = new Promise((resolve) => resolve(this.loader!()));
|
|
18
21
|
return this._currentTask;
|
|
19
22
|
}
|
|
20
23
|
set currentTask(task) {
|
|
24
|
+
this.ensureNotReleased();
|
|
21
25
|
this._currentTask = task;
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -47,10 +51,25 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
reset(): ImageManipulatorContext {
|
|
50
|
-
this.
|
|
54
|
+
this.ensureNotReleased();
|
|
55
|
+
const previousTask = this._currentTask;
|
|
56
|
+
this.currentTask = new Promise((resolve) => resolve(this.loader!()));
|
|
57
|
+
this.releaseTask(previousTask);
|
|
51
58
|
return this;
|
|
52
59
|
}
|
|
53
60
|
|
|
61
|
+
release(): void {
|
|
62
|
+
if (this.isReleased) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.isReleased = true;
|
|
66
|
+
|
|
67
|
+
this.releaseTask(this._currentTask);
|
|
68
|
+
this._currentTask = undefined;
|
|
69
|
+
this.loader = undefined;
|
|
70
|
+
super.release();
|
|
71
|
+
}
|
|
72
|
+
|
|
54
73
|
async renderAsync(): Promise<ImageManipulatorImageRef> {
|
|
55
74
|
const canvas = await this.currentTask;
|
|
56
75
|
|
|
@@ -64,10 +83,10 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
64
83
|
clonedCanvasCtx?.drawImage(canvas, 0, 0);
|
|
65
84
|
|
|
66
85
|
return new Promise((resolve) => {
|
|
67
|
-
//
|
|
68
|
-
|
|
86
|
+
// Encode the clone, which remains valid if the context is released or reset.
|
|
87
|
+
clonedCanvas.toBlob(
|
|
69
88
|
(blob) => {
|
|
70
|
-
const url = blob ? URL.createObjectURL(blob) :
|
|
89
|
+
const url = blob ? URL.createObjectURL(blob) : clonedCanvas.toDataURL();
|
|
71
90
|
const image = new ImageManipulatorImageRef(url, clonedCanvas);
|
|
72
91
|
|
|
73
92
|
resolve(image);
|
|
@@ -82,9 +101,32 @@ export default class ImageManipulatorContext extends SharedObject {
|
|
|
82
101
|
private addTask(
|
|
83
102
|
task: (canvas: HTMLCanvasElement) => HTMLCanvasElement | Promise<HTMLCanvasElement>
|
|
84
103
|
): ImageManipulatorContext {
|
|
85
|
-
this.currentTask = this.currentTask.then((canvas) => {
|
|
86
|
-
|
|
104
|
+
this.currentTask = this.currentTask.then(async (canvas) => {
|
|
105
|
+
try {
|
|
106
|
+
const result = await task(canvas);
|
|
107
|
+
if (result !== canvas) {
|
|
108
|
+
releaseCanvas(canvas);
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
releaseCanvas(canvas);
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
87
115
|
});
|
|
88
116
|
return this;
|
|
89
117
|
}
|
|
118
|
+
|
|
119
|
+
private ensureNotReleased(): void {
|
|
120
|
+
if (this.isReleased) {
|
|
121
|
+
throw new CodedError(
|
|
122
|
+
'ERR_IMAGE_MANIPULATOR_RELEASED',
|
|
123
|
+
'This image manipulation context was released by release() or by useImageManipulator when its source changed or its component unmounted. Create a new context with ImageManipulator.manipulate(...).'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private releaseTask(task: Promise<HTMLCanvasElement> | undefined): void {
|
|
129
|
+
// Failed tasks clean up their own canvases.
|
|
130
|
+
task?.then(releaseCanvas, () => {});
|
|
131
|
+
}
|
|
90
132
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { SharedRef } from 'expo';
|
|
1
|
+
import { CodedError, SharedRef } from 'expo';
|
|
2
2
|
|
|
3
3
|
import type { ImageResult, SaveOptions } from '../ImageManipulator.types';
|
|
4
4
|
import { SaveFormat } from '../ImageManipulator.types';
|
|
5
|
-
import { blobToBase64String } from './utils.web';
|
|
5
|
+
import { blobToBase64String, releaseCanvas } from './utils.web';
|
|
6
6
|
|
|
7
7
|
export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
8
8
|
readonly nativeRefType: string = 'image';
|
|
9
|
+
private isReleased = false;
|
|
9
10
|
|
|
10
11
|
readonly uri: string;
|
|
11
12
|
readonly canvas: HTMLCanvasElement;
|
|
@@ -17,14 +18,19 @@ export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
get width() {
|
|
21
|
+
this.ensureNotReleased();
|
|
20
22
|
return this.canvas.width;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
get height() {
|
|
26
|
+
this.ensureNotReleased();
|
|
24
27
|
return this.canvas.height;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
async saveAsync(options: SaveOptions = { base64: false }): Promise<ImageResult> {
|
|
31
|
+
this.ensureNotReleased();
|
|
32
|
+
const width = this.width;
|
|
33
|
+
const height = this.height;
|
|
28
34
|
return new Promise((resolve, reject) => {
|
|
29
35
|
const requestedType = `image/${options.format ?? SaveFormat.JPEG}`;
|
|
30
36
|
this.canvas.toBlob(
|
|
@@ -44,8 +50,8 @@ export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
|
44
50
|
|
|
45
51
|
resolve({
|
|
46
52
|
uri,
|
|
47
|
-
width
|
|
48
|
-
height
|
|
53
|
+
width,
|
|
54
|
+
height,
|
|
49
55
|
base64,
|
|
50
56
|
});
|
|
51
57
|
},
|
|
@@ -54,4 +60,26 @@ export default class ImageManipulatorImageRef extends SharedRef<'image'> {
|
|
|
54
60
|
);
|
|
55
61
|
});
|
|
56
62
|
}
|
|
63
|
+
|
|
64
|
+
release(): void {
|
|
65
|
+
if (this.isReleased) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.isReleased = true;
|
|
69
|
+
|
|
70
|
+
if (this.uri.toLowerCase().startsWith('blob:')) {
|
|
71
|
+
URL.revokeObjectURL(this.uri);
|
|
72
|
+
}
|
|
73
|
+
releaseCanvas(this.canvas);
|
|
74
|
+
super.release();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private ensureNotReleased(): void {
|
|
78
|
+
if (this.isReleased) {
|
|
79
|
+
throw new CodedError(
|
|
80
|
+
'ERR_IMAGE_MANIPULATOR_RELEASED',
|
|
81
|
+
'This image was released by release(). Render a new image with ImageManipulatorContext.renderAsync().'
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
57
85
|
}
|
package/src/web/utils.web.ts
CHANGED
|
@@ -21,6 +21,11 @@ export async function blobToBase64String(blob: Blob): Promise<string> {
|
|
|
21
21
|
return dataURL.replace(/^data:image\/\w+;base64,/, '');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export function releaseCanvas(canvas: HTMLCanvasElement): void {
|
|
25
|
+
canvas.width = 0;
|
|
26
|
+
canvas.height = 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
export function loadImageAsync(
|
|
25
30
|
uri: string,
|
|
26
31
|
options?: ImageLoadOptions
|
|
@@ -44,7 +49,15 @@ export function loadImageAsync(
|
|
|
44
49
|
|
|
45
50
|
resolve(canvas);
|
|
46
51
|
};
|
|
47
|
-
imageSource.onerror = () =>
|
|
52
|
+
imageSource.onerror = () => {
|
|
53
|
+
releaseCanvas(canvas);
|
|
54
|
+
reject(
|
|
55
|
+
new CodedError(
|
|
56
|
+
'ERR_IMAGE_MANIPULATOR_LOAD',
|
|
57
|
+
'Failed to load the image. Make sure the source URI is accessible and has not been revoked or released.'
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
};
|
|
48
61
|
imageSource.src = uri;
|
|
49
62
|
});
|
|
50
63
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2389d79b344466f3077193da9549e083
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ec905b6c60705bf39609ff4cbb7edd2406d15a1d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
34bd3065f95460a2ba050b071b69200ebc1b96b626812aacc5667c335379845c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8e76d76ebd69bde014e574309603280ed83f498fa701eace098ff1927f35579977fdbde29c25477cc221c1ed5752f83e7b95bdd43ccec01118d90a8c2c17b566
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
585f50b551fd02bc4f535b8ae9933739
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
26c5f9e5cb1fa1bc75867675dee3ba576eb95f34
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
04fc4615baf2e5f0e0fa2fccfb3ed46222e6450ca16a1dca4480cfeae09260b1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
145ac8540323042c96a1ee73e1e593e0d66b003946764ca47b52afdabeb300fa6ca58d4bcb6b9ea4a5f9dcbfd0350685aaf26a34c1b6fa7518f6bd692322be33
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|