react-native-capture-studio 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/generated/java/com/capturestudio/NativeCaptureStudioSpec.java +4 -0
- package/android/generated/jni/CMakeLists.txt +1 -4
- package/android/generated/jni/RNCaptureStudioSpec-generated.cpp +6 -0
- package/android/generated/jni/react/renderer/components/RNCaptureStudioSpec/RNCaptureStudioSpecJSI.h +9 -0
- package/android/src/main/java/com/capturestudio/CaptureStudioModule.kt +34 -0
- package/android/src/main/java/com/capturestudio/data/processing/ImageProcessor.kt +109 -9
- package/ios/CaptureStudio.mm +35 -0
- package/ios/ImageProcessor.h +3 -0
- package/ios/ImageProcessor.mm +60 -0
- package/ios/generated/Package.swift +1 -1
- package/ios/generated/ReactCodegen/RNCaptureStudioSpec/RNCaptureStudioSpec-generated.mm +7 -0
- package/ios/generated/ReactCodegen/RNCaptureStudioSpec/RNCaptureStudioSpec.h +3 -0
- package/ios/generated/ReactCodegen/RNCaptureStudioSpecJSI.h +9 -0
- package/lib/commonjs/NativeCaptureStudio.js.map +1 -1
- package/lib/commonjs/index.js +4 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeCaptureStudio.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeCaptureStudio.d.ts +1 -0
- package/lib/typescript/commonjs/src/NativeCaptureStudio.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +5 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeCaptureStudio.d.ts +1 -0
- package/lib/typescript/module/src/NativeCaptureStudio.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +5 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeCaptureStudio.ts +1 -0
- package/src/index.tsx +9 -0
|
@@ -45,4 +45,8 @@ public abstract class NativeCaptureStudioSpec extends ReactContextBaseJavaModule
|
|
|
45
45
|
@ReactMethod
|
|
46
46
|
@DoNotStrip
|
|
47
47
|
public abstract void fetchProcessingResult(String operationId, Promise promise);
|
|
48
|
+
|
|
49
|
+
@ReactMethod
|
|
50
|
+
@DoNotStrip
|
|
51
|
+
public abstract void generateThumbnail(ReadableMap item, Promise promise);
|
|
48
52
|
}
|
|
@@ -25,7 +25,4 @@ target_link_libraries(
|
|
|
25
25
|
reactnative
|
|
26
26
|
)
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
if(COMMAND target_compile_reactnative_options)
|
|
30
|
-
target_compile_reactnative_options(react_codegen_RNCaptureStudioSpec PRIVATE)
|
|
31
|
-
endif()
|
|
28
|
+
target_compile_reactnative_options(react_codegen_RNCaptureStudioSpec PRIVATE)
|
|
@@ -27,11 +27,17 @@ static facebook::jsi::Value __hostFunction_NativeCaptureStudioSpecJSI_fetchProce
|
|
|
27
27
|
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "fetchProcessingResult", "(Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
static facebook::jsi::Value __hostFunction_NativeCaptureStudioSpecJSI_generateThumbnail(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
31
|
+
static jmethodID cachedMethodId = nullptr;
|
|
32
|
+
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "generateThumbnail", "(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
NativeCaptureStudioSpecJSI::NativeCaptureStudioSpecJSI(const JavaTurboModule::InitParams ¶ms)
|
|
31
36
|
: JavaTurboModule(params) {
|
|
32
37
|
methodMap_["openCaptureStudio"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_openCaptureStudio};
|
|
33
38
|
methodMap_["processImages"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_processImages};
|
|
34
39
|
methodMap_["fetchProcessingResult"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_fetchProcessingResult};
|
|
40
|
+
methodMap_["generateThumbnail"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_generateThumbnail};
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
std::shared_ptr<TurboModule> RNCaptureStudioSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) {
|
package/android/generated/jni/react/renderer/components/RNCaptureStudioSpec/RNCaptureStudioSpecJSI.h
CHANGED
|
@@ -25,6 +25,7 @@ protected:
|
|
|
25
25
|
methodMap_["openCaptureStudio"] = MethodMetadata {.argCount = 1, .invoker = __openCaptureStudio};
|
|
26
26
|
methodMap_["processImages"] = MethodMetadata {.argCount = 1, .invoker = __processImages};
|
|
27
27
|
methodMap_["fetchProcessingResult"] = MethodMetadata {.argCount = 1, .invoker = __fetchProcessingResult};
|
|
28
|
+
methodMap_["generateThumbnail"] = MethodMetadata {.argCount = 1, .invoker = __generateThumbnail};
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
private:
|
|
@@ -51,6 +52,14 @@ private:
|
|
|
51
52
|
return bridging::callFromJs<jsi::Value>(rt, &T::fetchProcessingResult, static_cast<NativeCaptureStudioCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule),
|
|
52
53
|
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt));
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
static jsi::Value __generateThumbnail(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
|
57
|
+
static_assert(
|
|
58
|
+
bridging::getParameterCount(&T::generateThumbnail) == 2,
|
|
59
|
+
"Expected generateThumbnail(...) to have 2 parameters");
|
|
60
|
+
return bridging::callFromJs<jsi::Value>(rt, &T::generateThumbnail, static_cast<NativeCaptureStudioCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule),
|
|
61
|
+
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt));
|
|
62
|
+
}
|
|
54
63
|
};
|
|
55
64
|
|
|
56
65
|
} // namespace facebook::react
|
|
@@ -6,6 +6,7 @@ import androidx.work.Data
|
|
|
6
6
|
import androidx.work.OneTimeWorkRequestBuilder
|
|
7
7
|
import androidx.work.WorkInfo
|
|
8
8
|
import androidx.work.WorkManager
|
|
9
|
+
import com.capturestudio.data.processing.ImageProcessor
|
|
9
10
|
import com.capturestudio.data.processing.ImageProcessingWorker
|
|
10
11
|
import com.capturestudio.ui.camera.CameraActivity
|
|
11
12
|
import com.facebook.react.bridge.Promise
|
|
@@ -151,6 +152,39 @@ class CaptureStudioModule(reactContext: ReactApplicationContext) :
|
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Generate a thumbnail for a single image.
|
|
157
|
+
* Runs on a background thread.
|
|
158
|
+
*
|
|
159
|
+
* @param item Map with localPath (string) and maxSize (int)
|
|
160
|
+
* @param promise Resolves with thumbnail file path
|
|
161
|
+
*/
|
|
162
|
+
override fun generateThumbnail(item: ReadableMap, promise: Promise) {
|
|
163
|
+
val localPath = item.getString("localPath") ?: ""
|
|
164
|
+
val maxSize = if (item.hasKey("maxSize")) item.getInt("maxSize") else 100
|
|
165
|
+
|
|
166
|
+
if (localPath.isEmpty()) {
|
|
167
|
+
promise.reject("INVALID_INPUT", "localPath is required")
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
val cleanPath = localPath.replace("file://", "")
|
|
172
|
+
|
|
173
|
+
Thread {
|
|
174
|
+
try {
|
|
175
|
+
val result = ImageProcessor.generateThumbnail(cleanPath, maxSize)
|
|
176
|
+
if (result.isSuccess) {
|
|
177
|
+
promise.resolve(result.getOrNull())
|
|
178
|
+
} else {
|
|
179
|
+
promise.reject("THUMBNAIL_FAILED", result.exceptionOrNull()?.message ?: "Unknown error")
|
|
180
|
+
}
|
|
181
|
+
} catch (e: Exception) {
|
|
182
|
+
Log.e(TAG, "Thumbnail generation failed", e)
|
|
183
|
+
promise.reject("THUMBNAIL_FAILED", e.message, e)
|
|
184
|
+
}
|
|
185
|
+
}.start()
|
|
186
|
+
}
|
|
187
|
+
|
|
154
188
|
/**
|
|
155
189
|
* Convert a ReadableArray to a JSON string.
|
|
156
190
|
*/
|
|
@@ -87,6 +87,17 @@ object ImageProcessor {
|
|
|
87
87
|
useJpeg = compressJpeg
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
+
// 5. Reset EXIF orientation since pixels are already rotated
|
|
91
|
+
if (orientation != ExifInterface.ORIENTATION_NORMAL &&
|
|
92
|
+
orientation != ExifInterface.ORIENTATION_UNDEFINED) {
|
|
93
|
+
val newExif = ExifInterface(imagePath)
|
|
94
|
+
newExif.setAttribute(
|
|
95
|
+
ExifInterface.TAG_ORIENTATION,
|
|
96
|
+
ExifInterface.ORIENTATION_NORMAL.toString()
|
|
97
|
+
)
|
|
98
|
+
newExif.saveAttributes()
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
watermarkedBitmap.recycle()
|
|
91
102
|
|
|
92
103
|
Log.d(TAG, "Successfully processed: $imagePath")
|
|
@@ -94,18 +105,107 @@ object ImageProcessor {
|
|
|
94
105
|
}
|
|
95
106
|
|
|
96
107
|
/**
|
|
97
|
-
*
|
|
108
|
+
* Generate a small thumbnail from an image file.
|
|
109
|
+
* Uses BitmapFactory.Options.inSampleSize for memory-efficient downsampling.
|
|
110
|
+
* Does NOT load the full bitmap into memory.
|
|
111
|
+
*
|
|
112
|
+
* @param imagePath Path to the source image
|
|
113
|
+
* @param maxSize Max pixel dimension for the thumbnail (e.g. 200)
|
|
114
|
+
* @return Result with thumbnail path on success
|
|
98
115
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
116
|
+
fun generateThumbnail(imagePath: String, maxSize: Int): Result<String> {
|
|
117
|
+
return runCatching {
|
|
118
|
+
val file = File(imagePath)
|
|
119
|
+
if (!file.exists()) {
|
|
120
|
+
throw IllegalArgumentException("File not found: $imagePath")
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Step 1: Decode only bounds (no memory allocation for pixels)
|
|
124
|
+
val options = BitmapFactory.Options().apply {
|
|
125
|
+
inJustDecodeBounds = true
|
|
126
|
+
}
|
|
127
|
+
BitmapFactory.decodeFile(imagePath, options)
|
|
128
|
+
|
|
129
|
+
val imageWidth = options.outWidth
|
|
130
|
+
val imageHeight = options.outHeight
|
|
131
|
+
|
|
132
|
+
// Step 2: Calculate inSampleSize for memory-efficient downsampling
|
|
133
|
+
var inSampleSize = 1
|
|
134
|
+
if (imageWidth > maxSize || imageHeight > maxSize) {
|
|
135
|
+
val halfWidth = imageWidth / 2
|
|
136
|
+
val halfHeight = imageHeight / 2
|
|
137
|
+
while ((halfWidth / inSampleSize) >= maxSize && (halfHeight / inSampleSize) >= maxSize) {
|
|
138
|
+
inSampleSize *= 2
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Step 3: Decode with inSampleSize (loads only ~thumbnail-sized bitmap)
|
|
143
|
+
val decodeOptions = BitmapFactory.Options().apply {
|
|
144
|
+
this.inSampleSize = inSampleSize
|
|
145
|
+
}
|
|
146
|
+
val sampledBitmap = BitmapFactory.decodeFile(imagePath, decodeOptions)
|
|
147
|
+
?: throw IllegalStateException("Failed to decode image: $imagePath")
|
|
148
|
+
|
|
149
|
+
// Step 4: Scale to exact max size
|
|
150
|
+
val scale = maxSize.toFloat() / maxOf(sampledBitmap.width, sampledBitmap.height)
|
|
151
|
+
val targetWidth = (sampledBitmap.width * scale).toInt()
|
|
152
|
+
val targetHeight = (sampledBitmap.height * scale).toInt()
|
|
153
|
+
val thumbnail = Bitmap.createScaledBitmap(sampledBitmap, targetWidth, targetHeight, true)
|
|
154
|
+
|
|
155
|
+
if (thumbnail !== sampledBitmap) {
|
|
156
|
+
sampledBitmap.recycle()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Step 5: Handle EXIF rotation
|
|
160
|
+
val exif = ExifInterface(imagePath)
|
|
161
|
+
val orientation = exif.getAttributeInt(
|
|
162
|
+
ExifInterface.TAG_ORIENTATION,
|
|
163
|
+
ExifInterface.ORIENTATION_NORMAL
|
|
164
|
+
)
|
|
165
|
+
val rotatedThumbnail = rotateBitmapIfNeeded(thumbnail, orientation)
|
|
166
|
+
if (rotatedThumbnail !== thumbnail) {
|
|
167
|
+
thumbnail.recycle()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Step 6: Save as JPEG
|
|
171
|
+
val nameWithoutExt = imagePath.substringBeforeLast(".")
|
|
172
|
+
val thumbPath = "${nameWithoutExt}_thumb.jpg"
|
|
173
|
+
|
|
174
|
+
FileOutputStream(thumbPath).use { fos ->
|
|
175
|
+
rotatedThumbnail.compress(Bitmap.CompressFormat.JPEG, 60, fos)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
rotatedThumbnail.recycle()
|
|
179
|
+
|
|
180
|
+
Log.d(TAG, "Generated thumbnail: $thumbPath")
|
|
181
|
+
thumbPath
|
|
105
182
|
}
|
|
183
|
+
}
|
|
106
184
|
|
|
107
|
-
|
|
108
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Rotate and/or flip bitmap based on EXIF orientation.
|
|
187
|
+
* Handles all 8 EXIF orientation cases including mirrored variants
|
|
188
|
+
* produced by front-facing (selfie) cameras.
|
|
189
|
+
*/
|
|
190
|
+
private fun rotateBitmapIfNeeded(bitmap: Bitmap, orientation: Int): Bitmap {
|
|
191
|
+
val matrix = Matrix()
|
|
192
|
+
|
|
193
|
+
when (orientation) {
|
|
194
|
+
ExifInterface.ORIENTATION_NORMAL -> return bitmap
|
|
195
|
+
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.postScale(-1f, 1f)
|
|
196
|
+
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
|
|
197
|
+
ExifInterface.ORIENTATION_FLIP_VERTICAL -> matrix.postScale(1f, -1f)
|
|
198
|
+
ExifInterface.ORIENTATION_TRANSPOSE -> {
|
|
199
|
+
matrix.postRotate(90f)
|
|
200
|
+
matrix.postScale(-1f, 1f)
|
|
201
|
+
}
|
|
202
|
+
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
|
|
203
|
+
ExifInterface.ORIENTATION_TRANSVERSE -> {
|
|
204
|
+
matrix.postRotate(-90f)
|
|
205
|
+
matrix.postScale(-1f, 1f)
|
|
206
|
+
}
|
|
207
|
+
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
|
|
208
|
+
else -> return bitmap
|
|
109
209
|
}
|
|
110
210
|
|
|
111
211
|
return Bitmap.createBitmap(
|
package/ios/CaptureStudio.mm
CHANGED
|
@@ -175,6 +175,41 @@ RCT_EXPORT_MODULE()
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
#pragma mark - generateThumbnail
|
|
179
|
+
|
|
180
|
+
- (void)generateThumbnail:(NSDictionary *)item
|
|
181
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
182
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
183
|
+
{
|
|
184
|
+
NSString *localPath = item[@"localPath"];
|
|
185
|
+
NSNumber *maxSizeNum = item[@"maxSize"];
|
|
186
|
+
|
|
187
|
+
if (!localPath || localPath.length == 0) {
|
|
188
|
+
reject(@"INVALID_INPUT", @"localPath is required", nil);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
NSInteger maxSize = maxSizeNum ? [maxSizeNum integerValue] : 100;
|
|
193
|
+
|
|
194
|
+
// Remove file:// prefix if present
|
|
195
|
+
NSString *cleanPath = [localPath stringByReplacingOccurrencesOfString:@"file://"
|
|
196
|
+
withString:@""];
|
|
197
|
+
|
|
198
|
+
// Run on background queue to avoid blocking JS thread
|
|
199
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
200
|
+
BOOL success = [ImageProcessor generateThumbnailAtPath:cleanPath maxSize:maxSize];
|
|
201
|
+
|
|
202
|
+
if (success) {
|
|
203
|
+
// Return the thumbnail path
|
|
204
|
+
NSString *nameWithoutExt = [cleanPath stringByDeletingPathExtension];
|
|
205
|
+
NSString *thumbPath = [NSString stringWithFormat:@"%@_thumb.jpg", nameWithoutExt];
|
|
206
|
+
resolve(thumbPath);
|
|
207
|
+
} else {
|
|
208
|
+
reject(@"THUMBNAIL_FAILED", @"Failed to generate thumbnail", nil);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
178
213
|
#pragma mark - TurboModule
|
|
179
214
|
|
|
180
215
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
package/ios/ImageProcessor.h
CHANGED
package/ios/ImageProcessor.mm
CHANGED
|
@@ -380,4 +380,64 @@
|
|
|
380
380
|
return success;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
#pragma mark - Thumbnail Generation
|
|
384
|
+
|
|
385
|
+
+ (BOOL)generateThumbnailAtPath:(NSString *)path
|
|
386
|
+
maxSize:(NSInteger)maxSize
|
|
387
|
+
{
|
|
388
|
+
@autoreleasepool {
|
|
389
|
+
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
|
390
|
+
CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)fileURL, NULL);
|
|
391
|
+
|
|
392
|
+
if (!source) {
|
|
393
|
+
return NO;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Request a thumbnail at max dimension, downsampling during decode
|
|
397
|
+
// This is MEMORY EFFICIENT — does NOT load the full image into memory
|
|
398
|
+
NSDictionary *options = @{
|
|
399
|
+
(NSString *)kCGImageSourceThumbnailMaxPixelSize: @(maxSize),
|
|
400
|
+
(NSString *)kCGImageSourceCreateThumbnailFromImageAlways: @YES,
|
|
401
|
+
(NSString *)kCGImageSourceCreateThumbnailWithTransform: @YES,
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef)options);
|
|
405
|
+
CFRelease(source);
|
|
406
|
+
|
|
407
|
+
if (!thumbnail) {
|
|
408
|
+
return NO;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Build thumbnail output path: /path/to/IMG_123.jpg -> /path/to/IMG_123_thumb.jpg
|
|
412
|
+
NSString *nameWithoutExt = [path stringByDeletingPathExtension];
|
|
413
|
+
NSString *thumbPath = [NSString stringWithFormat:@"%@_thumb.jpg", nameWithoutExt];
|
|
414
|
+
|
|
415
|
+
// Write as JPEG with quality 60%
|
|
416
|
+
NSURL *thumbURL = [NSURL fileURLWithPath:thumbPath];
|
|
417
|
+
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(
|
|
418
|
+
(__bridge CFURLRef)thumbURL,
|
|
419
|
+
(__bridge CFStringRef)UTTypeJPEG.identifier,
|
|
420
|
+
1,
|
|
421
|
+
NULL
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
if (!destination) {
|
|
425
|
+
CGImageRelease(thumbnail);
|
|
426
|
+
return NO;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
NSDictionary *destOptions = @{
|
|
430
|
+
(__bridge NSString *)kCGImageDestinationLossyCompressionQuality: @(0.6)
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
CGImageDestinationAddImage(destination, thumbnail, (__bridge CFDictionaryRef)destOptions);
|
|
434
|
+
BOOL success = CGImageDestinationFinalize(destination);
|
|
435
|
+
|
|
436
|
+
CFRelease(destination);
|
|
437
|
+
CGImageRelease(thumbnail);
|
|
438
|
+
|
|
439
|
+
return success;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
383
443
|
@end
|
|
@@ -16,7 +16,7 @@ let package = Package(
|
|
|
16
16
|
targets: ["ReactAppDependencyProvider"]),
|
|
17
17
|
],
|
|
18
18
|
dependencies: [
|
|
19
|
-
.package(name: "React", path: "
|
|
19
|
+
.package(name: "React", path: "../../../../../../node_modules/react-native")
|
|
20
20
|
],
|
|
21
21
|
targets: [
|
|
22
22
|
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
|
@@ -38,6 +38,10 @@ namespace facebook::react {
|
|
|
38
38
|
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "fetchProcessingResult", @selector(fetchProcessingResult:resolve:reject:), args, count);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
static facebook::jsi::Value __hostFunction_NativeCaptureStudioSpecJSI_generateThumbnail(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
42
|
+
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "generateThumbnail", @selector(generateThumbnail:resolve:reject:), args, count);
|
|
43
|
+
}
|
|
44
|
+
|
|
41
45
|
NativeCaptureStudioSpecJSI::NativeCaptureStudioSpecJSI(const ObjCTurboModule::InitParams ¶ms)
|
|
42
46
|
: ObjCTurboModule(params) {
|
|
43
47
|
|
|
@@ -49,5 +53,8 @@ namespace facebook::react {
|
|
|
49
53
|
|
|
50
54
|
methodMap_["fetchProcessingResult"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_fetchProcessingResult};
|
|
51
55
|
|
|
56
|
+
|
|
57
|
+
methodMap_["generateThumbnail"] = MethodMetadata {1, __hostFunction_NativeCaptureStudioSpecJSI_generateThumbnail};
|
|
58
|
+
|
|
52
59
|
}
|
|
53
60
|
} // namespace facebook::react
|
|
@@ -44,6 +44,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
44
44
|
- (void)fetchProcessingResult:(NSString *)operationId
|
|
45
45
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
46
46
|
reject:(RCTPromiseRejectBlock)reject;
|
|
47
|
+
- (void)generateThumbnail:(NSDictionary *)item
|
|
48
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
47
50
|
|
|
48
51
|
@end
|
|
49
52
|
|
|
@@ -25,6 +25,7 @@ protected:
|
|
|
25
25
|
methodMap_["openCaptureStudio"] = MethodMetadata {.argCount = 1, .invoker = __openCaptureStudio};
|
|
26
26
|
methodMap_["processImages"] = MethodMetadata {.argCount = 1, .invoker = __processImages};
|
|
27
27
|
methodMap_["fetchProcessingResult"] = MethodMetadata {.argCount = 1, .invoker = __fetchProcessingResult};
|
|
28
|
+
methodMap_["generateThumbnail"] = MethodMetadata {.argCount = 1, .invoker = __generateThumbnail};
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
private:
|
|
@@ -51,6 +52,14 @@ private:
|
|
|
51
52
|
return bridging::callFromJs<jsi::Value>(rt, &T::fetchProcessingResult, static_cast<NativeCaptureStudioCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule),
|
|
52
53
|
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt));
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
static jsi::Value __generateThumbnail(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
|
57
|
+
static_assert(
|
|
58
|
+
bridging::getParameterCount(&T::generateThumbnail) == 2,
|
|
59
|
+
"Expected generateThumbnail(...) to have 2 parameters");
|
|
60
|
+
return bridging::callFromJs<jsi::Value>(rt, &T::generateThumbnail, static_cast<NativeCaptureStudioCxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule),
|
|
61
|
+
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt));
|
|
62
|
+
}
|
|
54
63
|
};
|
|
55
64
|
|
|
56
65
|
} // namespace facebook::react
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeCaptureStudio.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeCaptureStudio.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAUpCC,gCAAmB,CAACC,YAAY,CAAO,eAAe,CAAC","ignoreList":[]}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.fetchProcessingResult = fetchProcessingResult;
|
|
7
|
+
exports.generateThumbnail = generateThumbnail;
|
|
7
8
|
exports.openCaptureStudio = openCaptureStudio;
|
|
8
9
|
exports.processImages = processImages;
|
|
9
10
|
var _NativeCaptureStudio = _interopRequireDefault(require("./NativeCaptureStudio.js"));
|
|
@@ -17,4 +18,7 @@ function processImages(images) {
|
|
|
17
18
|
function fetchProcessingResult(operationId) {
|
|
18
19
|
return _NativeCaptureStudio.default.fetchProcessingResult(operationId);
|
|
19
20
|
}
|
|
21
|
+
function generateThumbnail(item) {
|
|
22
|
+
return _NativeCaptureStudio.default.generateThumbnail(item);
|
|
23
|
+
}
|
|
20
24
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_NativeCaptureStudio","_interopRequireDefault","require","e","__esModule","default","openCaptureStudio","options","CaptureStudio","processImages","images","fetchProcessingResult","operationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_NativeCaptureStudio","_interopRequireDefault","require","e","__esModule","default","openCaptureStudio","options","CaptureStudio","processImages","images","fetchProcessingResult","operationId","generateThumbnail","item"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;AAAA,IAAAA,oBAAA,GAAAC,sBAAA,CAAAC,OAAA;AAAkD,SAAAD,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAwB3C,SAASG,iBAAiBA,CAACC,OAAuB,GAAG,CAAC,CAAC,EAAgB;EAC5E,OAAOC,4BAAa,CAACF,iBAAiB,CAACC,OAAO,CAAC;AACjD;AAEO,SAASE,aAAaA,CAACC,MAA6B,EAAmB;EAC5E,OAAOF,4BAAa,CAACC,aAAa,CAACC,MAAM,CAAC;AAC5C;AAEO,SAASC,qBAAqBA,CAACC,WAAmB,EAAmB;EAC1E,OAAOJ,4BAAa,CAACG,qBAAqB,CAACC,WAAW,CAAC;AACzD;AAEO,SAASC,iBAAiBA,CAACC,IAAmB,EAAmB;EACtE,OAAON,4BAAa,CAACK,iBAAiB,CAACC,IAAI,CAAC;AAC9C","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeCaptureStudio.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeCaptureStudio.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAUlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,eAAe,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -10,4 +10,7 @@ export function processImages(images) {
|
|
|
10
10
|
export function fetchProcessingResult(operationId) {
|
|
11
11
|
return CaptureStudio.fetchProcessingResult(operationId);
|
|
12
12
|
}
|
|
13
|
+
export function generateThumbnail(item) {
|
|
14
|
+
return CaptureStudio.generateThumbnail(item);
|
|
15
|
+
}
|
|
13
16
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["CaptureStudio","openCaptureStudio","options","processImages","images","fetchProcessingResult","operationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,aAAa,MAAM,0BAAuB;
|
|
1
|
+
{"version":3,"names":["CaptureStudio","openCaptureStudio","options","processImages","images","fetchProcessingResult","operationId","generateThumbnail","item"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,aAAa,MAAM,0BAAuB;AAwBjD,OAAO,SAASC,iBAAiBA,CAACC,OAAuB,GAAG,CAAC,CAAC,EAAgB;EAC5E,OAAOF,aAAa,CAACC,iBAAiB,CAACC,OAAO,CAAC;AACjD;AAEA,OAAO,SAASC,aAAaA,CAACC,MAA6B,EAAmB;EAC5E,OAAOJ,aAAa,CAACG,aAAa,CAACC,MAAM,CAAC;AAC5C;AAEA,OAAO,SAASC,qBAAqBA,CAACC,WAAmB,EAAmB;EAC1E,OAAON,aAAa,CAACK,qBAAqB,CAACC,WAAW,CAAC;AACzD;AAEA,OAAO,SAASC,iBAAiBA,CAACC,IAAmB,EAAmB;EACtE,OAAOR,aAAa,CAACO,iBAAiB,CAACC,IAAI,CAAC;AAC9C","ignoreList":[]}
|
|
@@ -3,6 +3,7 @@ export interface Spec extends TurboModule {
|
|
|
3
3
|
openCaptureStudio(options: Object): Promise<Object>;
|
|
4
4
|
processImages(images: Object[]): Promise<string>;
|
|
5
5
|
fetchProcessingResult(operationId: string): Promise<string>;
|
|
6
|
+
generateThumbnail(item: Object): Promise<string>;
|
|
6
7
|
}
|
|
7
8
|
declare const _default: Spec;
|
|
8
9
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeCaptureStudio.d.ts","sourceRoot":"","sources":["../../../../src/NativeCaptureStudio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeCaptureStudio.d.ts","sourceRoot":"","sources":["../../../../src/NativeCaptureStudio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;;AAED,wBAAuE"}
|
|
@@ -13,7 +13,12 @@ export type ImageProcessingItem = {
|
|
|
13
13
|
compressJpegImage?: boolean;
|
|
14
14
|
replaceOriginal?: boolean;
|
|
15
15
|
};
|
|
16
|
+
export type ThumbnailItem = {
|
|
17
|
+
localPath: string;
|
|
18
|
+
maxSize?: number;
|
|
19
|
+
};
|
|
16
20
|
export declare function openCaptureStudio(options?: CaptureOptions): Promise<any>;
|
|
17
21
|
export declare function processImages(images: ImageProcessingItem[]): Promise<string>;
|
|
18
22
|
export declare function fetchProcessingResult(operationId: string): Promise<string>;
|
|
23
|
+
export declare function generateThumbnail(item: ThumbnailItem): Promise<string>;
|
|
19
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1E"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE"}
|
|
@@ -3,6 +3,7 @@ export interface Spec extends TurboModule {
|
|
|
3
3
|
openCaptureStudio(options: Object): Promise<Object>;
|
|
4
4
|
processImages(images: Object[]): Promise<string>;
|
|
5
5
|
fetchProcessingResult(operationId: string): Promise<string>;
|
|
6
|
+
generateThumbnail(item: Object): Promise<string>;
|
|
6
7
|
}
|
|
7
8
|
declare const _default: Spec;
|
|
8
9
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeCaptureStudio.d.ts","sourceRoot":"","sources":["../../../../src/NativeCaptureStudio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeCaptureStudio.d.ts","sourceRoot":"","sources":["../../../../src/NativeCaptureStudio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;;AAED,wBAAuE"}
|
|
@@ -13,7 +13,12 @@ export type ImageProcessingItem = {
|
|
|
13
13
|
compressJpegImage?: boolean;
|
|
14
14
|
replaceOriginal?: boolean;
|
|
15
15
|
};
|
|
16
|
+
export type ThumbnailItem = {
|
|
17
|
+
localPath: string;
|
|
18
|
+
maxSize?: number;
|
|
19
|
+
};
|
|
16
20
|
export declare function openCaptureStudio(options?: CaptureOptions): Promise<any>;
|
|
17
21
|
export declare function processImages(images: ImageProcessingItem[]): Promise<string>;
|
|
18
22
|
export declare function fetchProcessingResult(operationId: string): Promise<string>;
|
|
23
|
+
export declare function generateThumbnail(item: ThumbnailItem): Promise<string>;
|
|
19
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1E"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE"}
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ export interface Spec extends TurboModule {
|
|
|
6
6
|
// Image processing methods
|
|
7
7
|
processImages(images: Object[]): Promise<string>;
|
|
8
8
|
fetchProcessingResult(operationId: string): Promise<string>;
|
|
9
|
+
generateThumbnail(item: Object): Promise<string>;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export default TurboModuleRegistry.getEnforcing<Spec>('CaptureStudio');
|
package/src/index.tsx
CHANGED
|
@@ -17,6 +17,11 @@ export type ImageProcessingItem = {
|
|
|
17
17
|
replaceOriginal?: boolean; // true = override original, false = create new file (default: true)
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export type ThumbnailItem = {
|
|
21
|
+
localPath: string;
|
|
22
|
+
maxSize?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
20
25
|
export function openCaptureStudio(options: CaptureOptions = {}): Promise<any> {
|
|
21
26
|
return CaptureStudio.openCaptureStudio(options);
|
|
22
27
|
}
|
|
@@ -28,3 +33,7 @@ export function processImages(images: ImageProcessingItem[]): Promise<string> {
|
|
|
28
33
|
export function fetchProcessingResult(operationId: string): Promise<string> {
|
|
29
34
|
return CaptureStudio.fetchProcessingResult(operationId);
|
|
30
35
|
}
|
|
36
|
+
|
|
37
|
+
export function generateThumbnail(item: ThumbnailItem): Promise<string> {
|
|
38
|
+
return CaptureStudio.generateThumbnail(item);
|
|
39
|
+
}
|