@capgo/camera-preview 7.4.0-beta.2 → 7.4.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +120 -30
  2. package/android/.gradle/8.14.2/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.14.2/checksums/md5-checksums.bin +0 -0
  4. package/android/.gradle/8.14.2/checksums/sha1-checksums.bin +0 -0
  5. package/android/.gradle/8.14.2/executionHistory/executionHistory.bin +0 -0
  6. package/android/.gradle/8.14.2/executionHistory/executionHistory.lock +0 -0
  7. package/android/.gradle/8.14.2/fileHashes/fileHashes.bin +0 -0
  8. package/android/.gradle/8.14.2/fileHashes/fileHashes.lock +0 -0
  9. package/android/.gradle/8.14.2/fileHashes/resourceHashesCache.bin +0 -0
  10. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  11. package/android/.gradle/file-system.probe +0 -0
  12. package/android/build.gradle +2 -1
  13. package/android/src/main/AndroidManifest.xml +1 -4
  14. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +111 -29
  15. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +152 -17
  16. package/android/src/main/java/com/ahm/capacitor/camera/preview/GridOverlayView.java +80 -0
  17. package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraSessionConfiguration.java +19 -5
  18. package/dist/docs.json +117 -4
  19. package/dist/esm/definitions.d.ts +52 -3
  20. package/dist/esm/definitions.js.map +1 -1
  21. package/dist/esm/web.d.ts +16 -2
  22. package/dist/esm/web.js +180 -78
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +178 -78
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +178 -78
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Sources/CapgoCameraPreview/CameraController.swift +131 -13
  29. package/ios/Sources/CapgoCameraPreview/GridOverlayView.swift +65 -0
  30. package/ios/Sources/CapgoCameraPreview/Plugin.swift +176 -37
  31. package/package.json +1 -1
@@ -18,6 +18,8 @@ import androidx.camera.core.ImageCapture;
18
18
  import androidx.camera.core.ImageCaptureException;
19
19
  import androidx.camera.core.ImageProxy;
20
20
  import androidx.camera.core.Preview;
21
+ import androidx.camera.core.AspectRatio;
22
+ import androidx.camera.core.resolutionselector.AspectRatioStrategy;
21
23
  import androidx.camera.core.resolutionselector.ResolutionSelector;
22
24
  import androidx.camera.core.resolutionselector.ResolutionStrategy;
23
25
  import androidx.camera.lifecycle.ProcessCameraProvider;
@@ -27,6 +29,7 @@ import androidx.lifecycle.Lifecycle;
27
29
  import androidx.lifecycle.LifecycleOwner;
28
30
  import androidx.lifecycle.LifecycleRegistry;
29
31
  import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
32
+ import android.widget.FrameLayout;
30
33
  import com.ahm.capacitor.camera.preview.model.LensInfo;
31
34
  import com.ahm.capacitor.camera.preview.model.ZoomFactors;
32
35
  import com.google.common.util.concurrent.ListenableFuture;
@@ -56,8 +59,17 @@ import java.util.Locale;
56
59
  import androidx.exifinterface.media.ExifInterface;
57
60
  import org.json.JSONObject;
58
61
  import java.nio.file.Files;
59
-
60
- public class CameraXView implements LifecycleOwner {
62
+ import android.graphics.BitmapFactory;
63
+ import android.graphics.Bitmap;
64
+ import android.graphics.Matrix;
65
+ import java.io.ByteArrayOutputStream;
66
+ import android.location.Location;
67
+ import android.widget.FrameLayout;
68
+ import androidx.lifecycle.LifecycleObserver;
69
+ import androidx.lifecycle.OnLifecycleEvent;
70
+ import android.util.Rational;
71
+
72
+ public class CameraXView implements LifecycleOwner, LifecycleObserver {
61
73
  private static final String TAG = "CameraPreview CameraXView";
62
74
 
63
75
  public interface CameraXViewListener {
@@ -74,6 +86,8 @@ public class CameraXView implements LifecycleOwner {
74
86
  private ImageCapture imageCapture;
75
87
  private ImageCapture sampleImageCapture;
76
88
  private PreviewView previewView;
89
+ private GridOverlayView gridOverlayView;
90
+ private FrameLayout previewContainer;
77
91
  private CameraSelector currentCameraSelector;
78
92
  private String currentDeviceId;
79
93
  private int currentFlashMode = ImageCapture.FLASH_MODE_OFF;
@@ -174,23 +188,47 @@ public class CameraXView implements LifecycleOwner {
174
188
  if (sessionConfig.isToBack()) {
175
189
  webView.setBackgroundColor(android.graphics.Color.TRANSPARENT);
176
190
  }
191
+
192
+ // Create a container to hold both the preview and grid overlay
193
+ previewContainer = new FrameLayout(context);
194
+
195
+ // Create and setup the preview view
177
196
  previewView = new PreviewView(context);
178
197
  previewView.setScaleType(PreviewView.ScaleType.FILL_CENTER);
198
+ previewContainer.addView(previewView, new FrameLayout.LayoutParams(
199
+ FrameLayout.LayoutParams.MATCH_PARENT,
200
+ FrameLayout.LayoutParams.MATCH_PARENT
201
+ ));
202
+
203
+ // Create and setup the grid overlay
204
+ gridOverlayView = new GridOverlayView(context);
205
+ gridOverlayView.setGridMode(sessionConfig.getGridMode());
206
+ previewContainer.addView(gridOverlayView, new FrameLayout.LayoutParams(
207
+ FrameLayout.LayoutParams.MATCH_PARENT,
208
+ FrameLayout.LayoutParams.MATCH_PARENT
209
+ ));
210
+
179
211
  ViewGroup parent = (ViewGroup) webView.getParent();
180
212
  if (parent != null) {
181
- parent.addView(previewView, new ViewGroup.LayoutParams(sessionConfig.getWidth(), sessionConfig.getHeight()));
213
+ parent.addView(previewContainer, new ViewGroup.LayoutParams(sessionConfig.getWidth(), sessionConfig.getHeight()));
182
214
  if(sessionConfig.isToBack()) webView.bringToFront();
183
215
  }
184
216
  }
185
217
 
186
218
  private void removePreviewView() {
187
- if (previewView != null) {
188
- ViewGroup parent = (ViewGroup) previewView.getParent();
219
+ if (previewContainer != null) {
220
+ ViewGroup parent = (ViewGroup) previewContainer.getParent();
189
221
  if (parent != null) {
190
- parent.removeView(previewView);
222
+ parent.removeView(previewContainer);
191
223
  }
224
+ previewContainer = null;
225
+ }
226
+ if (previewView != null) {
192
227
  previewView = null;
193
228
  }
229
+ if (gridOverlayView != null) {
230
+ gridOverlayView = null;
231
+ }
194
232
  webView.setBackgroundColor(android.graphics.Color.WHITE);
195
233
  }
196
234
 
@@ -201,9 +239,22 @@ public class CameraXView implements LifecycleOwner {
201
239
  try {
202
240
  Log.d(TAG, "Building camera selector with deviceId: " + sessionConfig.getDeviceId() + " and position: " + sessionConfig.getPosition());
203
241
  currentCameraSelector = buildCameraSelector();
204
- ResolutionSelector resolutionSelector = new ResolutionSelector.Builder()
205
- .setResolutionStrategy(ResolutionStrategy.HIGHEST_AVAILABLE_STRATEGY)
206
- .build();
242
+
243
+ ResolutionSelector.Builder resolutionSelectorBuilder = new ResolutionSelector.Builder()
244
+ .setResolutionStrategy(ResolutionStrategy.HIGHEST_AVAILABLE_STRATEGY);
245
+
246
+ if (sessionConfig.getAspectRatio() != null) {
247
+ int aspectRatio;
248
+ if ("16:9".equals(sessionConfig.getAspectRatio())) {
249
+ aspectRatio = AspectRatio.RATIO_16_9;
250
+ } else { // "4:3"
251
+ aspectRatio = AspectRatio.RATIO_4_3;
252
+ }
253
+ resolutionSelectorBuilder.setAspectRatioStrategy(new AspectRatioStrategy(aspectRatio, AspectRatioStrategy.FALLBACK_RULE_AUTO));
254
+ }
255
+
256
+ ResolutionSelector resolutionSelector = resolutionSelectorBuilder.build();
257
+
207
258
  Preview preview = new Preview.Builder().setResolutionSelector(resolutionSelector).build();
208
259
  imageCapture = new ImageCapture.Builder().setResolutionSelector(resolutionSelector).setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY).setFlashMode(currentFlashMode).build();
209
260
  sampleImageCapture = imageCapture;
@@ -314,7 +365,7 @@ public class CameraXView implements LifecycleOwner {
314
365
  }
315
366
  }
316
367
 
317
- public void capturePhoto(int quality, final boolean saveToGallery) {
368
+ public void capturePhoto(int quality, final boolean saveToGallery, Integer width, Integer height, Location location) {
318
369
  Log.d(TAG, "capturePhoto: Starting photo capture with quality: " + quality);
319
370
 
320
371
  if (imageCapture == null) {
@@ -342,16 +393,34 @@ public class CameraXView implements LifecycleOwner {
342
393
  @Override
343
394
  public void onImageSaved(@NonNull ImageCapture.OutputFileResults output) {
344
395
  try {
345
- byte[] bytes = Files.readAllBytes(tempFile.toPath());
396
+ // Read file using FileInputStream for compatibility
397
+ byte[] bytes = new byte[(int) tempFile.length()];
398
+ java.io.FileInputStream fis = new java.io.FileInputStream(tempFile);
399
+ fis.read(bytes);
400
+ fis.close();
401
+
346
402
  ExifInterface exifInterface = new ExifInterface(tempFile.getAbsolutePath());
403
+
404
+ if (location != null) {
405
+ exifInterface.setGpsInfo(location);
406
+ }
407
+
347
408
  JSONObject exifData = getExifData(exifInterface);
348
409
 
410
+ if (width != null && height != null) {
411
+ Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
412
+ Bitmap resizedBitmap = resizeBitmap(bitmap, width, height);
413
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
414
+ resizedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
415
+ bytes = stream.toByteArray();
416
+ }
417
+
349
418
  if (saveToGallery) {
350
419
  saveImageToGallery(bytes);
351
420
  }
352
421
 
353
422
  String base64 = Base64.encodeToString(bytes, Base64.NO_WRAP);
354
-
423
+
355
424
  tempFile.delete();
356
425
 
357
426
  if (listener != null) {
@@ -368,6 +437,10 @@ public class CameraXView implements LifecycleOwner {
368
437
  );
369
438
  }
370
439
 
440
+ private Bitmap resizeBitmap(Bitmap bitmap, int width, int height) {
441
+ return Bitmap.createScaledBitmap(bitmap, width, height, true);
442
+ }
443
+
371
444
  private JSONObject getExifData(ExifInterface exifInterface) {
372
445
  JSONObject exifData = new JSONObject();
373
446
  try {
@@ -593,7 +666,7 @@ public class CameraXView implements LifecycleOwner {
593
666
  for (CameraInfo cameraInfo : cameraProvider.getAvailableCameraInfos()) {
594
667
  String logicalCameraId = Camera2CameraInfo.from(cameraInfo).getCameraId();
595
668
  String position = isBackCamera(cameraInfo) ? "rear" : "front";
596
-
669
+
597
670
  // Add logical camera
598
671
  float minZoom = Objects.requireNonNull(cameraInfo.getZoomState().getValue()).getMinZoomRatio();
599
672
  float maxZoom = cameraInfo.getZoomState().getValue().getMaxZoomRatio();
@@ -629,7 +702,7 @@ public class CameraXView implements LifecycleOwner {
629
702
  if (focalLengths[0] < 3.0f) deviceType = "ultraWide";
630
703
  else if (focalLengths[0] > 5.0f) deviceType = "telephoto";
631
704
  }
632
-
705
+
633
706
  float physicalMinZoom = 1.0f;
634
707
  float physicalMaxZoom = 1.0f;
635
708
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
@@ -639,11 +712,11 @@ public class CameraXView implements LifecycleOwner {
639
712
  physicalMaxZoom = zoomRange.getUpper();
640
713
  }
641
714
  }
642
-
715
+
643
716
  String label = "Physical " + deviceType + " (" + position + ")";
644
717
  List<LensInfo> physicalLenses = new ArrayList<>();
645
718
  physicalLenses.add(new LensInfo(focalLengths != null ? focalLengths[0] : 4.25f, deviceType, 1.0f, physicalMaxZoom));
646
-
719
+
647
720
  devices.add(new com.ahm.capacitor.camera.preview.model.CameraDevice(
648
721
  physicalId, label, position, physicalLenses, physicalMinZoom, physicalMaxZoom, false
649
722
  ));
@@ -947,7 +1020,9 @@ public class CameraXView implements LifecycleOwner {
947
1020
  sessionConfig.isEnableZoom(), // enableZoom
948
1021
  sessionConfig.isDisableExifHeaderStripping(), // disableExifHeaderStripping
949
1022
  sessionConfig.isDisableAudio(), // disableAudio
950
- sessionConfig.getZoomFactor() // zoomFactor
1023
+ sessionConfig.getZoomFactor(), // zoomFactor
1024
+ sessionConfig.getAspectRatio(), // aspectRatio
1025
+ sessionConfig.getGridMode() // gridMode
951
1026
  );
952
1027
 
953
1028
  // Clear current device ID to force position-based selection
@@ -965,4 +1040,64 @@ public class CameraXView implements LifecycleOwner {
965
1040
  previewView.setAlpha(opacity);
966
1041
  }
967
1042
  }
1043
+
1044
+ private void updateLayoutParams() {
1045
+ if (sessionConfig == null) return;
1046
+
1047
+ FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
1048
+ sessionConfig.getWidth(),
1049
+ sessionConfig.getHeight()
1050
+ );
1051
+ layoutParams.leftMargin = sessionConfig.getX();
1052
+ layoutParams.topMargin = sessionConfig.getY();
1053
+
1054
+ if (sessionConfig.getAspectRatio() != null && !sessionConfig.getAspectRatio().equals("fill")) {
1055
+ String[] ratios = sessionConfig.getAspectRatio().split(":");
1056
+ float ratio = Float.parseFloat(ratios[0]) / Float.parseFloat(ratios[1]);
1057
+ if (sessionConfig.getWidth() > 0) {
1058
+ layoutParams.height = (int) (sessionConfig.getWidth() / ratio);
1059
+ } else if (sessionConfig.getHeight() > 0) {
1060
+ layoutParams.width = (int) (sessionConfig.getHeight() * ratio);
1061
+ }
1062
+ } else {
1063
+ previewView.setScaleType(PreviewView.ScaleType.FILL_CENTER);
1064
+ }
1065
+
1066
+ previewView.setLayoutParams(layoutParams);
1067
+
1068
+ if (listener != null) {
1069
+ listener.onCameraStarted();
1070
+ }
1071
+ }
1072
+
1073
+ public String getAspectRatio() {
1074
+ if (sessionConfig != null) {
1075
+ return sessionConfig.getAspectRatio();
1076
+ }
1077
+ return "fill";
1078
+ }
1079
+
1080
+ public void setAspectRatio(String aspectRatio) {
1081
+ if (sessionConfig != null) {
1082
+ sessionConfig = new CameraSessionConfiguration(
1083
+ sessionConfig.getDeviceId(),
1084
+ sessionConfig.getPosition(),
1085
+ sessionConfig.getX(),
1086
+ sessionConfig.getY(),
1087
+ sessionConfig.getWidth(),
1088
+ sessionConfig.getHeight(),
1089
+ sessionConfig.getPaddingBottom(),
1090
+ sessionConfig.getToBack(),
1091
+ sessionConfig.getStoreToFile(),
1092
+ sessionConfig.getEnableOpacity(),
1093
+ sessionConfig.getEnableZoom(),
1094
+ sessionConfig.getDisableExifHeaderStripping(),
1095
+ sessionConfig.getDisableAudio(),
1096
+ sessionConfig.getZoomFactor(),
1097
+ aspectRatio,
1098
+ sessionConfig.getGridMode()
1099
+ );
1100
+ updateLayoutParams();
1101
+ }
1102
+ }
968
1103
  }
@@ -0,0 +1,80 @@
1
+ package com.ahm.capacitor.camera.preview;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.Canvas;
5
+ import android.graphics.Paint;
6
+ import android.util.AttributeSet;
7
+ import android.view.View;
8
+
9
+ public class GridOverlayView extends View {
10
+ private Paint gridPaint;
11
+ private String gridMode = "none";
12
+
13
+ public GridOverlayView(Context context) {
14
+ super(context);
15
+ init();
16
+ }
17
+
18
+ public GridOverlayView(Context context, AttributeSet attrs) {
19
+ super(context, attrs);
20
+ init();
21
+ }
22
+
23
+ public GridOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
24
+ super(context, attrs, defStyleAttr);
25
+ init();
26
+ }
27
+
28
+ private void init() {
29
+ gridPaint = new Paint();
30
+ gridPaint.setColor(0x80FFFFFF); // Semi-transparent white
31
+ gridPaint.setStrokeWidth(2f);
32
+ gridPaint.setStyle(Paint.Style.STROKE);
33
+ gridPaint.setAntiAlias(true);
34
+ }
35
+
36
+ public void setGridMode(String mode) {
37
+ this.gridMode = mode != null ? mode : "none";
38
+ setVisibility("none".equals(this.gridMode) ? View.GONE : View.VISIBLE);
39
+ invalidate();
40
+ }
41
+
42
+ @Override
43
+ protected void onDraw(Canvas canvas) {
44
+ super.onDraw(canvas);
45
+
46
+ if ("none".equals(gridMode)) {
47
+ return;
48
+ }
49
+
50
+ int width = getWidth();
51
+ int height = getHeight();
52
+
53
+ if (width <= 0 || height <= 0) {
54
+ return;
55
+ }
56
+
57
+ if ("3x3".equals(gridMode)) {
58
+ drawGrid(canvas, width, height, 3);
59
+ } else if ("4x4".equals(gridMode)) {
60
+ drawGrid(canvas, width, height, 4);
61
+ }
62
+ }
63
+
64
+ private void drawGrid(Canvas canvas, int width, int height, int divisions) {
65
+ float stepX = (float) width / divisions;
66
+ float stepY = (float) height / divisions;
67
+
68
+ // Draw vertical lines
69
+ for (int i = 1; i < divisions; i++) {
70
+ float x = i * stepX;
71
+ canvas.drawLine(x, 0, x, height, gridPaint);
72
+ }
73
+
74
+ // Draw horizontal lines
75
+ for (int i = 1; i < divisions; i++) {
76
+ float y = i * stepY;
77
+ canvas.drawLine(0, y, width, y, gridPaint);
78
+ }
79
+ }
80
+ }
@@ -18,12 +18,14 @@ public class CameraSessionConfiguration {
18
18
  private final boolean disableExifHeaderStripping;
19
19
  private final boolean disableAudio;
20
20
  private final float zoomFactor;
21
+ private final String aspectRatio;
22
+ private final String gridMode;
21
23
  private float targetZoom = 1.0f;
22
24
 
23
- public CameraSessionConfiguration(String deviceId, String position, int x, int y, int width, int height,
24
- int paddingBottom, boolean toBack, boolean storeToFile, boolean enableOpacity,
25
- boolean enableZoom, boolean disableExifHeaderStripping, boolean disableAudio,
26
- float zoomFactor) {
25
+ public CameraSessionConfiguration(String deviceId, String position, int x, int y, int width, int height,
26
+ int paddingBottom, boolean toBack, boolean storeToFile, boolean enableOpacity,
27
+ boolean enableZoom, boolean disableExifHeaderStripping, boolean disableAudio,
28
+ float zoomFactor, String aspectRatio, String gridMode) {
27
29
  this.deviceId = deviceId;
28
30
  this.position = position;
29
31
  this.x = x;
@@ -38,6 +40,8 @@ public class CameraSessionConfiguration {
38
40
  this.disableExifHeaderStripping = disableExifHeaderStripping;
39
41
  this.disableAudio = disableAudio;
40
42
  this.zoomFactor = zoomFactor;
43
+ this.aspectRatio = aspectRatio;
44
+ this.gridMode = gridMode != null ? gridMode : "none";
41
45
  }
42
46
 
43
47
  public void setTargetZoom(float zoom) {
@@ -62,4 +66,14 @@ public class CameraSessionConfiguration {
62
66
  public boolean isDisableExifHeaderStripping() { return disableExifHeaderStripping; }
63
67
  public boolean isDisableAudio() { return disableAudio; }
64
68
  public float getZoomFactor() { return zoomFactor; }
65
- }
69
+ public String getAspectRatio() { return aspectRatio; }
70
+ public String getGridMode() { return gridMode; }
71
+
72
+ // Additional getters with "get" prefix for compatibility
73
+ public boolean getToBack() { return toBack; }
74
+ public boolean getStoreToFile() { return storeToFile; }
75
+ public boolean getEnableOpacity() { return enableOpacity; }
76
+ public boolean getEnableZoom() { return enableZoom; }
77
+ public boolean getDisableExifHeaderStripping() { return disableExifHeaderStripping; }
78
+ public boolean getDisableAudio() { return disableAudio; }
79
+ }
package/dist/docs.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "methods": [
8
8
  {
9
9
  "name": "start",
10
- "signature": "(options: CameraPreviewOptions) => Promise<void>",
10
+ "signature": "(options: CameraPreviewOptions) => Promise<{ width: number; height: number; x: number; y: number; }>",
11
11
  "parameters": [
12
12
  {
13
13
  "name": "options",
@@ -15,7 +15,7 @@
15
15
  "type": "CameraPreviewOptions"
16
16
  }
17
17
  ],
18
- "returns": "Promise<void>",
18
+ "returns": "Promise<{ width: number; height: number; x: number; y: number; }>",
19
19
  "tags": [
20
20
  {
21
21
  "name": "param",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  {
25
25
  "name": "returns",
26
- "text": "A promise that resolves when the camera preview is started."
26
+ "text": "A promise that resolves with the preview dimensions."
27
27
  },
28
28
  {
29
29
  "name": "since",
@@ -139,6 +139,54 @@
139
139
  ],
140
140
  "slug": "getsupportedflashmodes"
141
141
  },
142
+ {
143
+ "name": "setAspectRatio",
144
+ "signature": "(options: { aspectRatio: '4:3' | '16:9' | 'fill'; }) => Promise<void>",
145
+ "parameters": [
146
+ {
147
+ "name": "options",
148
+ "docs": "- The desired aspect ratio.",
149
+ "type": "{ aspectRatio: '4:3' | '16:9' | 'fill'; }"
150
+ }
151
+ ],
152
+ "returns": "Promise<void>",
153
+ "tags": [
154
+ {
155
+ "name": "param",
156
+ "text": "options - The desired aspect ratio."
157
+ },
158
+ {
159
+ "name": "returns",
160
+ "text": "A promise that resolves when the aspect ratio is set."
161
+ },
162
+ {
163
+ "name": "since",
164
+ "text": "7.4.0"
165
+ }
166
+ ],
167
+ "docs": "Set the aspect ratio of the camera preview.",
168
+ "complexTypes": [],
169
+ "slug": "setaspectratio"
170
+ },
171
+ {
172
+ "name": "getAspectRatio",
173
+ "signature": "() => Promise<{ aspectRatio: '4:3' | '16:9' | 'fill'; }>",
174
+ "parameters": [],
175
+ "returns": "Promise<{ aspectRatio: '4:3' | '16:9' | 'fill'; }>",
176
+ "tags": [
177
+ {
178
+ "name": "returns",
179
+ "text": "A promise that resolves with the current aspect ratio."
180
+ },
181
+ {
182
+ "name": "since",
183
+ "text": "7.4.0"
184
+ }
185
+ ],
186
+ "docs": "Gets the current aspect ratio of the camera preview.",
187
+ "complexTypes": [],
188
+ "slug": "getaspectratio"
189
+ },
142
190
  {
143
191
  "name": "getHorizontalFov",
144
192
  "signature": "() => Promise<{ result: number; }>",
@@ -567,6 +615,36 @@
567
615
  "complexTypes": [],
568
616
  "type": "number | undefined"
569
617
  },
618
+ {
619
+ "name": "aspectRatio",
620
+ "tags": [
621
+ {
622
+ "text": "2.0.0",
623
+ "name": "since"
624
+ }
625
+ ],
626
+ "docs": "The aspect ratio of the camera preview, '4:3' or '16:9'.\nIf not set, the camera will use the default aspect ratio.",
627
+ "complexTypes": [],
628
+ "type": "'4:3' | '16:9' | 'fill' | undefined"
629
+ },
630
+ {
631
+ "name": "gridMode",
632
+ "tags": [
633
+ {
634
+ "text": "\"none\"",
635
+ "name": "default"
636
+ },
637
+ {
638
+ "text": "2.1.0",
639
+ "name": "since"
640
+ }
641
+ ],
642
+ "docs": "The grid overlay to display on the camera preview.",
643
+ "complexTypes": [
644
+ "GridMode"
645
+ ],
646
+ "type": "GridMode"
647
+ },
570
648
  {
571
649
  "name": "includeSafeAreaInsets",
572
650
  "tags": [
@@ -689,7 +767,7 @@
689
767
  "name": "disableAudio",
690
768
  "tags": [
691
769
  {
692
- "text": "false",
770
+ "text": "true",
693
771
  "name": "default"
694
772
  }
695
773
  ],
@@ -845,6 +923,22 @@
845
923
  "docs": "If true, the captured image will be saved to the user's gallery.",
846
924
  "complexTypes": [],
847
925
  "type": "boolean | undefined"
926
+ },
927
+ {
928
+ "name": "withExifLocation",
929
+ "tags": [
930
+ {
931
+ "text": "false",
932
+ "name": "default"
933
+ },
934
+ {
935
+ "text": "7.6.0",
936
+ "name": "since"
937
+ }
938
+ ],
939
+ "docs": "If true, the plugin will attempt to add GPS location data to the image's EXIF metadata.\nThis may prompt the user for location permissions.",
940
+ "complexTypes": [],
941
+ "type": "boolean | undefined"
848
942
  }
849
943
  ]
850
944
  },
@@ -1144,6 +1238,25 @@
1144
1238
  }
1145
1239
  ],
1146
1240
  "typeAliases": [
1241
+ {
1242
+ "name": "GridMode",
1243
+ "slug": "gridmode",
1244
+ "docs": "",
1245
+ "types": [
1246
+ {
1247
+ "text": "\"none\"",
1248
+ "complexTypes": []
1249
+ },
1250
+ {
1251
+ "text": "\"3x3\"",
1252
+ "complexTypes": []
1253
+ },
1254
+ {
1255
+ "text": "\"4x4\"",
1256
+ "complexTypes": []
1257
+ }
1258
+ ]
1259
+ },
1147
1260
  {
1148
1261
  "name": "CameraPosition",
1149
1262
  "slug": "cameraposition",
@@ -1,5 +1,6 @@
1
1
  export type CameraPosition = "rear" | "front";
2
2
  export type FlashMode = CameraPreviewFlashMode;
3
+ export type GridMode = "none" | "3x3" | "4x4";
3
4
  export declare enum DeviceType {
4
5
  ULTRA_WIDE = "ultraWide",
5
6
  WIDE_ANGLE = "wideAngle",
@@ -92,6 +93,19 @@ export interface CameraPreviewOptions {
92
93
  * @platform android, ios
93
94
  */
94
95
  y?: number;
96
+ /**
97
+ * The aspect ratio of the camera preview, '4:3' or '16:9'.
98
+ * If not set, the camera will use the default aspect ratio.
99
+ *
100
+ * @since 2.0.0
101
+ */
102
+ aspectRatio?: '4:3' | '16:9' | 'fill';
103
+ /**
104
+ * The grid overlay to display on the camera preview.
105
+ * @default "none"
106
+ * @since 2.1.0
107
+ */
108
+ gridMode?: GridMode;
95
109
  /**
96
110
  * Adjusts the y-position to account for safe areas (e.g., notches).
97
111
  * @platform ios
@@ -140,7 +154,7 @@ export interface CameraPreviewOptions {
140
154
  enableHighResolution?: boolean;
141
155
  /**
142
156
  * If true, disables the audio stream, preventing audio permission requests.
143
- * @default false
157
+ * @default true
144
158
  */
145
159
  disableAudio?: boolean;
146
160
  /**
@@ -198,6 +212,13 @@ export interface CameraPreviewPictureOptions {
198
212
  * @since 7.5.0
199
213
  */
200
214
  saveToGallery?: boolean;
215
+ /**
216
+ * If true, the plugin will attempt to add GPS location data to the image's EXIF metadata.
217
+ * This may prompt the user for location permissions.
218
+ * @default false
219
+ * @since 7.6.0
220
+ */
221
+ withExifLocation?: boolean;
201
222
  }
202
223
  /** Represents EXIF data extracted from an image. */
203
224
  export interface ExifData {
@@ -251,10 +272,19 @@ export interface CameraPreviewPlugin {
251
272
  * Starts the camera preview.
252
273
  *
253
274
  * @param {CameraPreviewOptions} options - The configuration for the camera preview.
254
- * @returns {Promise<void>} A promise that resolves when the camera preview is started.
275
+ * @returns {Promise<{ width: number; height: number; x: number; y: number }>} A promise that resolves with the preview dimensions.
255
276
  * @since 0.0.1
256
277
  */
257
- start(options: CameraPreviewOptions): Promise<void>;
278
+ start(options: CameraPreviewOptions): Promise<{
279
+ /** The width of the preview in pixels. */
280
+ width: number;
281
+ /** The height of the preview in pixels. */
282
+ height: number;
283
+ /** The horizontal origin of the preview, in pixels. */
284
+ x: number;
285
+ /** The vertical origin of the preview, in pixels. */
286
+ y: number;
287
+ }>;
258
288
  /**
259
289
  * Stops the camera preview.
260
290
  *
@@ -293,6 +323,25 @@ export interface CameraPreviewPlugin {
293
323
  getSupportedFlashModes(): Promise<{
294
324
  result: CameraPreviewFlashMode[];
295
325
  }>;
326
+ /**
327
+ * Set the aspect ratio of the camera preview.
328
+ *
329
+ * @param {{ aspectRatio: '4:3' | '16:9' | 'fill' }} options - The desired aspect ratio.
330
+ * @returns {Promise<void>} A promise that resolves when the aspect ratio is set.
331
+ * @since 7.4.0
332
+ */
333
+ setAspectRatio(options: {
334
+ aspectRatio: '4:3' | '16:9' | 'fill';
335
+ }): Promise<void>;
336
+ /**
337
+ * Gets the current aspect ratio of the camera preview.
338
+ *
339
+ * @returns {Promise<{ aspectRatio: '4:3' | '16:9' | 'fill' }>} A promise that resolves with the current aspect ratio.
340
+ * @since 7.4.0
341
+ */
342
+ getAspectRatio(): Promise<{
343
+ aspectRatio: '4:3' | '16:9' | 'fill';
344
+ }>;
296
345
  /**
297
346
  * Gets the horizontal field of view (FoV) for the active camera.
298
347
  * Note: This can be an estimate on some devices.