capacitor-camera-multicapture 0.12.2

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.
Files changed (76) hide show
  1. package/CameraMultiCapture.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/Package.swift +28 -0
  4. package/README.md +551 -0
  5. package/android/build.gradle +69 -0
  6. package/android/src/main/AndroidManifest.xml +6 -0
  7. package/android/src/main/java/dev/hemang/cameramulticapture/CameraConfig.java +45 -0
  8. package/android/src/main/java/dev/hemang/cameramulticapture/CameraConfigMapper.java +98 -0
  9. package/android/src/main/java/dev/hemang/cameramulticapture/CameraMultiCapture.java +10 -0
  10. package/android/src/main/java/dev/hemang/cameramulticapture/CameraMultiCapturePlugin.java +1340 -0
  11. package/android/src/main/java/dev/hemang/cameramulticapture/ExifWrapper.java +108 -0
  12. package/android/src/main/java/dev/hemang/cameramulticapture/GenericUploadWorker.java +173 -0
  13. package/android/src/main/java/dev/hemang/cameramulticapture/ImageUtils.java +215 -0
  14. package/android/src/main/java/dev/hemang/cameramulticapture/PluginVersion.java +6 -0
  15. package/android/src/main/java/dev/hemang/cameramulticapture/ThumbnailGenerator.java +48 -0
  16. package/android/src/main/res/.gitkeep +0 -0
  17. package/dist/esm/controllers/camera-controller.d.ts +127 -0
  18. package/dist/esm/controllers/camera-controller.js +388 -0
  19. package/dist/esm/controllers/camera-controller.js.map +1 -0
  20. package/dist/esm/controllers/gallery-controller.d.ts +66 -0
  21. package/dist/esm/controllers/gallery-controller.js +333 -0
  22. package/dist/esm/controllers/gallery-controller.js.map +1 -0
  23. package/dist/esm/definitions.d.ts +372 -0
  24. package/dist/esm/definitions.js +6 -0
  25. package/dist/esm/definitions.js.map +1 -0
  26. package/dist/esm/index.d.ts +5 -0
  27. package/dist/esm/index.js +6 -0
  28. package/dist/esm/index.js.map +1 -0
  29. package/dist/esm/overlay-manager.d.ts +124 -0
  30. package/dist/esm/overlay-manager.js +732 -0
  31. package/dist/esm/overlay-manager.js.map +1 -0
  32. package/dist/esm/overlay.d.ts +2 -0
  33. package/dist/esm/overlay.js +39 -0
  34. package/dist/esm/overlay.js.map +1 -0
  35. package/dist/esm/registration.d.ts +5 -0
  36. package/dist/esm/registration.js +8 -0
  37. package/dist/esm/registration.js.map +1 -0
  38. package/dist/esm/types/ui-types.d.ts +78 -0
  39. package/dist/esm/types/ui-types.js +2 -0
  40. package/dist/esm/types/ui-types.js.map +1 -0
  41. package/dist/esm/ui/capture-gesture-handler.d.ts +15 -0
  42. package/dist/esm/ui/capture-gesture-handler.js +87 -0
  43. package/dist/esm/ui/capture-gesture-handler.js.map +1 -0
  44. package/dist/esm/ui/default-styles.d.ts +27 -0
  45. package/dist/esm/ui/default-styles.js +134 -0
  46. package/dist/esm/ui/default-styles.js.map +1 -0
  47. package/dist/esm/ui/image-editor.d.ts +10 -0
  48. package/dist/esm/ui/image-editor.js +103 -0
  49. package/dist/esm/ui/image-editor.js.map +1 -0
  50. package/dist/esm/ui/layout-manager.d.ts +42 -0
  51. package/dist/esm/ui/layout-manager.js +199 -0
  52. package/dist/esm/ui/layout-manager.js.map +1 -0
  53. package/dist/esm/ui/media-viewer.d.ts +2 -0
  54. package/dist/esm/ui/media-viewer.js +267 -0
  55. package/dist/esm/ui/media-viewer.js.map +1 -0
  56. package/dist/esm/ui/pinch-zoom-handler.d.ts +37 -0
  57. package/dist/esm/ui/pinch-zoom-handler.js +118 -0
  58. package/dist/esm/ui/pinch-zoom-handler.js.map +1 -0
  59. package/dist/esm/ui/ui-factory.d.ts +39 -0
  60. package/dist/esm/ui/ui-factory.js +272 -0
  61. package/dist/esm/ui/ui-factory.js.map +1 -0
  62. package/dist/esm/version.d.ts +1 -0
  63. package/dist/esm/version.js +3 -0
  64. package/dist/esm/version.js.map +1 -0
  65. package/dist/esm/web.d.ts +69 -0
  66. package/dist/esm/web.js +122 -0
  67. package/dist/esm/web.js.map +1 -0
  68. package/dist/plugin.cjs.js +6274 -0
  69. package/dist/plugin.cjs.js.map +1 -0
  70. package/dist/plugin.js +6276 -0
  71. package/dist/plugin.js.map +1 -0
  72. package/ios/Sources/CameraMultiCapturePlugin/CameraMultiCapture.swift +8 -0
  73. package/ios/Sources/CameraMultiCapturePlugin/CameraMultiCapturePlugin.swift +1551 -0
  74. package/ios/Sources/CameraMultiCapturePlugin/PluginVersion.swift +2 -0
  75. package/ios/Tests/CameraMultiCapturePluginTests/CameraMultiCapturePluginTests.swift +15 -0
  76. package/package.json +93 -0
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CameraMultiCapture'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '14.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hemang Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CameraMultiCapture",
6
+ platforms: [.iOS(.v14)],
7
+ products: [
8
+ .library(
9
+ name: "CameraMultiCapture",
10
+ targets: ["CameraMultiCapturePlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "CameraMultiCapturePlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/CameraMultiCapturePlugin"),
23
+ .testTarget(
24
+ name: "CameraMultiCapturePluginTests",
25
+ dependencies: ["CameraMultiCapturePlugin"],
26
+ path: "ios/Tests/CameraMultiCapturePluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,551 @@
1
+ # capacitor-camera-multicapture
2
+
3
+ Capacitor plugin that lets the user capture multiple photos and videos with a customizable UI overlay in a single camera session. Includes built-in image annotation powered by marker.js 2.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install capacitor-camera-multicapture
9
+ npx cap sync
10
+ ```
11
+
12
+ ## Configuration
13
+
14
+ ### iOS (Info.plist)
15
+
16
+ Add the following permissions to your iOS app's `Info.plist` file:
17
+
18
+ ```xml
19
+ <key>NSCameraUsageDescription</key>
20
+ <string>This app needs access to camera to capture photos</string>
21
+ <key>NSPhotoLibraryUsageDescription</key>
22
+ <string>This app needs access to photo library to save captured images</string>
23
+ <key>NSPhotoLibraryAddUsageDescription</key>
24
+ <string>This app needs access to photo library to save captured images</string>
25
+ ```
26
+
27
+ ### Android (AndroidManifest.xml)
28
+
29
+ The plugin automatically adds the necessary permissions to your Android app. However, if you need to declare them explicitly, add these to your `android/app/src/main/AndroidManifest.xml`:
30
+
31
+ ```xml
32
+ <uses-permission android:name="android.permission.CAMERA" />
33
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
34
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
35
+ ```
36
+
37
+ ### Permission Handling
38
+
39
+ Before using the camera, check and request permissions:
40
+
41
+ ```typescript
42
+ import { CameraMultiCapture } from 'capacitor-camera-multicapture';
43
+
44
+ // Check current permissions
45
+ const permissions = await CameraMultiCapture.checkPermissions();
46
+
47
+ if (permissions.camera !== 'granted' || permissions.photos !== 'granted') {
48
+ // Request permissions
49
+ const result = await CameraMultiCapture.requestPermissions();
50
+
51
+ if (result.camera !== 'granted') {
52
+ console.error('Camera permission denied');
53
+ return;
54
+ }
55
+ }
56
+
57
+ // Now you can safely use the camera
58
+ const cameraResult = await CameraMultiCapture.start(options);
59
+ ```
60
+
61
+ ## Demo
62
+
63
+ https://github.com/hemangsk/capacitor-multi-preview-demo
64
+
65
+ ## Usage
66
+
67
+ ```typescript
68
+ import { initialize, CameraOverlayResult } from 'capacitor-camera-multicapture';
69
+
70
+ const result = await initialize({
71
+ containerId: 'camera-overlay',
72
+ quality: 90,
73
+ thumbnailStyle: {
74
+ width: '100px',
75
+ height: '100px'
76
+ },
77
+
78
+ /** more options */
79
+ }).then((result: CameraOverlayResult) => {
80
+ if (result.cancelled) {
81
+ console.log('User cancelled the camera overlay');
82
+ } else {
83
+ console.log('Captured images:', result.images);
84
+ }
85
+
86
+ // normally you'd want go back to previous screen
87
+
88
+ // this.navCtrl.pop();
89
+ // this.navCtrl.navigateBack();
90
+ });
91
+
92
+ // Single capture mode example - returns immediately after one photo
93
+ const singleResult = await initialize({
94
+ containerId: 'camera-overlay',
95
+ quality: 90,
96
+ maxCaptures: 1 // Automatically returns after capturing one image
97
+ }).then((result: CameraOverlayResult) => {
98
+ if (!result.cancelled && result.images.length > 0) {
99
+ console.log('Single image captured:', result.images[0]);
100
+ }
101
+ });
102
+ ```
103
+
104
+ ```html
105
+ <div id="camera-overlay"></div>
106
+ ```
107
+
108
+ ```css
109
+ #camera-overlay {
110
+ width: 100%; // or any other value for custom container
111
+ height: 100%;
112
+
113
+ background-color: transparent !important;
114
+ --background: transparent !important;
115
+ --ion-background-color: transparent !important;
116
+ }
117
+ ```
118
+
119
+ ### Examples
120
+
121
+ #### Single Capture Mode
122
+
123
+ ```typescript
124
+ // Capture only one image and return immediately
125
+ const result = await initialize({
126
+ maxCaptures: 1, // Single capture mode
127
+ containerId: 'camera-container',
128
+ quality: 90
129
+ });
130
+ ```
131
+
132
+ #### Video Recording (Tap & Long-Press)
133
+
134
+ The capture button supports dual gestures: a quick tap captures a photo, and a long-press starts video recording. During recording a pulsing indicator with an elapsed timer is shown, and the capture button glows red.
135
+
136
+ ```typescript
137
+ const result = await initialize({
138
+ containerId: 'camera-container',
139
+ quality: 90,
140
+ maxRecordingDuration: 30, // seconds; auto-stops when reached
141
+ });
142
+
143
+ // result.images – captured photos
144
+ // result.videos – captured videos (uri, thumbnail, duration)
145
+ ```
146
+
147
+ Videos appear as thumbnails with a play badge and duration label. Tapping a video thumbnail opens a fullscreen preview.
148
+
149
+ #### Image Annotation (marker.js 2)
150
+
151
+ After capturing photos you can annotate them directly in the camera session. Tap a thumbnail to open the fullscreen preview, then tap the edit (pencil) icon to launch the marker.js 2 editor.
152
+
153
+ The editor supports freehand drawing, arrows, text, callouts, and more. Annotations are non-destructive — editor state is preserved so you can re-open and continue editing. On save the annotated image replaces the original in the gallery.
154
+
155
+ #### Smart Zoom with Physical Camera Switching
156
+
157
+ The plugin automatically detects available physical cameras (ultrawide, wide, telephoto) and displays appropriate zoom buttons. The system seamlessly switches between physical cameras when you select certain zoom levels.
158
+
159
+ #### Button Opacity and Shot Counter
160
+
161
+ ```typescript
162
+ // Semi-transparent buttons with shot counter
163
+ const result = await initialize({
164
+ containerId: 'camera-container',
165
+ quality: 90,
166
+ showShotCounter: true, // Display shot count
167
+ buttons: {
168
+ capture: {
169
+ style: {
170
+ backgroundColor: '#ffffff',
171
+ opacity: 0.8 // 80% opacity
172
+ }
173
+ },
174
+ done: {
175
+ style: {
176
+ backgroundColor: '#28a745',
177
+ opacity: 0.9 // 90% opacity
178
+ }
179
+ }
180
+ }
181
+ });
182
+ ```
183
+
184
+ #### Flash Auto Mode
185
+
186
+ ```typescript
187
+ // Enable flash auto mode
188
+ const result = await initialize({
189
+ containerId: 'camera-container',
190
+ flashAutoModeEnabled: true, // Allow auto flash mode
191
+ flash: 'auto' // Start with auto flash
192
+ });
193
+ ```
194
+
195
+ #### Pinch-to-Zoom with Zoom Button Sync
196
+
197
+ The overlay supports a JavaScript-based pinch-to-zoom gesture on both Android and iOS.
198
+
199
+ When enabled:
200
+
201
+ - Users can pinch in/out anywhere on the camera preview.
202
+ - The current zoom level is clamped to the device’s supported zoom range.
203
+ - Zoom buttons (e.g. 0.7x, 1x, 2x) stay in sync with the active zoom level.
204
+ - If `lockToNearestStep` is `true`, the zoom snaps to the nearest preset level when the pinch ends.
205
+
206
+ ```typescript
207
+
208
+ import { initialize, CameraOverlayResult } from "capacitor-camera-multicapture";
209
+ const result: CameraOverlayResult = await initialize({
210
+ containerId: "camera-container",
211
+ quality: 90,
212
+ // Enable JS pinch-to-zoom
213
+ pinchToZoom: {
214
+ enabled: true,
215
+ lockToNearestStep: true, // Snap to nearest preset (e.g. 0.7x, 1x, 2x)
216
+ },
217
+ buttons: {
218
+ // Optional: smart zoom buttons that are kept in sync with pinch
219
+ zoom: {
220
+ levels: [0.7, 1, 2, 3], // Example zoom steps; plugin may override with device-specific smart levels
221
+ style: {
222
+ radius: 30,
223
+ backgroundColor: "rgba(0,0,0,0.5)",
224
+ color: "#ffffff",
225
+ padding: "10px",
226
+ size: 24,
227
+ },
228
+ },
229
+ },
230
+ });
231
+ ```
232
+ **Notes:**
233
+
234
+ - Pinch handling is implemented entirely in the overlay layer (JavaScript), independent of native gesture recognizers.
235
+ - The plugin still uses native camera APIs (CameraX / AVFoundation) for the actual zoom, but all gesture detection runs on the web side.
236
+ - If `pinchToZoom` is omitted or `enabled` is `false`, pinch gestures are ignored and only the zoom buttons are used.
237
+
238
+ #### Advanced Button Styling with Box Shadows and Filters
239
+
240
+ ```typescript
241
+ // Enhanced button styling with shadows and filters
242
+ const result = await initialize({
243
+ containerId: 'camera-container',
244
+ quality: 90,
245
+ buttons: {
246
+ capture: {
247
+ style: {
248
+ backgroundColor: '#ffffff',
249
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)',
250
+ filter: 'brightness(1.1)'
251
+ }
252
+ },
253
+ done: {
254
+ style: {
255
+ backgroundColor: '#28a745',
256
+ boxShadow: '0 2px 8px rgba(40, 167, 69, 0.3)',
257
+ filter: 'saturate(1.2)'
258
+ }
259
+ },
260
+ cancel: {
261
+ style: {
262
+ backgroundColor: '#dc3545',
263
+ boxShadow: '0 2px 8px rgba(220, 53, 69, 0.3)',
264
+ filter: 'contrast(1.1)'
265
+ }
266
+ },
267
+ switchCamera: {
268
+ style: {
269
+ backgroundColor: 'rgba(0,0,0,0.5)',
270
+ boxShadow: '0 2px 6px rgba(0, 0, 0, 0.3)',
271
+ filter: 'blur(0.5px) brightness(1.1)'
272
+ }
273
+ }
274
+ }
275
+ });
276
+ ```
277
+
278
+ **Available Filter Effects:**
279
+ - `blur(2px)` - Blur effect
280
+ - `brightness(1.2)` - Brightness adjustment (1.0 = normal)
281
+ - `contrast(1.5)` - Contrast enhancement
282
+ - `grayscale(100%)` - Grayscale effect
283
+ - `saturate(1.3)` - Saturation boost
284
+ - `hue-rotate(90deg)` - Hue rotation
285
+ - `drop-shadow(0 2px 4px rgba(0,0,0,0.2))` - Drop shadow alternative
286
+ - Multiple filters: `brightness(1.1) contrast(1.2) saturate(1.3)`
287
+
288
+ **Box Shadow Examples:**
289
+ - Subtle: `0 2px 4px rgba(0, 0, 0, 0.1)`
290
+ - Prominent: `0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)`
291
+ - Colored: `0 4px 12px rgba(59, 130, 246, 0.4)`
292
+ - Inset: `inset 0 1px 0 rgba(255, 255, 255, 0.2)`
293
+
294
+ ## API
295
+
296
+ <docgen-index>
297
+
298
+ * [`start(...)`](#start)
299
+ * [`capture()`](#capture)
300
+ * [`stop()`](#stop)
301
+ * [`switchCamera()`](#switchcamera)
302
+ * [`setZoom(...)`](#setzoom)
303
+ * [`updatePreviewRect(...)`](#updatepreviewrect)
304
+ * [`checkPermissions()`](#checkpermissions)
305
+ * [`requestPermissions()`](#requestpermissions)
306
+ * [Interfaces](#interfaces)
307
+ * [Type Aliases](#type-aliases)
308
+
309
+ </docgen-index>
310
+
311
+ <docgen-api>
312
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
313
+
314
+ ### start(...)
315
+
316
+ ```typescript
317
+ start(options?: CameraOverlayOptions | undefined) => Promise<CameraOverlayResult>
318
+ ```
319
+
320
+ Starts the camera overlay session.
321
+
322
+ | Param | Type |
323
+ | ------------- | --------------------------------------------------------------------- |
324
+ | **`options`** | <code><a href="#cameraoverlayoptions">CameraOverlayOptions</a></code> |
325
+
326
+ **Returns:** <code>Promise&lt;<a href="#cameraoverlayresult">CameraOverlayResult</a>&gt;</code>
327
+
328
+ --------------------
329
+
330
+
331
+ ### capture()
332
+
333
+ ```typescript
334
+ capture() => Promise<{ value: CameraImageData; }>
335
+ ```
336
+
337
+ Captures a single frame.
338
+
339
+ **Returns:** <code>Promise&lt;{ value: <a href="#cameraimagedata">CameraImageData</a>; }&gt;</code>
340
+
341
+ --------------------
342
+
343
+
344
+ ### stop()
345
+
346
+ ```typescript
347
+ stop() => Promise<void>
348
+ ```
349
+
350
+ Stops and tears down the camera session.
351
+
352
+ --------------------
353
+
354
+
355
+ ### switchCamera()
356
+
357
+ ```typescript
358
+ switchCamera() => Promise<void>
359
+ ```
360
+
361
+ Switches the camera between front and back.
362
+
363
+ --------------------
364
+
365
+
366
+ ### setZoom(...)
367
+
368
+ ```typescript
369
+ setZoom(options: { zoom: number; }) => Promise<void>
370
+ ```
371
+
372
+ Sets the zoom level of the camera.
373
+
374
+ | Param | Type |
375
+ | ------------- | ------------------------------ |
376
+ | **`options`** | <code>{ zoom: number; }</code> |
377
+
378
+ --------------------
379
+
380
+
381
+ ### updatePreviewRect(...)
382
+
383
+ ```typescript
384
+ updatePreviewRect(options: CameraPreviewRect) => Promise<void>
385
+ ```
386
+
387
+ Updates the camera preview rectangle dimensions.
388
+ Call this when the container size changes (e.g., orientation change).
389
+
390
+ | Param | Type |
391
+ | ------------- | --------------------------------------------------------------- |
392
+ | **`options`** | <code><a href="#camerapreviewrect">CameraPreviewRect</a></code> |
393
+
394
+ --------------------
395
+
396
+
397
+ ### checkPermissions()
398
+
399
+ ```typescript
400
+ checkPermissions() => Promise<PermissionStatus>
401
+ ```
402
+
403
+ Check camera and photo library permissions
404
+
405
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
406
+
407
+ --------------------
408
+
409
+
410
+ ### requestPermissions()
411
+
412
+ ```typescript
413
+ requestPermissions() => Promise<PermissionStatus>
414
+ ```
415
+
416
+ Request camera and photo library permissions
417
+
418
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
419
+
420
+ --------------------
421
+
422
+
423
+ ### Interfaces
424
+
425
+
426
+ #### CameraOverlayResult
427
+
428
+ | Prop | Type |
429
+ | --------------- | ------------------------------ |
430
+ | **`images`** | <code>CameraImageData[]</code> |
431
+ | **`videos`** | <code>CameraVideoData[]</code> |
432
+ | **`cancelled`** | <code>boolean</code> |
433
+
434
+
435
+ #### PermissionStatus
436
+
437
+ Permission status for the camera multi-capture plugin
438
+
439
+ | Prop | Type |
440
+ | ------------ | ----------------------------------------------------------- |
441
+ | **`camera`** | <code>'granted' \| 'denied' \| 'prompt'</code> |
442
+ | **`photos`** | <code>'granted' \| 'denied' \| 'prompt'</code> |
443
+
444
+
445
+ #### CameraImageData
446
+
447
+ Structure for image data returned by the camera
448
+
449
+ | Prop | Type |
450
+ | ------------ | ------------------- |
451
+ | **`uri`** | <code>string</code> |
452
+ | **`base64`** | <code>string</code> |
453
+
454
+
455
+ #### CameraOverlayOptions
456
+
457
+ | Prop | Type |
458
+ | -------------------- | --------------------------------------------------------------------- |
459
+ | **`buttons`** | <code><a href="#cameraoverlaybuttons">CameraOverlayButtons</a></code> |
460
+ | **`thumbnailStyle`** | <code>{ width: string; height: string; }</code> |
461
+ | **`quality`** | <code>number</code> |
462
+ | **`containerId`** | <code>string</code> |
463
+ | **`previewRect`** | <code><a href="#camerapreviewrect">CameraPreviewRect</a></code> |
464
+ | **`direction`** | <code><a href="#cameradirection">CameraDirection</a></code> |
465
+ | **`captureMode`** | <code><a href="#capturemode">CaptureMode</a></code> |
466
+ | **`resolution`** | <code><a href="#resolution">Resolution</a></code> |
467
+ | **`zoom`** | <code>number</code> |
468
+ | **`autoFocus`** | <code>boolean</code> |
469
+ | **`maxCaptures`** | <code>number</code> |
470
+ | **`flashAutoModeEnabled`** | <code>boolean</code> |
471
+ | **`showShotCounter`** | <code>boolean</code> |
472
+ | **`pinchToZoom`** | <code>{ enabled?: boolean; lockToNearestStep?: boolean; }</code> |
473
+
474
+
475
+ #### CameraOverlayButtons
476
+
477
+ | Prop | Type |
478
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
479
+ | **`capture`** | <code>{ icon?: string; style?: <a href="#buttonstyle">ButtonStyle</a>; position?: 'center' \| 'left' \| 'right' \| 'custom'; }</code> |
480
+ | **`done`** | <code>{ icon?: string; style?: <a href="#buttonstyle">ButtonStyle</a>; text?: string; }</code> |
481
+ | **`cancel`** | <code>{ icon?: string; style?: <a href="#buttonstyle">ButtonStyle</a>; text?: string; }</code> |
482
+ | **`switchCamera`** | <code>{ icon?: string; style?: <a href="#buttonstyle">ButtonStyle</a>; position?: 'custom' \| 'topLeft' \| 'topRight'; }</code> |
483
+ | **`zoom`** | <code>{ icon?: string; style?: <a href="#buttonstyle">ButtonStyle</a>; levels?: number[]; }</code> |
484
+
485
+
486
+ #### ButtonStyle
487
+
488
+ | Prop | Type |
489
+ | --------------------- | ------------------- |
490
+ | **`radius`** | <code>number</code> |
491
+ | **`color`** | <code>string</code> |
492
+ | **`backgroundColor`** | <code>string</code> |
493
+ | **`padding`** | <code>string</code> |
494
+ | **`size`** | <code>number</code> |
495
+ | **`activeColor`** | <code>string</code> |
496
+ | **`border`** | <code>string</code> |
497
+ | **`opacity`** | <code>number</code> |
498
+ | **`boxShadow`** | <code>string</code> |
499
+ | **`filter`** | <code>string</code> |
500
+
501
+
502
+ #### CameraPreviewRect
503
+
504
+ | Prop | Type |
505
+ | ------------ | ------------------- |
506
+ | **`width`** | <code>number</code> |
507
+ | **`height`** | <code>number</code> |
508
+ | **`x`** | <code>number</code> |
509
+ | **`y`** | <code>number</code> |
510
+
511
+
512
+ #### Resolution
513
+
514
+ | Prop | Type |
515
+ | ------------ | ------------------- |
516
+ | **`width`** | <code>number</code> |
517
+ | **`height`** | <code>number</code> |
518
+
519
+
520
+ ### Type Aliases
521
+
522
+
523
+ #### ButtonStyle
524
+
525
+ Defines the style properties for camera buttons
526
+
527
+ <code>OriginalButtonStyle</code>
528
+
529
+
530
+ #### CameraDirection
531
+
532
+ <code>'front' | 'back'</code>
533
+
534
+
535
+ #### CaptureMode
536
+
537
+ <code>'minimizeLatency' | 'maxQuality'</code>
538
+
539
+ </docgen-api>
540
+
541
+
542
+ ## License
543
+
544
+ MIT
545
+
546
+ ## Acknowledgements
547
+
548
+ - ![isbecker](https://github.com/isbecker)'s comment at https://github.com/ionic-team/capacitor-plugins/issues/1616#issuecomment-1912900318
549
+ - Capawesome plugins repository for formatting scripts and documentation setup.
550
+ - [marker.js 2](https://markerjs.com/) for the image annotation engine.
551
+ - [bigger-picture](https://github.com/henrygd/bigger-picture) for fullscreen media preview.
@@ -0,0 +1,69 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.7.3'
15
+
16
+ }
17
+ }
18
+
19
+ apply plugin: 'com.android.library'
20
+
21
+ android {
22
+ namespace "dev.hemang.cameramulticapture"
23
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
24
+ defaultConfig {
25
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
26
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
27
+ versionCode 1
28
+ versionName "1.0"
29
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
30
+ }
31
+ buildTypes {
32
+ release {
33
+ minifyEnabled false
34
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
35
+ }
36
+ }
37
+ lintOptions {
38
+ abortOnError false
39
+ }
40
+ compileOptions {
41
+ sourceCompatibility JavaVersion.VERSION_21
42
+ targetCompatibility JavaVersion.VERSION_21
43
+ }
44
+ }
45
+
46
+ repositories {
47
+ google()
48
+ mavenCentral()
49
+ }
50
+
51
+
52
+ dependencies {
53
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
54
+ implementation project(':capacitor-android')
55
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
56
+ testImplementation "junit:junit:$junitVersion"
57
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
58
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
59
+
60
+ implementation "androidx.camera:camera-core:1.4.2"
61
+ implementation "androidx.camera:camera-camera2:1.4.2"
62
+ implementation "androidx.camera:camera-lifecycle:1.4.2"
63
+ implementation "androidx.camera:camera-view:1.4.2"
64
+ implementation "androidx.camera:camera-video:1.4.2"
65
+ implementation "androidx.camera:camera-extensions:1.4.2"
66
+ implementation 'androidx.work:work-runtime:2.8.1'
67
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
68
+ api 'androidx.exifinterface:exifinterface:1.3.7'
69
+ }
@@ -0,0 +1,6 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.INTERNET" />
3
+ <uses-permission android:name="android.permission.CAMERA" />
4
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
5
+ <uses-feature android:name="android.hardware.camera" android:required="true" />
6
+ </manifest>