expo-image-manipulator 9.2.2 → 10.0.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/CHANGELOG.md +18 -3
- package/android/build.gradle +7 -12
- package/android/src/main/java/expo/modules/imagemanipulator/FileUtils.kt +4 -4
- package/android/src/main/java/expo/modules/imagemanipulator/ImageManipulatorModule.kt +23 -21
- package/android/src/main/java/expo/modules/imagemanipulator/ImageManipulatorPackage.kt +1 -2
- package/android/src/main/java/expo/modules/imagemanipulator/actions/RotateAction.kt +1 -1
- package/android/src/main/java/expo/modules/imagemanipulator/arguments/SaveOptions.kt +1 -1
- package/build/ExpoImageManipulator.d.ts +1 -1
- package/build/ExpoImageManipulator.js +1 -1
- package/build/ExpoImageManipulator.js.map +1 -1
- package/build/ExpoImageManipulator.web.js +30 -221
- package/build/ExpoImageManipulator.web.js.map +1 -1
- package/build/ImageManipulator.d.ts +11 -0
- package/build/ImageManipulator.js +13 -1
- package/build/ImageManipulator.js.map +1 -1
- package/build/ImageManipulator.types.d.ts +50 -2
- package/build/ImageManipulator.types.js +5 -1
- package/build/ImageManipulator.types.js.map +1 -1
- package/build/actions/CropAction.web.d.ts +3 -0
- package/build/actions/CropAction.web.js +25 -0
- package/build/actions/CropAction.web.js.map +1 -0
- package/build/actions/FlipAction.web.d.ts +3 -0
- package/build/actions/FlipAction.web.js +20 -0
- package/build/actions/FlipAction.web.js.map +1 -0
- package/build/actions/ResizeAction.web.d.ts +3 -0
- package/build/actions/ResizeAction.web.js +102 -0
- package/build/actions/ResizeAction.web.js.map +1 -0
- package/build/actions/RotateAction.web.d.ts +3 -0
- package/build/actions/RotateAction.web.js +29 -0
- package/build/actions/RotateAction.web.js.map +1 -0
- package/build/actions/index.web.d.ts +4 -0
- package/build/actions/index.web.js +5 -0
- package/build/actions/index.web.js.map +1 -0
- package/build/utils/getContext.web.d.ts +1 -0
- package/build/utils/getContext.web.js +9 -0
- package/build/utils/getContext.web.js.map +1 -0
- package/ios/EXImageManipulator/EXImageManipulatorModule.h +3 -3
- package/ios/EXImageManipulator/EXImageManipulatorModule.m +18 -8
- package/ios/EXImageManipulator.podspec +2 -2
- package/package.json +4 -7
- package/src/ExpoImageManipulator.ts +1 -1
- package/src/ExpoImageManipulator.web.ts +32 -296
- package/src/ImageManipulator.ts +13 -1
- package/src/ImageManipulator.types.ts +59 -3
- package/src/actions/CropAction.web.ts +35 -0
- package/src/actions/FlipAction.web.ts +26 -0
- package/src/actions/ResizeAction.web.ts +119 -0
- package/src/actions/RotateAction.web.ts +41 -0
- package/src/actions/index.web.ts +4 -0
- package/src/utils/getContext.web.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,15 +10,30 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## 10.0.0 — 2021-09-28
|
|
14
|
+
|
|
15
|
+
### 🛠 Breaking changes
|
|
16
|
+
|
|
17
|
+
- Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
|
|
18
|
+
|
|
19
|
+
### 🎉 New features
|
|
20
|
+
|
|
21
|
+
- Support loading base64 data URIs on iOS. ([#13725](https://github.com/expo/expo/pull/13725) by [@mnightingale](https://github.com/mnightingale))
|
|
14
22
|
|
|
15
23
|
### 🐛 Bug fixes
|
|
16
24
|
|
|
17
25
|
- Fix resize action validator to allow providing just one of `width` or `height`. ([#13369](https://github.com/expo/expo/pull/13369) by [@cruzach](https://github.com/cruzach))
|
|
26
|
+
- Fix incorrect compression used when `0` is requested on web. ([#13728](https://github.com/expo/expo/pull/13728) by [@mnightingale](https://github.com/mnightingale))
|
|
27
|
+
- Fix Android `manipulateAsync` returns incorrect height (original unmanipulated height). ([#13726](https://github.com/expo/expo/pull/13726) by [@mnightingale](https://github.com/mnightingale))
|
|
28
|
+
- Fixed Android to use filename extension consistent with other platforms. ([#13726](https://github.com/expo/expo/pull/13726) by [@mnightingale](https://github.com/mnightingale))
|
|
29
|
+
- Fixed rotation direction to be clockwise on web. ([#13760](https://github.com/expo/expo/pull/13760) by [@mnightingale](https://github.com/mnightingale))
|
|
30
|
+
- Fixed web support for multiple actions. ([#14056](https://github.com/expo/expo/pull/14056) by [@mnightingale](https://github.com/mnightingale))
|
|
31
|
+
- Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
### 💡 Others
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
- Migrated from `@unimodules/core` to `expo-modules-core`. ([#13757](https://github.com/expo/expo/pull/13757) by [@tsapeta](https://github.com/tsapeta))
|
|
36
|
+
- Refactored web to pass canvases to each action avoiding multiple calls to `toDataURL`. ([#14145](https://github.com/expo/expo/pull/14145) by [@mnightingale](https://github.com/mnightingale))
|
|
22
37
|
|
|
23
38
|
## 9.2.0 — 2021-06-16
|
|
24
39
|
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '
|
|
6
|
+
version = '10.0.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
// Simple helper that allows the root project to override versions declared by this library.
|
|
@@ -53,28 +53,23 @@ android {
|
|
|
53
53
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
kotlinOptions {
|
|
57
|
+
jvmTarget = JavaVersion.VERSION_1_8
|
|
58
|
+
}
|
|
59
|
+
|
|
56
60
|
defaultConfig {
|
|
57
61
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
58
62
|
targetSdkVersion safeExtGet("targetSdkVersion", 30)
|
|
59
63
|
versionCode 23
|
|
60
|
-
versionName "
|
|
64
|
+
versionName "10.0.0"
|
|
61
65
|
}
|
|
62
66
|
lintOptions {
|
|
63
67
|
abortOnError false
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
if (new File(rootProject.projectDir.parentFile, 'package.json').exists()) {
|
|
68
|
-
apply from: project(':unimodules-core').file('../unimodules-core.gradle')
|
|
69
|
-
} else {
|
|
70
|
-
throw new GradleException(
|
|
71
|
-
'\'unimodules-core.gradle\' was not found in the usual React Native dependency location. ' +
|
|
72
|
-
'This package can only be used in such projects. Are you sure you\'ve installed the dependencies properly?')
|
|
73
|
-
}
|
|
74
|
-
|
|
75
71
|
dependencies {
|
|
76
|
-
|
|
77
|
-
unimodule 'expo-modules-core'
|
|
72
|
+
implementation project(':expo-modules-core')
|
|
78
73
|
|
|
79
74
|
api "androidx.annotation:annotation:1.0.0"
|
|
80
75
|
|
|
@@ -9,9 +9,9 @@ import java.util.*
|
|
|
9
9
|
internal object FileUtils {
|
|
10
10
|
@Throws(IOException::class)
|
|
11
11
|
fun generateRandomOutputPath(context: Context, compressFormat: CompressFormat): String {
|
|
12
|
-
val directory = File("${context.cacheDir
|
|
12
|
+
val directory = File("${context.cacheDir}${File.separator}ImageManipulator")
|
|
13
13
|
ensureDirExists(directory)
|
|
14
|
-
return "${directory
|
|
14
|
+
return "${directory}${File.separator}${UUID.randomUUID()}${toExtension(compressFormat)}"
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
@Throws(IOException::class)
|
|
@@ -24,9 +24,9 @@ internal object FileUtils {
|
|
|
24
24
|
|
|
25
25
|
private fun toExtension(compressFormat: CompressFormat): String {
|
|
26
26
|
return when (compressFormat) {
|
|
27
|
-
CompressFormat.JPEG -> ".
|
|
27
|
+
CompressFormat.JPEG -> ".jpg"
|
|
28
28
|
CompressFormat.PNG -> ".png"
|
|
29
|
-
else -> ".
|
|
29
|
+
else -> ".jpg"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -9,16 +9,15 @@ import expo.modules.imagemanipulator.arguments.Actions
|
|
|
9
9
|
import expo.modules.imagemanipulator.arguments.SaveOptions
|
|
10
10
|
import expo.modules.interfaces.imageloader.ImageLoaderInterface
|
|
11
11
|
import expo.modules.interfaces.imageloader.ImageLoaderInterface.ResultListener
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
12
|
+
import expo.modules.core.ExportedModule
|
|
13
|
+
import expo.modules.core.ModuleRegistry
|
|
14
|
+
import expo.modules.core.ModuleRegistryDelegate
|
|
15
|
+
import expo.modules.core.Promise
|
|
16
|
+
import expo.modules.core.arguments.ReadableArguments
|
|
17
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
18
18
|
import java.io.ByteArrayOutputStream
|
|
19
19
|
import java.io.File
|
|
20
20
|
import java.io.FileOutputStream
|
|
21
|
-
import java.io.IOException
|
|
22
21
|
import java.util.*
|
|
23
22
|
|
|
24
23
|
private const val TAG = "ExpoImageManipulator"
|
|
@@ -26,7 +25,7 @@ private const val ERROR_TAG = "E_IMAGE_MANIPULATOR"
|
|
|
26
25
|
|
|
27
26
|
class ImageManipulatorModule(
|
|
28
27
|
context: Context,
|
|
29
|
-
private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate()
|
|
28
|
+
private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate()
|
|
30
29
|
) : ExportedModule(context) {
|
|
31
30
|
private val mImageLoader: ImageLoaderInterface by moduleRegistry()
|
|
32
31
|
|
|
@@ -41,21 +40,24 @@ class ImageManipulatorModule(
|
|
|
41
40
|
fun manipulateAsync(uri: String, actionsRaw: ArrayList<Any?>, saveOptionsRaw: ReadableArguments, promise: Promise) {
|
|
42
41
|
val saveOptions = SaveOptions.fromArguments(saveOptionsRaw)
|
|
43
42
|
val actions = Actions.fromArgument(actionsRaw)
|
|
44
|
-
mImageLoader.loadImageForManipulationFromURL(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
mImageLoader.loadImageForManipulationFromURL(
|
|
44
|
+
uri,
|
|
45
|
+
object : ResultListener {
|
|
46
|
+
override fun onSuccess(bitmap: Bitmap) {
|
|
47
|
+
runActions(bitmap, actions, saveOptions, promise)
|
|
48
|
+
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
override fun onFailure(cause: Throwable?) {
|
|
51
|
+
// No cleanup required here.
|
|
52
|
+
val basicMessage = "Could not get decoded bitmap of $uri"
|
|
53
|
+
if (cause != null) {
|
|
54
|
+
promise.reject("${ERROR_TAG}_DECODE", "$basicMessage: $cause", cause)
|
|
55
|
+
} else {
|
|
56
|
+
promise.reject("${ERROR_TAG}_DECODE", "$basicMessage.")
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
|
-
|
|
60
|
+
)
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
private fun runActions(bitmap: Bitmap, actions: Actions, saveOptions: SaveOptions, promise: Promise) {
|
|
@@ -78,7 +80,7 @@ class ImageManipulatorModule(
|
|
|
78
80
|
val result = Bundle().apply {
|
|
79
81
|
putString("uri", Uri.fromFile(File(path)).toString())
|
|
80
82
|
putInt("width", resultBitmap.width)
|
|
81
|
-
putInt("height",
|
|
83
|
+
putInt("height", resultBitmap.height)
|
|
82
84
|
if (base64String != null) {
|
|
83
85
|
putString("base64", base64String)
|
|
84
86
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
package expo.modules.imagemanipulator
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
-
import
|
|
5
|
-
import org.unimodules.core.ExportedModule
|
|
4
|
+
import expo.modules.core.BasePackage
|
|
6
5
|
|
|
7
6
|
class ImageManipulatorPackage : BasePackage() {
|
|
8
7
|
override fun createExportedModules(context: Context) = listOf(ImageManipulatorModule(context))
|
|
@@ -3,7 +3,7 @@ package expo.modules.imagemanipulator.actions
|
|
|
3
3
|
import android.graphics.Bitmap
|
|
4
4
|
import android.graphics.Matrix
|
|
5
5
|
|
|
6
|
-
class RotateAction
|
|
6
|
+
class RotateAction(private val rotation: Int) : Action {
|
|
7
7
|
override fun run(bitmap: Bitmap): Bitmap {
|
|
8
8
|
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, rotationMatrix, true)
|
|
9
9
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("
|
|
1
|
+
declare const _default: import("expo-modules-core").ProxyNativeModule;
|
|
2
2
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoImageManipulator.js","sourceRoot":"","sources":["../src/ExpoImageManipulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ExpoImageManipulator.js","sourceRoot":"","sources":["../src/ExpoImageManipulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,eAAe,kBAAkB,CAAC,oBAAoB,IAAI,EAAE,CAAC","sourcesContent":["import { NativeModulesProxy } from 'expo-modules-core';\nexport default NativeModulesProxy.ExpoImageManipulator || {};\n"]}
|
|
@@ -1,134 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
/**
|
|
4
|
-
* Hermite resize - fast image resize/resample using Hermite filter. 1 cpu version!
|
|
5
|
-
* https://stackoverflow.com/a/18320662/4047926
|
|
6
|
-
*
|
|
7
|
-
* @param {HtmlElement} canvas
|
|
8
|
-
* @param {int} width
|
|
9
|
-
* @param {int} height
|
|
10
|
-
* @param {boolean} resizeCanvas if true, canvas will be resized. Optional.
|
|
11
|
-
*/
|
|
12
|
-
function resampleSingle(canvas, width, height, resizeCanvas = false) {
|
|
13
|
-
const widthSource = canvas.width;
|
|
14
|
-
const heightSource = canvas.height;
|
|
15
|
-
width = Math.round(width);
|
|
16
|
-
height = Math.round(height);
|
|
17
|
-
const wRatio = widthSource / width;
|
|
18
|
-
const hRatio = heightSource / height;
|
|
19
|
-
const wRatioHalf = Math.ceil(wRatio / 2);
|
|
20
|
-
const hRatioHalf = Math.ceil(hRatio / 2);
|
|
21
|
-
const ctx = getContext(canvas);
|
|
22
|
-
const img = ctx.getImageData(0, 0, widthSource, heightSource);
|
|
23
|
-
const img2 = ctx.createImageData(width, height);
|
|
24
|
-
const data = img.data;
|
|
25
|
-
const data2 = img2.data;
|
|
26
|
-
for (let j = 0; j < height; j++) {
|
|
27
|
-
for (let i = 0; i < width; i++) {
|
|
28
|
-
const x2 = (i + j * width) * 4;
|
|
29
|
-
let weight = 0;
|
|
30
|
-
let weights = 0;
|
|
31
|
-
let weightsAlpha = 0;
|
|
32
|
-
let gx_r = 0;
|
|
33
|
-
let gx_g = 0;
|
|
34
|
-
let gx_b = 0;
|
|
35
|
-
let gx_a = 0;
|
|
36
|
-
const yCenter = (j + 0.5) * hRatio;
|
|
37
|
-
const yy_start = Math.floor(j * hRatio);
|
|
38
|
-
const yy_stop = Math.ceil((j + 1) * hRatio);
|
|
39
|
-
for (let yy = yy_start; yy < yy_stop; yy++) {
|
|
40
|
-
const dy = Math.abs(yCenter - (yy + 0.5)) / hRatioHalf;
|
|
41
|
-
const center_x = (i + 0.5) * wRatio;
|
|
42
|
-
const w0 = dy * dy; //pre-calc part of w
|
|
43
|
-
const xx_start = Math.floor(i * wRatio);
|
|
44
|
-
const xx_stop = Math.ceil((i + 1) * wRatio);
|
|
45
|
-
for (let xx = xx_start; xx < xx_stop; xx++) {
|
|
46
|
-
const dx = Math.abs(center_x - (xx + 0.5)) / wRatioHalf;
|
|
47
|
-
const w = Math.sqrt(w0 + dx * dx);
|
|
48
|
-
if (w >= 1) {
|
|
49
|
-
//pixel too far
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
//hermite filter
|
|
53
|
-
weight = 2 * w * w * w - 3 * w * w + 1;
|
|
54
|
-
const xPosition = 4 * (xx + yy * widthSource);
|
|
55
|
-
//alpha
|
|
56
|
-
gx_a += weight * data[xPosition + 3];
|
|
57
|
-
weightsAlpha += weight;
|
|
58
|
-
//colors
|
|
59
|
-
if (data[xPosition + 3] < 255) {
|
|
60
|
-
weight = (weight * data[xPosition + 3]) / 250;
|
|
61
|
-
}
|
|
62
|
-
gx_r += weight * data[xPosition];
|
|
63
|
-
gx_g += weight * data[xPosition + 1];
|
|
64
|
-
gx_b += weight * data[xPosition + 2];
|
|
65
|
-
weights += weight;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
data2[x2] = gx_r / weights;
|
|
69
|
-
data2[x2 + 1] = gx_g / weights;
|
|
70
|
-
data2[x2 + 2] = gx_b / weights;
|
|
71
|
-
data2[x2 + 3] = gx_a / weightsAlpha;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
//clear and resize canvas
|
|
75
|
-
if (resizeCanvas) {
|
|
76
|
-
canvas.width = width;
|
|
77
|
-
canvas.height = height;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
ctx.clearRect(0, 0, widthSource, heightSource);
|
|
81
|
-
}
|
|
82
|
-
//draw
|
|
83
|
-
ctx.putImageData(img2, 0, 0);
|
|
84
|
-
}
|
|
85
|
-
function sizeFromAngle(width, height, angle) {
|
|
86
|
-
const radians = (angle * Math.PI) / 180;
|
|
87
|
-
let c = Math.cos(radians);
|
|
88
|
-
let s = Math.sin(radians);
|
|
89
|
-
if (s < 0) {
|
|
90
|
-
s = -s;
|
|
91
|
-
}
|
|
92
|
-
if (c < 0) {
|
|
93
|
-
c = -c;
|
|
94
|
-
}
|
|
95
|
-
return { width: height * s + width * c, height: height * c + width * s };
|
|
96
|
-
}
|
|
97
|
-
function cropImage(canvas, image, x = 0, y = 0, width = 0, height = 0) {
|
|
98
|
-
const context = getContext(canvas);
|
|
99
|
-
context.save();
|
|
100
|
-
context.drawImage(image, x, y, width, height, 0, 0, width, height);
|
|
101
|
-
}
|
|
102
|
-
function drawImage(canvas, img, x = 0, y = 0, angle = 0, xFlip = false, yFlip = false, width, height) {
|
|
103
|
-
const context = getContext(canvas);
|
|
104
|
-
context.save();
|
|
105
|
-
if (width == null) {
|
|
106
|
-
width = img.naturalWidth;
|
|
107
|
-
}
|
|
108
|
-
if (height == null) {
|
|
109
|
-
height = img.naturalHeight;
|
|
110
|
-
}
|
|
111
|
-
// Set the origin to the center of the image
|
|
112
|
-
context.translate(x + canvas.width / 2, y + canvas.height / 2);
|
|
113
|
-
// Rotate the canvas around the origin
|
|
114
|
-
const radians = 2 * Math.PI - (angle * Math.PI) / 180;
|
|
115
|
-
context.rotate(radians);
|
|
116
|
-
// Flip/flop the canvas
|
|
117
|
-
const xScale = xFlip ? -1 : 1;
|
|
118
|
-
const yScale = yFlip ? -1 : 1;
|
|
119
|
-
context.scale(xScale, yScale);
|
|
120
|
-
// Draw the image
|
|
121
|
-
context.drawImage(img, -img.naturalWidth / 2, -img.naturalHeight / 2, img.naturalWidth, img.naturalHeight);
|
|
122
|
-
context.restore();
|
|
123
|
-
return context;
|
|
124
|
-
}
|
|
125
|
-
function getContext(canvas) {
|
|
126
|
-
const ctx = canvas.getContext('2d');
|
|
127
|
-
if (!ctx) {
|
|
128
|
-
throw new CodedError('ERR_IMAGE_MANIPULATOR', 'Failed to create canvas context');
|
|
129
|
-
}
|
|
130
|
-
return ctx;
|
|
131
|
-
}
|
|
1
|
+
import { crop, flip, resize, rotate } from './actions/index.web';
|
|
2
|
+
import { getContext } from './utils/getContext.web';
|
|
132
3
|
function getResults(canvas, options) {
|
|
133
4
|
let base64;
|
|
134
5
|
if (options) {
|
|
@@ -136,7 +7,7 @@ function getResults(canvas, options) {
|
|
|
136
7
|
if (options.format === 'png' && options.compress !== undefined) {
|
|
137
8
|
console.warn('compress is not supported with png format.');
|
|
138
9
|
}
|
|
139
|
-
const quality = Math.min(1, Math.max(0, options.compress
|
|
10
|
+
const quality = Math.min(1, Math.max(0, options.compress ?? 1));
|
|
140
11
|
base64 = canvas.toDataURL('image/' + format, quality);
|
|
141
12
|
}
|
|
142
13
|
else {
|
|
@@ -153,104 +24,42 @@ function getResults(canvas, options) {
|
|
|
153
24
|
function loadImageAsync(uri) {
|
|
154
25
|
return new Promise((resolve, reject) => {
|
|
155
26
|
const imageSource = new Image();
|
|
156
|
-
|
|
157
|
-
imageSource.
|
|
27
|
+
const canvas = document.createElement('canvas');
|
|
28
|
+
imageSource.onload = () => {
|
|
29
|
+
canvas.width = imageSource.naturalWidth;
|
|
30
|
+
canvas.height = imageSource.naturalHeight;
|
|
31
|
+
const context = getContext(canvas);
|
|
32
|
+
context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);
|
|
33
|
+
resolve(canvas);
|
|
34
|
+
};
|
|
35
|
+
imageSource.onerror = () => reject(canvas);
|
|
158
36
|
imageSource.src = uri;
|
|
159
37
|
});
|
|
160
38
|
}
|
|
161
|
-
async function manipulateWithActionAsync(uri, action, options) {
|
|
162
|
-
const canvas = document.createElement('canvas');
|
|
163
|
-
const imageSource = await loadImageAsync(uri);
|
|
164
|
-
canvas.width = imageSource.naturalWidth;
|
|
165
|
-
canvas.height = imageSource.naturalHeight;
|
|
166
|
-
if (action.crop) {
|
|
167
|
-
const { crop } = action;
|
|
168
|
-
// ensure values are defined.
|
|
169
|
-
let { originX = 0, originY = 0, width = 0, height = 0 } = crop;
|
|
170
|
-
const clamp = (value, max) => Math.max(0, Math.min(max, value));
|
|
171
|
-
// lock within bounds.
|
|
172
|
-
width = clamp(width, canvas.width);
|
|
173
|
-
height = clamp(height, canvas.height);
|
|
174
|
-
originX = clamp(originX, canvas.width);
|
|
175
|
-
originY = clamp(originY, canvas.height);
|
|
176
|
-
// lock sum of crop.
|
|
177
|
-
width = Math.min(originX + width, canvas.width) - originX;
|
|
178
|
-
height = Math.min(originY + height, canvas.height) - originY;
|
|
179
|
-
if (width === 0 || height === 0) {
|
|
180
|
-
throw new CodedError('ERR_IMAGE_MANIPULATOR_CROP', 'Crop size must be greater than 0: ' + JSON.stringify(crop, null, 2));
|
|
181
|
-
}
|
|
182
|
-
// change size of canvas.
|
|
183
|
-
canvas.width = width;
|
|
184
|
-
canvas.height = height;
|
|
185
|
-
cropImage(canvas, imageSource, originX, originY, width, height);
|
|
186
|
-
}
|
|
187
|
-
else if (action.resize) {
|
|
188
|
-
const { resize } = action;
|
|
189
|
-
const { width, height } = resize;
|
|
190
|
-
const imageRatio = imageSource.naturalWidth / imageSource.naturalHeight;
|
|
191
|
-
let requestedWidth = 0;
|
|
192
|
-
let requestedHeight = 0;
|
|
193
|
-
if (width !== undefined) {
|
|
194
|
-
requestedWidth = width;
|
|
195
|
-
requestedHeight = requestedWidth / imageRatio;
|
|
196
|
-
}
|
|
197
|
-
if (height !== undefined) {
|
|
198
|
-
requestedHeight = height;
|
|
199
|
-
if (requestedWidth === 0) {
|
|
200
|
-
requestedWidth = requestedHeight * imageRatio;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const context = getContext(canvas);
|
|
204
|
-
context.save();
|
|
205
|
-
context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);
|
|
206
|
-
resampleSingle(canvas, requestedWidth, requestedHeight, true);
|
|
207
|
-
}
|
|
208
|
-
else if (action.flip !== undefined) {
|
|
209
|
-
const { flip } = action;
|
|
210
|
-
const xFlip = flip === FlipType.Horizontal;
|
|
211
|
-
const yFlip = flip === FlipType.Vertical;
|
|
212
|
-
drawImage(canvas, imageSource, 0, 0, 0, xFlip, yFlip);
|
|
213
|
-
}
|
|
214
|
-
else if (action.rotate !== undefined) {
|
|
215
|
-
const { rotate } = action;
|
|
216
|
-
const { width, height } = sizeFromAngle(imageSource.naturalWidth, imageSource.naturalHeight, rotate);
|
|
217
|
-
canvas.width = width;
|
|
218
|
-
canvas.height = height;
|
|
219
|
-
drawImage(canvas, imageSource, 0, 0, rotate, false, false, width, height);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
const context = getContext(canvas);
|
|
223
|
-
context.save();
|
|
224
|
-
context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);
|
|
225
|
-
}
|
|
226
|
-
return getResults(canvas, options);
|
|
227
|
-
}
|
|
228
39
|
export default {
|
|
229
40
|
get name() {
|
|
230
41
|
return 'ExpoImageManipulator';
|
|
231
42
|
},
|
|
232
43
|
async manipulateAsync(uri, actions = [], options) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
canvas.height = imageSource.naturalHeight;
|
|
238
|
-
const ctx = getContext(canvas);
|
|
239
|
-
ctx.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);
|
|
240
|
-
return getResults(canvas, options);
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
let output;
|
|
244
|
-
for (let i = 0; i < actions.length; i++) {
|
|
245
|
-
const action = actions[i];
|
|
246
|
-
let _options;
|
|
247
|
-
if (i === actions.length - 1) {
|
|
248
|
-
_options = options;
|
|
249
|
-
}
|
|
250
|
-
output = await manipulateWithActionAsync(uri || output.uri, action, _options);
|
|
44
|
+
const originalCanvas = await loadImageAsync(uri);
|
|
45
|
+
const resultCanvas = actions.reduce((canvas, action) => {
|
|
46
|
+
if ('crop' in action) {
|
|
47
|
+
return crop(canvas, action.crop);
|
|
251
48
|
}
|
|
252
|
-
|
|
253
|
-
|
|
49
|
+
else if ('resize' in action) {
|
|
50
|
+
return resize(canvas, action.resize);
|
|
51
|
+
}
|
|
52
|
+
else if ('flip' in action) {
|
|
53
|
+
return flip(canvas, action.flip);
|
|
54
|
+
}
|
|
55
|
+
else if ('rotate' in action) {
|
|
56
|
+
return rotate(canvas, action.rotate);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return canvas;
|
|
60
|
+
}
|
|
61
|
+
}, originalCanvas);
|
|
62
|
+
return getResults(resultCanvas, options);
|
|
254
63
|
},
|
|
255
64
|
};
|
|
256
65
|
//# sourceMappingURL=ExpoImageManipulator.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoImageManipulator.web.js","sourceRoot":"","sources":["../src/ExpoImageManipulator.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from '@unimodules/core';\n\nimport {\n ImageResult,\n SaveOptions,\n Action,\n ActionCrop,\n ActionResize,\n ActionFlip,\n ActionRotate,\n FlipType,\n} from './ImageManipulator.types';\n\n/**\n * Hermite resize - fast image resize/resample using Hermite filter. 1 cpu version!\n * https://stackoverflow.com/a/18320662/4047926\n *\n * @param {HtmlElement} canvas\n * @param {int} width\n * @param {int} height\n * @param {boolean} resizeCanvas if true, canvas will be resized. Optional.\n */\nfunction resampleSingle(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n resizeCanvas: boolean = false\n): void {\n const widthSource = canvas.width;\n const heightSource = canvas.height;\n width = Math.round(width);\n height = Math.round(height);\n\n const wRatio = widthSource / width;\n const hRatio = heightSource / height;\n const wRatioHalf = Math.ceil(wRatio / 2);\n const hRatioHalf = Math.ceil(hRatio / 2);\n\n const ctx = getContext(canvas);\n\n const img = ctx.getImageData(0, 0, widthSource, heightSource);\n const img2 = ctx.createImageData(width, height);\n const data = img.data;\n const data2 = img2.data;\n\n for (let j = 0; j < height; j++) {\n for (let i = 0; i < width; i++) {\n const x2 = (i + j * width) * 4;\n let weight = 0;\n let weights = 0;\n let weightsAlpha = 0;\n let gx_r = 0;\n let gx_g = 0;\n let gx_b = 0;\n let gx_a = 0;\n const yCenter = (j + 0.5) * hRatio;\n const yy_start = Math.floor(j * hRatio);\n const yy_stop = Math.ceil((j + 1) * hRatio);\n for (let yy = yy_start; yy < yy_stop; yy++) {\n const dy = Math.abs(yCenter - (yy + 0.5)) / hRatioHalf;\n const center_x = (i + 0.5) * wRatio;\n const w0 = dy * dy; //pre-calc part of w\n const xx_start = Math.floor(i * wRatio);\n const xx_stop = Math.ceil((i + 1) * wRatio);\n for (let xx = xx_start; xx < xx_stop; xx++) {\n const dx = Math.abs(center_x - (xx + 0.5)) / wRatioHalf;\n const w = Math.sqrt(w0 + dx * dx);\n if (w >= 1) {\n //pixel too far\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n const xPosition = 4 * (xx + yy * widthSource);\n //alpha\n gx_a += weight * data[xPosition + 3];\n weightsAlpha += weight;\n //colors\n if (data[xPosition + 3] < 255) {\n weight = (weight * data[xPosition + 3]) / 250;\n }\n gx_r += weight * data[xPosition];\n gx_g += weight * data[xPosition + 1];\n gx_b += weight * data[xPosition + 2];\n weights += weight;\n }\n }\n data2[x2] = gx_r / weights;\n data2[x2 + 1] = gx_g / weights;\n data2[x2 + 2] = gx_b / weights;\n data2[x2 + 3] = gx_a / weightsAlpha;\n }\n }\n //clear and resize canvas\n if (resizeCanvas) {\n canvas.width = width;\n canvas.height = height;\n } else {\n ctx.clearRect(0, 0, widthSource, heightSource);\n }\n\n //draw\n ctx.putImageData(img2, 0, 0);\n}\n\nfunction sizeFromAngle(\n width: number,\n height: number,\n angle: number\n): { width: number; height: number } {\n const radians = (angle * Math.PI) / 180;\n let c = Math.cos(radians);\n let s = Math.sin(radians);\n if (s < 0) {\n s = -s;\n }\n if (c < 0) {\n c = -c;\n }\n return { width: height * s + width * c, height: height * c + width * s };\n}\n\nfunction cropImage(\n canvas: HTMLCanvasElement,\n image: HTMLImageElement,\n x: number = 0,\n y: number = 0,\n width: number = 0,\n height: number = 0\n): void {\n const context = getContext(canvas);\n context.save();\n context.drawImage(image, x, y, width, height, 0, 0, width, height);\n}\n\nfunction drawImage(\n canvas: HTMLCanvasElement,\n img: HTMLImageElement,\n x: number = 0,\n y: number = 0,\n angle: number = 0,\n xFlip: boolean = false,\n yFlip: boolean = false,\n width?: number,\n height?: number\n): CanvasRenderingContext2D {\n const context = getContext(canvas);\n context.save();\n\n if (width == null) {\n width = img.naturalWidth as number;\n }\n if (height == null) {\n height = img.naturalHeight as number;\n }\n\n // Set the origin to the center of the image\n context.translate(x + canvas.width / 2, y + canvas.height / 2);\n\n // Rotate the canvas around the origin\n const radians = 2 * Math.PI - (angle * Math.PI) / 180;\n context.rotate(radians);\n\n // Flip/flop the canvas\n const xScale = xFlip ? -1 : 1;\n const yScale = yFlip ? -1 : 1;\n\n context.scale(xScale, yScale);\n\n // Draw the image\n context.drawImage(\n img,\n -img.naturalWidth / 2,\n -img.naturalHeight / 2,\n img.naturalWidth,\n img.naturalHeight\n );\n\n context.restore();\n return context;\n}\n\nfunction getContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D {\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n throw new CodedError('ERR_IMAGE_MANIPULATOR', 'Failed to create canvas context');\n }\n return ctx;\n}\n\nfunction getResults(canvas: HTMLCanvasElement, options?: SaveOptions): ImageResult {\n let base64;\n if (options) {\n const { format = 'png' } = options;\n if (options.format === 'png' && options.compress !== undefined) {\n console.warn('compress is not supported with png format.');\n }\n const quality = Math.min(1, Math.max(0, options.compress || 1));\n base64 = canvas.toDataURL('image/' + format, quality);\n } else {\n // defaults to PNG with no loss\n base64 = canvas.toDataURL();\n }\n return {\n uri: base64,\n width: canvas.width,\n height: canvas.height,\n base64,\n };\n}\n\nfunction loadImageAsync(uri: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const imageSource = new Image();\n imageSource.onload = () => resolve(imageSource);\n imageSource.onerror = () => reject(imageSource);\n imageSource.src = uri;\n });\n}\n\nasync function manipulateWithActionAsync(\n uri: string,\n action: Action,\n options: SaveOptions\n): Promise<ImageResult> {\n const canvas = document.createElement('canvas');\n const imageSource = await loadImageAsync(uri);\n canvas.width = imageSource.naturalWidth;\n canvas.height = imageSource.naturalHeight;\n\n if ((action as ActionCrop).crop) {\n const { crop } = action as ActionCrop;\n // ensure values are defined.\n let { originX = 0, originY = 0, width = 0, height = 0 } = crop;\n const clamp = (value, max) => Math.max(0, Math.min(max, value));\n // lock within bounds.\n width = clamp(width, canvas.width);\n height = clamp(height, canvas.height);\n originX = clamp(originX, canvas.width);\n originY = clamp(originY, canvas.height);\n\n // lock sum of crop.\n width = Math.min(originX + width, canvas.width) - originX;\n height = Math.min(originY + height, canvas.height) - originY;\n\n if (width === 0 || height === 0) {\n throw new CodedError(\n 'ERR_IMAGE_MANIPULATOR_CROP',\n 'Crop size must be greater than 0: ' + JSON.stringify(crop, null, 2)\n );\n }\n\n // change size of canvas.\n canvas.width = width;\n canvas.height = height;\n\n cropImage(canvas, imageSource, originX, originY, width, height);\n } else if ((action as ActionResize).resize) {\n const { resize } = action as ActionResize;\n const { width, height } = resize;\n\n const imageRatio = imageSource.naturalWidth / imageSource.naturalHeight;\n\n let requestedWidth: number = 0;\n let requestedHeight: number = 0;\n if (width !== undefined) {\n requestedWidth = width;\n requestedHeight = requestedWidth / imageRatio;\n }\n if (height !== undefined) {\n requestedHeight = height;\n if (requestedWidth === 0) {\n requestedWidth = requestedHeight * imageRatio;\n }\n }\n\n const context = getContext(canvas);\n context.save();\n context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);\n\n resampleSingle(canvas, requestedWidth, requestedHeight, true);\n } else if ((action as ActionFlip).flip !== undefined) {\n const { flip } = action as ActionFlip;\n const xFlip = flip === FlipType.Horizontal;\n const yFlip = flip === FlipType.Vertical;\n drawImage(canvas, imageSource, 0, 0, 0, xFlip, yFlip);\n } else if ((action as ActionRotate).rotate !== undefined) {\n const { rotate } = action as ActionRotate;\n const { width, height } = sizeFromAngle(\n imageSource.naturalWidth,\n imageSource.naturalHeight,\n rotate\n );\n canvas.width = width;\n canvas.height = height;\n drawImage(canvas, imageSource, 0, 0, rotate, false, false, width, height);\n } else {\n const context = getContext(canvas);\n context.save();\n context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);\n }\n return getResults(canvas, options);\n}\n\nexport default {\n get name(): string {\n return 'ExpoImageManipulator';\n },\n async manipulateAsync(\n uri: string,\n actions: Action[] = [],\n options: SaveOptions\n ): Promise<ImageResult> {\n if (!actions.length) {\n const canvas = document.createElement('canvas');\n const imageSource = await loadImageAsync(uri);\n canvas.width = imageSource.naturalWidth;\n canvas.height = imageSource.naturalHeight;\n const ctx = getContext(canvas);\n ctx.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);\n return getResults(canvas, options);\n } else {\n let output: ImageResult;\n for (let i = 0; i < actions.length; i++) {\n const action = actions[i];\n let _options;\n if (i === actions.length - 1) {\n _options = options;\n }\n output = await manipulateWithActionAsync(uri || output!.uri, action, _options);\n }\n return output!;\n }\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ExpoImageManipulator.web.js","sourceRoot":"","sources":["../src/ExpoImageManipulator.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { ImageResult, SaveOptions, Action } from './ImageManipulator.types';\nimport { crop, flip, resize, rotate } from './actions/index.web';\nimport { getContext } from './utils/getContext.web';\n\nfunction getResults(canvas: HTMLCanvasElement, options?: SaveOptions): ImageResult {\n let base64;\n if (options) {\n const { format = 'png' } = options;\n if (options.format === 'png' && options.compress !== undefined) {\n console.warn('compress is not supported with png format.');\n }\n const quality = Math.min(1, Math.max(0, options.compress ?? 1));\n base64 = canvas.toDataURL('image/' + format, quality);\n } else {\n // defaults to PNG with no loss\n base64 = canvas.toDataURL();\n }\n return {\n uri: base64,\n width: canvas.width,\n height: canvas.height,\n base64,\n };\n}\n\nfunction loadImageAsync(uri: string): Promise<HTMLCanvasElement> {\n return new Promise((resolve, reject) => {\n const imageSource = new Image();\n const canvas = document.createElement('canvas');\n imageSource.onload = () => {\n canvas.width = imageSource.naturalWidth;\n canvas.height = imageSource.naturalHeight;\n\n const context = getContext(canvas);\n context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);\n\n resolve(canvas);\n };\n imageSource.onerror = () => reject(canvas);\n imageSource.src = uri;\n });\n}\n\nexport default {\n get name(): string {\n return 'ExpoImageManipulator';\n },\n async manipulateAsync(\n uri: string,\n actions: Action[] = [],\n options: SaveOptions\n ): Promise<ImageResult> {\n const originalCanvas = await loadImageAsync(uri);\n\n const resultCanvas = actions.reduce((canvas, action) => {\n if ('crop' in action) {\n return crop(canvas, action.crop);\n } else if ('resize' in action) {\n return resize(canvas, action.resize);\n } else if ('flip' in action) {\n return flip(canvas, action.flip);\n } else if ('rotate' in action) {\n return rotate(canvas, action.rotate);\n } else {\n return canvas;\n }\n }, originalCanvas);\n\n return getResults(resultCanvas, options);\n },\n};\n"]}
|
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
import { Action, ImageResult, SaveOptions } from './ImageManipulator.types';
|
|
2
|
+
/**
|
|
3
|
+
* Manipulate the image provided via `uri`. Available modifications are rotating, flipping (mirroring),
|
|
4
|
+
* resizing and cropping. Each invocation results in a new file. With one invocation you can provide
|
|
5
|
+
* a set of actions to perform over the image. Overwriting the source file would not have an effect
|
|
6
|
+
* in displaying the result as images are cached.
|
|
7
|
+
* @param uri URI of the file to manipulate. Should be on the local file system or a base64 data URI.
|
|
8
|
+
* @param actions An array of objects representing manipulation options. Each object should have
|
|
9
|
+
* __only one__ of the keys that corresponds to specific transformation.
|
|
10
|
+
* @param saveOptions A map defining how modified image should be saved.
|
|
11
|
+
* @return Promise which fulfils with [`ImageResult`](#imageresult) object.
|
|
12
|
+
*/
|
|
2
13
|
export declare function manipulateAsync(uri: string, actions?: Action[], saveOptions?: SaveOptions): Promise<ImageResult>;
|
|
3
14
|
export * from './ImageManipulator.types';
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import { UnavailabilityError } from '
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
import ExpoImageManipulator from './ExpoImageManipulator';
|
|
3
3
|
import { SaveFormat } from './ImageManipulator.types';
|
|
4
4
|
import { validateArguments } from './validators';
|
|
5
|
+
// @needsAudit
|
|
6
|
+
/**
|
|
7
|
+
* Manipulate the image provided via `uri`. Available modifications are rotating, flipping (mirroring),
|
|
8
|
+
* resizing and cropping. Each invocation results in a new file. With one invocation you can provide
|
|
9
|
+
* a set of actions to perform over the image. Overwriting the source file would not have an effect
|
|
10
|
+
* in displaying the result as images are cached.
|
|
11
|
+
* @param uri URI of the file to manipulate. Should be on the local file system or a base64 data URI.
|
|
12
|
+
* @param actions An array of objects representing manipulation options. Each object should have
|
|
13
|
+
* __only one__ of the keys that corresponds to specific transformation.
|
|
14
|
+
* @param saveOptions A map defining how modified image should be saved.
|
|
15
|
+
* @return Promise which fulfils with [`ImageResult`](#imageresult) object.
|
|
16
|
+
*/
|
|
5
17
|
export async function manipulateAsync(uri, actions = [], saveOptions = {}) {
|
|
6
18
|
if (!ExpoImageManipulator.manipulateAsync) {
|
|
7
19
|
throw new UnavailabilityError('ImageManipulator', 'manipulateAsync');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManipulator.js","sourceRoot":"","sources":["../src/ImageManipulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ImageManipulator.js","sourceRoot":"","sources":["../src/ImageManipulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAuB,UAAU,EAAe,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,cAAc;AACd;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,UAAoB,EAAE,EACtB,cAA2B,EAAE;IAE7B,IAAI,CAAC,oBAAoB,CAAC,eAAe,EAAE;QACzC,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;KACtE;IAED,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAE7C,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,WAAW,CAAC;IAC1D,OAAO,MAAM,oBAAoB,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,cAAc,0BAA0B,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoImageManipulator from './ExpoImageManipulator';\nimport { Action, ImageResult, SaveFormat, SaveOptions } from './ImageManipulator.types';\nimport { validateArguments } from './validators';\n\n// @needsAudit\n/**\n * Manipulate the image provided via `uri`. Available modifications are rotating, flipping (mirroring),\n * resizing and cropping. Each invocation results in a new file. With one invocation you can provide\n * a set of actions to perform over the image. Overwriting the source file would not have an effect\n * in displaying the result as images are cached.\n * @param uri URI of the file to manipulate. Should be on the local file system or a base64 data URI.\n * @param actions An array of objects representing manipulation options. Each object should have\n * __only one__ of the keys that corresponds to specific transformation.\n * @param saveOptions A map defining how modified image should be saved.\n * @return Promise which fulfils with [`ImageResult`](#imageresult) object.\n */\nexport async function manipulateAsync(\n uri: string,\n actions: Action[] = [],\n saveOptions: SaveOptions = {}\n): Promise<ImageResult> {\n if (!ExpoImageManipulator.manipulateAsync) {\n throw new UnavailabilityError('ImageManipulator', 'manipulateAsync');\n }\n\n validateArguments(uri, actions, saveOptions);\n\n const { format = SaveFormat.JPEG, ...rest } = saveOptions;\n return await ExpoImageManipulator.manipulateAsync(uri, actions, { format, ...rest });\n}\n\nexport * from './ImageManipulator.types';\n"]}
|