@capgo/camera-preview 7.4.0-beta.12 → 7.4.0-beta.15
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/README.md +28 -10
- package/android/.gradle/8.14.2/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.14.2/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.14.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/file-system.probe +0 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +200 -15
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +770 -98
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraSessionConfiguration.java +9 -0
- package/dist/docs.json +56 -23
- package/dist/esm/definitions.d.ts +26 -10
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +5 -0
- package/dist/esm/web.js +256 -34
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +256 -34
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +256 -34
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapgoCameraPreview/CameraController.swift +418 -66
- package/ios/Sources/CapgoCameraPreview/Plugin.swift +69 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -241,6 +241,7 @@ Documentation for the [uploader](https://github.com/Cap-go/capacitor-uploader)
|
|
|
241
241
|
* [`getDeviceId()`](#getdeviceid)
|
|
242
242
|
* [`getPreviewSize()`](#getpreviewsize)
|
|
243
243
|
* [`setPreviewSize(...)`](#setpreviewsize)
|
|
244
|
+
* [`setFocus(...)`](#setfocus)
|
|
244
245
|
* [Interfaces](#interfaces)
|
|
245
246
|
* [Type Aliases](#type-aliases)
|
|
246
247
|
* [Enums](#enums)
|
|
@@ -561,14 +562,14 @@ Gets the current zoom state, including min/max and current lens info.
|
|
|
561
562
|
### setZoom(...)
|
|
562
563
|
|
|
563
564
|
```typescript
|
|
564
|
-
setZoom(options: { level: number; ramp?: boolean; }) => Promise<void>
|
|
565
|
+
setZoom(options: { level: number; ramp?: boolean; autoFocus?: boolean; }) => Promise<void>
|
|
565
566
|
```
|
|
566
567
|
|
|
567
|
-
Sets the
|
|
568
|
+
Sets the zoom level of the camera.
|
|
568
569
|
|
|
569
|
-
| Param | Type
|
|
570
|
-
| ------------- |
|
|
571
|
-
| **`options`** | <code>{ level: number; ramp?: boolean; }</code> | - The desired zoom level. `ramp` is currently unused. |
|
|
570
|
+
| Param | Type | Description |
|
|
571
|
+
| ------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
572
|
+
| **`options`** | <code>{ level: number; ramp?: boolean; autoFocus?: boolean; }</code> | - The desired zoom level. `ramp` is currently unused. `autoFocus` defaults to true. |
|
|
572
573
|
|
|
573
574
|
**Since:** 7.4.0
|
|
574
575
|
|
|
@@ -651,20 +652,37 @@ Gets the current preview size and position.
|
|
|
651
652
|
### setPreviewSize(...)
|
|
652
653
|
|
|
653
654
|
```typescript
|
|
654
|
-
setPreviewSize(options: { x
|
|
655
|
+
setPreviewSize(options: { x?: number; y?: number; width: number; height: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>
|
|
655
656
|
```
|
|
656
657
|
|
|
657
658
|
Sets the preview size and position.
|
|
658
659
|
|
|
659
|
-
| Param | Type
|
|
660
|
-
| ------------- |
|
|
661
|
-
| **`options`** | <code>{ x
|
|
660
|
+
| Param | Type | Description |
|
|
661
|
+
| ------------- | ----------------------------------------------------------------------- | -------------------------------- |
|
|
662
|
+
| **`options`** | <code>{ x?: number; y?: number; width: number; height: number; }</code> | The new position and dimensions. |
|
|
662
663
|
|
|
663
664
|
**Returns:** <code>Promise<{ width: number; height: number; x: number; y: number; }></code>
|
|
664
665
|
|
|
665
666
|
--------------------
|
|
666
667
|
|
|
667
668
|
|
|
669
|
+
### setFocus(...)
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
setFocus(options: { x: number; y: number; }) => Promise<void>
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
Sets the camera focus to a specific point in the preview.
|
|
676
|
+
|
|
677
|
+
| Param | Type | Description |
|
|
678
|
+
| ------------- | -------------------------------------- | -------------------- |
|
|
679
|
+
| **`options`** | <code>{ x: number; y: number; }</code> | - The focus options. |
|
|
680
|
+
|
|
681
|
+
**Since:** 8.1.0
|
|
682
|
+
|
|
683
|
+
--------------------
|
|
684
|
+
|
|
685
|
+
|
|
668
686
|
### Interfaces
|
|
669
687
|
|
|
670
688
|
|
|
@@ -689,13 +707,13 @@ Defines the configuration options for starting the camera preview.
|
|
|
689
707
|
| **`position`** | <code>string</code> | The camera to use. | <code>"rear"</code> | |
|
|
690
708
|
| **`storeToFile`** | <code>boolean</code> | If true, saves the captured image to a file and returns the file path. If false, returns a base64 encoded string. | <code>false</code> | |
|
|
691
709
|
| **`disableExifHeaderStripping`** | <code>boolean</code> | If true, prevents the plugin from rotating the image based on EXIF data. | <code>false</code> | |
|
|
692
|
-
| **`enableHighResolution`** | <code>boolean</code> | If true, enables high-resolution image capture. | <code>false</code> | |
|
|
693
710
|
| **`disableAudio`** | <code>boolean</code> | If true, disables the audio stream, preventing audio permission requests. | <code>true</code> | |
|
|
694
711
|
| **`lockAndroidOrientation`** | <code>boolean</code> | If true, locks the device orientation while the camera is active. | <code>false</code> | |
|
|
695
712
|
| **`enableOpacity`** | <code>boolean</code> | If true, allows the camera preview's opacity to be changed. | <code>false</code> | |
|
|
696
713
|
| **`enableZoom`** | <code>boolean</code> | If true, enables pinch-to-zoom functionality on the preview. | <code>false</code> | |
|
|
697
714
|
| **`enableVideoMode`** | <code>boolean</code> | If true, uses the video-optimized preset for the camera session. | <code>false</code> | |
|
|
698
715
|
| **`deviceId`** | <code>string</code> | The `deviceId` of the camera to use. If provided, `position` is ignored. | | |
|
|
716
|
+
| **`initialZoomLevel`** | <code>number</code> | The initial zoom level when starting the camera preview. If the requested zoom level is not available, the native plugin will reject. | <code>1.0</code> | 2.2.0 |
|
|
699
717
|
|
|
700
718
|
|
|
701
719
|
#### ExifData
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -10,6 +10,7 @@ import android.util.DisplayMetrics;
|
|
|
10
10
|
import android.util.Log;
|
|
11
11
|
import android.util.Size;
|
|
12
12
|
import android.view.ViewGroup;
|
|
13
|
+
import android.webkit.WebView;
|
|
13
14
|
import com.ahm.capacitor.camera.preview.model.CameraDevice;
|
|
14
15
|
import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
|
|
15
16
|
import com.ahm.capacitor.camera.preview.model.LensInfo;
|
|
@@ -277,14 +278,44 @@ public class CameraPreview
|
|
|
277
278
|
call.reject("level parameter is required");
|
|
278
279
|
return;
|
|
279
280
|
}
|
|
281
|
+
Boolean autoFocus = call.getBoolean("autoFocus", true);
|
|
280
282
|
try {
|
|
281
|
-
cameraXView.setZoom(level);
|
|
283
|
+
cameraXView.setZoom(level, autoFocus);
|
|
282
284
|
call.resolve();
|
|
283
285
|
} catch (Exception e) {
|
|
284
286
|
call.reject("Failed to set zoom: " + e.getMessage());
|
|
285
287
|
}
|
|
286
288
|
}
|
|
287
289
|
|
|
290
|
+
@PluginMethod
|
|
291
|
+
public void setFocus(PluginCall call) {
|
|
292
|
+
if (cameraXView == null || !cameraXView.isRunning()) {
|
|
293
|
+
call.reject("Camera is not running");
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
Float x = call.getFloat("x");
|
|
297
|
+
Float y = call.getFloat("y");
|
|
298
|
+
if (x == null || y == null) {
|
|
299
|
+
call.reject("x and y parameters are required");
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// Reject if values are outside 0-1 range
|
|
303
|
+
if (x < 0f || x > 1f || y < 0f || y > 1f) {
|
|
304
|
+
call.reject("Focus coordinates must be between 0 and 1");
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getActivity()
|
|
309
|
+
.runOnUiThread(() -> {
|
|
310
|
+
try {
|
|
311
|
+
cameraXView.setFocus(x, y);
|
|
312
|
+
call.resolve();
|
|
313
|
+
} catch (Exception e) {
|
|
314
|
+
call.reject("Failed to set focus: " + e.getMessage());
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
288
319
|
@PluginMethod
|
|
289
320
|
public void setDeviceId(PluginCall call) {
|
|
290
321
|
String deviceId = call.getString("deviceId");
|
|
@@ -412,8 +443,30 @@ public class CameraPreview
|
|
|
412
443
|
"back".equals(positionParam))
|
|
413
444
|
? "back"
|
|
414
445
|
: "front";
|
|
415
|
-
|
|
416
|
-
final
|
|
446
|
+
// Use -1 as default to indicate centering is needed when x/y not provided
|
|
447
|
+
final Integer xParam = call.getInt("x");
|
|
448
|
+
final Integer yParam = call.getInt("y");
|
|
449
|
+
final int x = xParam != null ? xParam : -1;
|
|
450
|
+
final int y = yParam != null ? yParam : -1;
|
|
451
|
+
|
|
452
|
+
Log.d("CameraPreview", "========================");
|
|
453
|
+
Log.d("CameraPreview", "CAMERA POSITION TRACKING START:");
|
|
454
|
+
Log.d(
|
|
455
|
+
"CameraPreview",
|
|
456
|
+
"1. RAW PARAMS - xParam: " + xParam + ", yParam: " + yParam
|
|
457
|
+
);
|
|
458
|
+
Log.d(
|
|
459
|
+
"CameraPreview",
|
|
460
|
+
"2. AFTER DEFAULT - x: " +
|
|
461
|
+
x +
|
|
462
|
+
" (center=" +
|
|
463
|
+
(x == -1) +
|
|
464
|
+
"), y: " +
|
|
465
|
+
y +
|
|
466
|
+
" (center=" +
|
|
467
|
+
(y == -1) +
|
|
468
|
+
")"
|
|
469
|
+
);
|
|
417
470
|
final int width = call.getInt("width", 0);
|
|
418
471
|
final int height = call.getInt("height", 0);
|
|
419
472
|
final int paddingBottom = call.getInt("paddingBottom", 0);
|
|
@@ -438,6 +491,7 @@ public class CameraPreview
|
|
|
438
491
|
);
|
|
439
492
|
final String aspectRatio = call.getString("aspectRatio", "4:3");
|
|
440
493
|
final String gridMode = call.getString("gridMode", "none");
|
|
494
|
+
final float initialZoomLevel = call.getFloat("initialZoomLevel", 1.0f);
|
|
441
495
|
|
|
442
496
|
// Check for conflict between aspectRatio and size
|
|
443
497
|
if (
|
|
@@ -450,7 +504,7 @@ public class CameraPreview
|
|
|
450
504
|
return;
|
|
451
505
|
}
|
|
452
506
|
|
|
453
|
-
float targetZoom =
|
|
507
|
+
float targetZoom = initialZoomLevel;
|
|
454
508
|
// Check if the selected device is a physical ultra-wide
|
|
455
509
|
if (originalDeviceId != null) {
|
|
456
510
|
List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
|
|
@@ -521,10 +575,84 @@ public class CameraPreview
|
|
|
521
575
|
// Calculate pixel ratio
|
|
522
576
|
float pixelRatio = metrics.density;
|
|
523
577
|
|
|
524
|
-
//
|
|
525
|
-
int computedX
|
|
526
|
-
int computedY
|
|
578
|
+
// Calculate position - center if x or y is -1
|
|
579
|
+
int computedX;
|
|
580
|
+
int computedY;
|
|
581
|
+
|
|
582
|
+
// Calculate dimensions first
|
|
583
|
+
int computedWidth = width != 0
|
|
584
|
+
? (int) (width * pixelRatio)
|
|
585
|
+
: getBridge().getWebView().getWidth();
|
|
586
|
+
int computedHeight = height != 0
|
|
587
|
+
? (int) (height * pixelRatio)
|
|
588
|
+
: getBridge().getWebView().getHeight();
|
|
589
|
+
computedHeight -= (int) (paddingBottom * pixelRatio);
|
|
527
590
|
|
|
591
|
+
Log.d("CameraPreview", "Positioning logic - x: " + x + ", y: " + y);
|
|
592
|
+
|
|
593
|
+
if (x == -1) {
|
|
594
|
+
// Center horizontally
|
|
595
|
+
int screenWidth = metrics.widthPixels;
|
|
596
|
+
computedX = (screenWidth - computedWidth) / 2;
|
|
597
|
+
Log.d(
|
|
598
|
+
"CameraPreview",
|
|
599
|
+
"Centering horizontally: screenWidth=" +
|
|
600
|
+
screenWidth +
|
|
601
|
+
", computedWidth=" +
|
|
602
|
+
computedWidth +
|
|
603
|
+
", computedX=" +
|
|
604
|
+
computedX
|
|
605
|
+
);
|
|
606
|
+
} else {
|
|
607
|
+
computedX = (int) (x * pixelRatio);
|
|
608
|
+
Log.d(
|
|
609
|
+
"CameraPreview",
|
|
610
|
+
"Using provided X position: " +
|
|
611
|
+
x +
|
|
612
|
+
" * " +
|
|
613
|
+
pixelRatio +
|
|
614
|
+
" = " +
|
|
615
|
+
computedX
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (y == -1) {
|
|
620
|
+
// Center vertically using full screen height
|
|
621
|
+
int screenHeight = metrics.heightPixels;
|
|
622
|
+
computedY = (screenHeight - computedHeight) / 2;
|
|
623
|
+
Log.d(
|
|
624
|
+
"CameraPreview",
|
|
625
|
+
"Centering vertically: screenHeight=" +
|
|
626
|
+
screenHeight +
|
|
627
|
+
", computedHeight=" +
|
|
628
|
+
computedHeight +
|
|
629
|
+
", computedY=" +
|
|
630
|
+
computedY
|
|
631
|
+
);
|
|
632
|
+
} else {
|
|
633
|
+
computedY = (int) (y * pixelRatio);
|
|
634
|
+
Log.d(
|
|
635
|
+
"CameraPreview",
|
|
636
|
+
"Using provided Y position: " +
|
|
637
|
+
y +
|
|
638
|
+
" * " +
|
|
639
|
+
pixelRatio +
|
|
640
|
+
" = " +
|
|
641
|
+
computedY
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
Log.d(
|
|
646
|
+
"CameraPreview",
|
|
647
|
+
"3. COMPUTED POSITION - x=" + computedX + ", y=" + computedY
|
|
648
|
+
);
|
|
649
|
+
Log.d(
|
|
650
|
+
"CameraPreview",
|
|
651
|
+
"4. COMPUTED SIZE - width=" +
|
|
652
|
+
computedWidth +
|
|
653
|
+
", height=" +
|
|
654
|
+
computedHeight
|
|
655
|
+
);
|
|
528
656
|
Log.d("CameraPreview", "=== COORDINATE DEBUG ===");
|
|
529
657
|
Log.d(
|
|
530
658
|
"CameraPreview",
|
|
@@ -579,14 +707,11 @@ public class CameraPreview
|
|
|
579
707
|
computedY +
|
|
580
708
|
")"
|
|
581
709
|
);
|
|
710
|
+
Log.d("CameraPreview", "5. IS_CENTERED - " + (x == -1 || y == -1));
|
|
582
711
|
Log.d("CameraPreview", "========================");
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
int computedHeight = height != 0
|
|
587
|
-
? (int) (height * pixelRatio)
|
|
588
|
-
: getBridge().getWebView().getHeight();
|
|
589
|
-
computedHeight -= (int) (paddingBottom * pixelRatio);
|
|
712
|
+
|
|
713
|
+
// Pass along whether we're centering so CameraXView knows not to add insets
|
|
714
|
+
boolean isCentered = (x == -1 || y == -1);
|
|
590
715
|
|
|
591
716
|
CameraSessionConfiguration config = new CameraSessionConfiguration(
|
|
592
717
|
finalDeviceId,
|
|
@@ -607,6 +732,7 @@ public class CameraPreview
|
|
|
607
732
|
gridMode
|
|
608
733
|
);
|
|
609
734
|
config.setTargetZoom(finalTargetZoom);
|
|
735
|
+
config.setCentered(isCentered);
|
|
610
736
|
|
|
611
737
|
bridge.saveCall(call);
|
|
612
738
|
cameraStartCallbackId = call.getCallbackId();
|
|
@@ -650,11 +776,70 @@ public class CameraPreview
|
|
|
650
776
|
.getDisplayMetrics();
|
|
651
777
|
float pixelRatio = metrics.density;
|
|
652
778
|
|
|
779
|
+
// Check if edge-to-edge mode is active by looking at WebView insets
|
|
780
|
+
// If the WebView has a top margin, it means edge-to-edge is active
|
|
781
|
+
// and JavaScript positions are relative to WebView content area
|
|
782
|
+
int webViewTopInset = 0;
|
|
783
|
+
boolean isEdgeToEdgeActive = false;
|
|
784
|
+
WebView webView = getBridge().getWebView();
|
|
785
|
+
if (
|
|
786
|
+
webView != null &&
|
|
787
|
+
webView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams
|
|
788
|
+
) {
|
|
789
|
+
webViewTopInset =
|
|
790
|
+
((ViewGroup.MarginLayoutParams) webView.getLayoutParams()).topMargin;
|
|
791
|
+
isEdgeToEdgeActive = webViewTopInset > 0;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Only convert to relative position if edge-to-edge is active
|
|
795
|
+
int relativeY = isEdgeToEdgeActive ? (y - webViewTopInset) : y;
|
|
796
|
+
|
|
797
|
+
Log.d("CameraPreview", "========================");
|
|
798
|
+
Log.d("CameraPreview", "CAMERA STARTED - POSITION RETURNED:");
|
|
799
|
+
Log.d(
|
|
800
|
+
"CameraPreview",
|
|
801
|
+
"7. RETURNED (pixels) - x=" +
|
|
802
|
+
x +
|
|
803
|
+
", y=" +
|
|
804
|
+
y +
|
|
805
|
+
", width=" +
|
|
806
|
+
width +
|
|
807
|
+
", height=" +
|
|
808
|
+
height
|
|
809
|
+
);
|
|
810
|
+
Log.d(
|
|
811
|
+
"CameraPreview",
|
|
812
|
+
"8. EDGE-TO-EDGE - " + (isEdgeToEdgeActive ? "ACTIVE" : "INACTIVE")
|
|
813
|
+
);
|
|
814
|
+
Log.d("CameraPreview", "9. WEBVIEW INSET - " + webViewTopInset);
|
|
815
|
+
Log.d(
|
|
816
|
+
"CameraPreview",
|
|
817
|
+
"10. RELATIVE Y - " +
|
|
818
|
+
relativeY +
|
|
819
|
+
" (y=" +
|
|
820
|
+
y +
|
|
821
|
+
(isEdgeToEdgeActive ? " - inset=" + webViewTopInset : " unchanged") +
|
|
822
|
+
")"
|
|
823
|
+
);
|
|
824
|
+
Log.d(
|
|
825
|
+
"CameraPreview",
|
|
826
|
+
"11. RETURNED (logical) - x=" +
|
|
827
|
+
(x / pixelRatio) +
|
|
828
|
+
", y=" +
|
|
829
|
+
(relativeY / pixelRatio) +
|
|
830
|
+
", width=" +
|
|
831
|
+
(width / pixelRatio) +
|
|
832
|
+
", height=" +
|
|
833
|
+
(height / pixelRatio)
|
|
834
|
+
);
|
|
835
|
+
Log.d("CameraPreview", "12. PIXEL RATIO - " + pixelRatio);
|
|
836
|
+
Log.d("CameraPreview", "========================");
|
|
837
|
+
|
|
653
838
|
JSObject result = new JSObject();
|
|
654
839
|
result.put("width", width / pixelRatio);
|
|
655
840
|
result.put("height", height / pixelRatio);
|
|
656
841
|
result.put("x", x / pixelRatio);
|
|
657
|
-
result.put("y",
|
|
842
|
+
result.put("y", relativeY / pixelRatio);
|
|
658
843
|
call.resolve(result);
|
|
659
844
|
bridge.releaseCall(call);
|
|
660
845
|
cameraStartCallbackId = null; // Prevent re-use
|