@capgo/camera-preview 7.4.0-beta.10 → 7.4.0-beta.11
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 +3 -3
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +281 -133
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +2028 -1467
- package/android/src/main/java/com/ahm/capacitor/camera/preview/GridOverlayView.java +71 -58
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraDevice.java +55 -46
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraLens.java +61 -52
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraSessionConfiguration.java +151 -72
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/LensInfo.java +29 -23
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/ZoomFactors.java +24 -23
- package/dist/docs.json +3 -3
- package/dist/esm/definitions.d.ts +3 -3
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -2
- package/dist/esm/web.js +51 -34
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +51 -34
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +51 -34
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapgoCameraPreview/CameraController.swift +202 -273
- package/ios/Sources/CapgoCameraPreview/Plugin.swift +467 -390
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -340,7 +340,7 @@ Gets the flash modes supported by the active camera.
|
|
|
340
340
|
### setAspectRatio(...)
|
|
341
341
|
|
|
342
342
|
```typescript
|
|
343
|
-
setAspectRatio(options: { aspectRatio:
|
|
343
|
+
setAspectRatio(options: { aspectRatio: "4:3" | "16:9"; x?: number; y?: number; }) => Promise<{ width: number; height: number; x: number; y: number; }>
|
|
344
344
|
```
|
|
345
345
|
|
|
346
346
|
Set the aspect ratio of the camera preview.
|
|
@@ -359,7 +359,7 @@ Set the aspect ratio of the camera preview.
|
|
|
359
359
|
### getAspectRatio()
|
|
360
360
|
|
|
361
361
|
```typescript
|
|
362
|
-
getAspectRatio() => Promise<{ aspectRatio:
|
|
362
|
+
getAspectRatio() => Promise<{ aspectRatio: "4:3" | "16:9"; }>
|
|
363
363
|
```
|
|
364
364
|
|
|
365
365
|
Gets the current aspect ratio of the camera preview.
|
|
@@ -680,7 +680,7 @@ Defines the configuration options for starting the camera preview.
|
|
|
680
680
|
| **`height`** | <code>number</code> | The height of the preview in pixels. Defaults to the screen height. | | |
|
|
681
681
|
| **`x`** | <code>number</code> | The horizontal origin of the preview, in pixels. | | |
|
|
682
682
|
| **`y`** | <code>number</code> | The vertical origin of the preview, in pixels. | | |
|
|
683
|
-
| **`aspectRatio`** | <code>'4:3' \| '16:9'
|
|
683
|
+
| **`aspectRatio`** | <code>'4:3' \| '16:9'</code> | The aspect ratio of the camera preview, '4:3' or '16:9' or 'fill'. Cannot be set if width or height is provided, otherwise the call will be rejected. Use setPreviewSize to adjust size after starting. | | 2.0.0 |
|
|
684
684
|
| **`gridMode`** | <code><a href="#gridmode">GridMode</a></code> | The grid overlay to display on the camera preview. | <code>"none"</code> | 2.1.0 |
|
|
685
685
|
| **`includeSafeAreaInsets`** | <code>boolean</code> | Adjusts the y-position to account for safe areas (e.g., notches). | <code>false</code> | |
|
|
686
686
|
| **`toBack`** | <code>boolean</code> | If true, places the preview behind the webview. | <code>true</code> | |
|
|
@@ -5,9 +5,18 @@ import static android.Manifest.permission.RECORD_AUDIO;
|
|
|
5
5
|
|
|
6
6
|
import android.Manifest;
|
|
7
7
|
import android.content.pm.ActivityInfo;
|
|
8
|
+
import android.location.Location;
|
|
8
9
|
import android.util.DisplayMetrics;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
import android.util.Size;
|
|
12
|
+
import android.view.ViewGroup;
|
|
13
|
+
import com.ahm.capacitor.camera.preview.model.CameraDevice;
|
|
14
|
+
import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
|
|
15
|
+
import com.ahm.capacitor.camera.preview.model.LensInfo;
|
|
16
|
+
import com.ahm.capacitor.camera.preview.model.ZoomFactors;
|
|
9
17
|
import com.getcapacitor.JSArray;
|
|
10
18
|
import com.getcapacitor.JSObject;
|
|
19
|
+
import com.getcapacitor.Logger;
|
|
11
20
|
import com.getcapacitor.PermissionState;
|
|
12
21
|
import com.getcapacitor.Plugin;
|
|
13
22
|
import com.getcapacitor.PluginCall;
|
|
@@ -15,22 +24,11 @@ import com.getcapacitor.PluginMethod;
|
|
|
15
24
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
16
25
|
import com.getcapacitor.annotation.Permission;
|
|
17
26
|
import com.getcapacitor.annotation.PermissionCallback;
|
|
18
|
-
import com.ahm.capacitor.camera.preview.model.CameraDevice;
|
|
19
|
-
import com.ahm.capacitor.camera.preview.model.CameraSessionConfiguration;
|
|
20
|
-
import com.ahm.capacitor.camera.preview.model.ZoomFactors;
|
|
21
|
-
import java.util.List;
|
|
22
|
-
import java.util.Objects;
|
|
23
|
-
import android.util.Size;
|
|
24
|
-
import android.util.Log;
|
|
25
|
-
import com.ahm.capacitor.camera.preview.model.LensInfo;
|
|
26
27
|
import com.google.android.gms.location.FusedLocationProviderClient;
|
|
27
28
|
import com.google.android.gms.location.LocationServices;
|
|
29
|
+
import java.util.List;
|
|
30
|
+
import java.util.Objects;
|
|
28
31
|
import org.json.JSONObject;
|
|
29
|
-
import android.location.Location;
|
|
30
|
-
import android.view.ViewGroup;
|
|
31
|
-
|
|
32
|
-
import com.getcapacitor.Logger;
|
|
33
|
-
|
|
34
32
|
|
|
35
33
|
@CapacitorPlugin(
|
|
36
34
|
name = "CameraPreview",
|
|
@@ -44,9 +42,12 @@ import com.getcapacitor.Logger;
|
|
|
44
42
|
alias = CameraPreview.CAMERA_ONLY_PERMISSION_ALIAS
|
|
45
43
|
),
|
|
46
44
|
@Permission(
|
|
47
|
-
strings = {
|
|
45
|
+
strings = {
|
|
46
|
+
Manifest.permission.ACCESS_COARSE_LOCATION,
|
|
47
|
+
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
48
|
+
},
|
|
48
49
|
alias = CameraPreview.CAMERA_WITH_LOCATION_PERMISSION_ALIAS
|
|
49
|
-
)
|
|
50
|
+
),
|
|
50
51
|
}
|
|
51
52
|
)
|
|
52
53
|
public class CameraPreview
|
|
@@ -55,19 +56,23 @@ public class CameraPreview
|
|
|
55
56
|
|
|
56
57
|
static final String CAMERA_WITH_AUDIO_PERMISSION_ALIAS = "cameraWithAudio";
|
|
57
58
|
static final String CAMERA_ONLY_PERMISSION_ALIAS = "cameraOnly";
|
|
58
|
-
static final String CAMERA_WITH_LOCATION_PERMISSION_ALIAS =
|
|
59
|
+
static final String CAMERA_WITH_LOCATION_PERMISSION_ALIAS =
|
|
60
|
+
"cameraWithLocation";
|
|
59
61
|
|
|
60
62
|
private String captureCallbackId = "";
|
|
61
63
|
private String snapshotCallbackId = "";
|
|
62
64
|
private String cameraStartCallbackId = "";
|
|
63
|
-
private int previousOrientationRequest =
|
|
65
|
+
private int previousOrientationRequest =
|
|
66
|
+
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
|
64
67
|
private CameraXView cameraXView;
|
|
65
68
|
private FusedLocationProviderClient fusedLocationClient;
|
|
66
69
|
private Location lastLocation;
|
|
67
70
|
|
|
68
71
|
@PluginMethod
|
|
69
72
|
public void start(PluginCall call) {
|
|
70
|
-
boolean disableAudio = Boolean.TRUE.equals(
|
|
73
|
+
boolean disableAudio = Boolean.TRUE.equals(
|
|
74
|
+
call.getBoolean("disableAudio", true)
|
|
75
|
+
);
|
|
71
76
|
String permissionAlias = disableAudio
|
|
72
77
|
? CAMERA_ONLY_PERMISSION_ALIAS
|
|
73
78
|
: CAMERA_WITH_AUDIO_PERMISSION_ALIAS;
|
|
@@ -103,8 +108,15 @@ public class CameraPreview
|
|
|
103
108
|
final boolean withExifLocation = call.getBoolean("withExifLocation", false);
|
|
104
109
|
|
|
105
110
|
if (withExifLocation) {
|
|
106
|
-
if (
|
|
107
|
-
|
|
111
|
+
if (
|
|
112
|
+
getPermissionState(CAMERA_WITH_LOCATION_PERMISSION_ALIAS) !=
|
|
113
|
+
PermissionState.GRANTED
|
|
114
|
+
) {
|
|
115
|
+
requestPermissionForAlias(
|
|
116
|
+
CAMERA_WITH_LOCATION_PERMISSION_ALIAS,
|
|
117
|
+
call,
|
|
118
|
+
"captureWithLocationPermission"
|
|
119
|
+
);
|
|
108
120
|
} else {
|
|
109
121
|
getLocationAndCapture(call);
|
|
110
122
|
}
|
|
@@ -115,22 +127,32 @@ public class CameraPreview
|
|
|
115
127
|
|
|
116
128
|
@PermissionCallback
|
|
117
129
|
private void captureWithLocationPermission(PluginCall call) {
|
|
118
|
-
if (
|
|
130
|
+
if (
|
|
131
|
+
getPermissionState(CAMERA_WITH_LOCATION_PERMISSION_ALIAS) ==
|
|
132
|
+
PermissionState.GRANTED
|
|
133
|
+
) {
|
|
119
134
|
getLocationAndCapture(call);
|
|
120
135
|
} else {
|
|
121
|
-
Logger.warn(
|
|
136
|
+
Logger.warn(
|
|
137
|
+
"Location permission denied. Capturing photo without location data."
|
|
138
|
+
);
|
|
122
139
|
captureWithoutLocation(call);
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
|
|
126
143
|
private void getLocationAndCapture(PluginCall call) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
if (fusedLocationClient == null) {
|
|
145
|
+
fusedLocationClient = LocationServices.getFusedLocationProviderClient(
|
|
146
|
+
getContext()
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
fusedLocationClient
|
|
150
|
+
.getLastLocation()
|
|
151
|
+
.addOnSuccessListener(getActivity(), location -> {
|
|
131
152
|
lastLocation = location;
|
|
132
153
|
proceedWithCapture(call, lastLocation);
|
|
133
|
-
})
|
|
154
|
+
})
|
|
155
|
+
.addOnFailureListener(e -> {
|
|
134
156
|
Logger.error("Failed to get location: " + e.getMessage());
|
|
135
157
|
proceedWithCapture(call, null);
|
|
136
158
|
});
|
|
@@ -168,19 +190,17 @@ public class CameraPreview
|
|
|
168
190
|
public void stop(final PluginCall call) {
|
|
169
191
|
bridge
|
|
170
192
|
.getActivity()
|
|
171
|
-
.runOnUiThread(
|
|
172
|
-
()
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
cameraXView = null;
|
|
180
|
-
}
|
|
181
|
-
call.resolve();
|
|
193
|
+
.runOnUiThread(() -> {
|
|
194
|
+
getBridge()
|
|
195
|
+
.getActivity()
|
|
196
|
+
.setRequestedOrientation(previousOrientationRequest);
|
|
197
|
+
|
|
198
|
+
if (cameraXView != null && cameraXView.isRunning()) {
|
|
199
|
+
cameraXView.stopSession();
|
|
200
|
+
cameraXView = null;
|
|
182
201
|
}
|
|
183
|
-
|
|
202
|
+
call.resolve();
|
|
203
|
+
});
|
|
184
204
|
}
|
|
185
205
|
|
|
186
206
|
@PluginMethod
|
|
@@ -208,7 +228,9 @@ public class CameraPreview
|
|
|
208
228
|
|
|
209
229
|
@PluginMethod
|
|
210
230
|
public void getAvailableDevices(PluginCall call) {
|
|
211
|
-
List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
|
|
231
|
+
List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
|
|
232
|
+
getContext()
|
|
233
|
+
);
|
|
212
234
|
JSArray devicesArray = new JSArray();
|
|
213
235
|
for (CameraDevice device : devices) {
|
|
214
236
|
JSObject deviceJson = new JSObject();
|
|
@@ -285,7 +307,7 @@ public class CameraPreview
|
|
|
285
307
|
JSObject rear = new JSObject();
|
|
286
308
|
rear.put("facing", "rear");
|
|
287
309
|
JSArray rearSizesJs = new JSArray();
|
|
288
|
-
for(Size size : rearSizes) {
|
|
310
|
+
for (Size size : rearSizes) {
|
|
289
311
|
JSObject sizeJs = new JSObject();
|
|
290
312
|
sizeJs.put("width", size.getWidth());
|
|
291
313
|
sizeJs.put("height", size.getHeight());
|
|
@@ -298,7 +320,7 @@ public class CameraPreview
|
|
|
298
320
|
JSObject front = new JSObject();
|
|
299
321
|
front.put("facing", "front");
|
|
300
322
|
JSArray frontSizesJs = new JSArray();
|
|
301
|
-
for(Size size : frontSizes) {
|
|
323
|
+
for (Size size : frontSizes) {
|
|
302
324
|
JSObject sizeJs = new JSObject();
|
|
303
325
|
sizeJs.put("width", size.getWidth());
|
|
304
326
|
sizeJs.put("height", size.getHeight());
|
|
@@ -365,8 +387,14 @@ public class CameraPreview
|
|
|
365
387
|
|
|
366
388
|
@PermissionCallback
|
|
367
389
|
private void handleCameraPermissionResult(PluginCall call) {
|
|
368
|
-
if (
|
|
369
|
-
|
|
390
|
+
if (
|
|
391
|
+
PermissionState.GRANTED.equals(
|
|
392
|
+
getPermissionState(CAMERA_ONLY_PERMISSION_ALIAS)
|
|
393
|
+
) ||
|
|
394
|
+
PermissionState.GRANTED.equals(
|
|
395
|
+
getPermissionState(CAMERA_WITH_AUDIO_PERMISSION_ALIAS)
|
|
396
|
+
)
|
|
397
|
+
) {
|
|
370
398
|
startCamera(call);
|
|
371
399
|
} else {
|
|
372
400
|
call.reject("Permission failed");
|
|
@@ -378,108 +406,212 @@ public class CameraPreview
|
|
|
378
406
|
String originalDeviceId = call.getString("deviceId");
|
|
379
407
|
String deviceId = originalDeviceId; // Use a mutable variable
|
|
380
408
|
|
|
381
|
-
final String position = (positionParam == null ||
|
|
409
|
+
final String position = (positionParam == null ||
|
|
410
|
+
positionParam.isEmpty() ||
|
|
411
|
+
"rear".equals(positionParam) ||
|
|
412
|
+
"back".equals(positionParam))
|
|
413
|
+
? "back"
|
|
414
|
+
: "front";
|
|
382
415
|
final int x = call.getInt("x", 0);
|
|
383
416
|
final int y = call.getInt("y", 0);
|
|
384
417
|
final int width = call.getInt("width", 0);
|
|
385
418
|
final int height = call.getInt("height", 0);
|
|
386
419
|
final int paddingBottom = call.getInt("paddingBottom", 0);
|
|
387
420
|
final boolean toBack = Boolean.TRUE.equals(call.getBoolean("toBack", true));
|
|
388
|
-
final boolean storeToFile = Boolean.TRUE.equals(
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
final boolean
|
|
392
|
-
|
|
393
|
-
|
|
421
|
+
final boolean storeToFile = Boolean.TRUE.equals(
|
|
422
|
+
call.getBoolean("storeToFile", false)
|
|
423
|
+
);
|
|
424
|
+
final boolean enableOpacity = Boolean.TRUE.equals(
|
|
425
|
+
call.getBoolean("enableOpacity", false)
|
|
426
|
+
);
|
|
427
|
+
final boolean enableZoom = Boolean.TRUE.equals(
|
|
428
|
+
call.getBoolean("enableZoom", false)
|
|
429
|
+
);
|
|
430
|
+
final boolean disableExifHeaderStripping = Boolean.TRUE.equals(
|
|
431
|
+
call.getBoolean("disableExifHeaderStripping", false)
|
|
432
|
+
);
|
|
433
|
+
final boolean lockOrientation = Boolean.TRUE.equals(
|
|
434
|
+
call.getBoolean("lockAndroidOrientation", false)
|
|
435
|
+
);
|
|
436
|
+
final boolean disableAudio = Boolean.TRUE.equals(
|
|
437
|
+
call.getBoolean("disableAudio", true)
|
|
438
|
+
);
|
|
394
439
|
final String aspectRatio = call.getString("aspectRatio", "4:3");
|
|
395
440
|
final String gridMode = call.getString("gridMode", "none");
|
|
396
|
-
|
|
441
|
+
|
|
397
442
|
// Check for conflict between aspectRatio and size
|
|
398
|
-
if (
|
|
399
|
-
call.
|
|
443
|
+
if (
|
|
444
|
+
call.getData().has("aspectRatio") &&
|
|
445
|
+
(call.getData().has("width") || call.getData().has("height"))
|
|
446
|
+
) {
|
|
447
|
+
call.reject(
|
|
448
|
+
"Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start."
|
|
449
|
+
);
|
|
400
450
|
return;
|
|
401
451
|
}
|
|
402
452
|
|
|
403
453
|
float targetZoom = 1.0f;
|
|
404
454
|
// Check if the selected device is a physical ultra-wide
|
|
405
455
|
if (originalDeviceId != null) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
456
|
+
List<CameraDevice> devices = CameraXView.getAvailableDevicesStatic(
|
|
457
|
+
getContext()
|
|
458
|
+
);
|
|
459
|
+
for (CameraDevice device : devices) {
|
|
460
|
+
if (
|
|
461
|
+
originalDeviceId.equals(device.getDeviceId()) && !device.isLogical()
|
|
462
|
+
) {
|
|
463
|
+
for (LensInfo lens : device.getLenses()) {
|
|
464
|
+
if ("ultraWide".equals(lens.getDeviceType())) {
|
|
465
|
+
Log.d(
|
|
466
|
+
"CameraPreview",
|
|
467
|
+
"Ultra-wide lens selected. Targeting 0.5x zoom on logical camera."
|
|
468
|
+
);
|
|
469
|
+
targetZoom = 0.5f;
|
|
470
|
+
// Force the use of the logical camera by clearing the specific deviceId
|
|
471
|
+
deviceId = null;
|
|
472
|
+
break;
|
|
418
473
|
}
|
|
419
|
-
|
|
474
|
+
}
|
|
420
475
|
}
|
|
476
|
+
if (deviceId == null) break; // Exit outer loop once we've made our decision
|
|
477
|
+
}
|
|
421
478
|
}
|
|
422
479
|
|
|
423
|
-
previousOrientationRequest = getBridge()
|
|
480
|
+
previousOrientationRequest = getBridge()
|
|
481
|
+
.getActivity()
|
|
482
|
+
.getRequestedOrientation();
|
|
424
483
|
cameraXView = new CameraXView(getContext(), getBridge().getWebView());
|
|
425
484
|
cameraXView.setListener(this);
|
|
426
485
|
|
|
427
486
|
String finalDeviceId = deviceId;
|
|
428
487
|
float finalTargetZoom = targetZoom;
|
|
429
|
-
getBridge()
|
|
430
|
-
|
|
488
|
+
getBridge()
|
|
489
|
+
.getActivity()
|
|
490
|
+
.runOnUiThread(() -> {
|
|
491
|
+
DisplayMetrics metrics = getBridge()
|
|
492
|
+
.getActivity()
|
|
493
|
+
.getResources()
|
|
494
|
+
.getDisplayMetrics();
|
|
431
495
|
if (lockOrientation) {
|
|
432
|
-
getBridge()
|
|
496
|
+
getBridge()
|
|
497
|
+
.getActivity()
|
|
498
|
+
.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
|
|
433
499
|
}
|
|
434
|
-
|
|
500
|
+
|
|
435
501
|
// Debug: Let's check all the positioning information
|
|
436
|
-
ViewGroup webViewParent = (ViewGroup) getBridge()
|
|
437
|
-
|
|
502
|
+
ViewGroup webViewParent = (ViewGroup) getBridge()
|
|
503
|
+
.getWebView()
|
|
504
|
+
.getParent();
|
|
505
|
+
|
|
438
506
|
// Get webview position in different coordinate systems
|
|
439
507
|
int[] webViewLocationInWindow = new int[2];
|
|
440
508
|
int[] webViewLocationOnScreen = new int[2];
|
|
441
509
|
getBridge().getWebView().getLocationInWindow(webViewLocationInWindow);
|
|
442
510
|
getBridge().getWebView().getLocationOnScreen(webViewLocationOnScreen);
|
|
443
|
-
|
|
511
|
+
|
|
444
512
|
int webViewLeft = getBridge().getWebView().getLeft();
|
|
445
513
|
int webViewTop = getBridge().getWebView().getTop();
|
|
446
|
-
|
|
514
|
+
|
|
447
515
|
// Check parent position too
|
|
448
516
|
int[] parentLocationInWindow = new int[2];
|
|
449
517
|
int[] parentLocationOnScreen = new int[2];
|
|
450
518
|
webViewParent.getLocationInWindow(parentLocationInWindow);
|
|
451
519
|
webViewParent.getLocationOnScreen(parentLocationOnScreen);
|
|
452
|
-
|
|
520
|
+
|
|
453
521
|
// Calculate pixel ratio
|
|
454
522
|
float pixelRatio = metrics.density;
|
|
455
|
-
|
|
523
|
+
|
|
456
524
|
// Try using just the pixel ratio without any webview offset for now
|
|
457
525
|
int computedX = (int) (x * pixelRatio);
|
|
458
526
|
int computedY = (int) (y * pixelRatio);
|
|
459
|
-
|
|
527
|
+
|
|
460
528
|
Log.d("CameraPreview", "=== COORDINATE DEBUG ===");
|
|
461
|
-
Log.d(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
Log.d(
|
|
466
|
-
|
|
467
|
-
|
|
529
|
+
Log.d(
|
|
530
|
+
"CameraPreview",
|
|
531
|
+
"WebView getLeft/getTop: (" + webViewLeft + ", " + webViewTop + ")"
|
|
532
|
+
);
|
|
533
|
+
Log.d(
|
|
534
|
+
"CameraPreview",
|
|
535
|
+
"WebView locationInWindow: (" +
|
|
536
|
+
webViewLocationInWindow[0] +
|
|
537
|
+
", " +
|
|
538
|
+
webViewLocationInWindow[1] +
|
|
539
|
+
")"
|
|
540
|
+
);
|
|
541
|
+
Log.d(
|
|
542
|
+
"CameraPreview",
|
|
543
|
+
"WebView locationOnScreen: (" +
|
|
544
|
+
webViewLocationOnScreen[0] +
|
|
545
|
+
", " +
|
|
546
|
+
webViewLocationOnScreen[1] +
|
|
547
|
+
")"
|
|
548
|
+
);
|
|
549
|
+
Log.d(
|
|
550
|
+
"CameraPreview",
|
|
551
|
+
"Parent locationInWindow: (" +
|
|
552
|
+
parentLocationInWindow[0] +
|
|
553
|
+
", " +
|
|
554
|
+
parentLocationInWindow[1] +
|
|
555
|
+
")"
|
|
556
|
+
);
|
|
557
|
+
Log.d(
|
|
558
|
+
"CameraPreview",
|
|
559
|
+
"Parent locationOnScreen: (" +
|
|
560
|
+
parentLocationOnScreen[0] +
|
|
561
|
+
", " +
|
|
562
|
+
parentLocationOnScreen[1] +
|
|
563
|
+
")"
|
|
564
|
+
);
|
|
565
|
+
Log.d(
|
|
566
|
+
"CameraPreview",
|
|
567
|
+
"Parent class: " + webViewParent.getClass().getSimpleName()
|
|
568
|
+
);
|
|
569
|
+
Log.d(
|
|
570
|
+
"CameraPreview",
|
|
571
|
+
"Requested position (logical): (" + x + ", " + y + ")"
|
|
572
|
+
);
|
|
468
573
|
Log.d("CameraPreview", "Pixel ratio: " + pixelRatio);
|
|
469
|
-
Log.d(
|
|
574
|
+
Log.d(
|
|
575
|
+
"CameraPreview",
|
|
576
|
+
"Final computed position (no offset): (" +
|
|
577
|
+
computedX +
|
|
578
|
+
", " +
|
|
579
|
+
computedY +
|
|
580
|
+
")"
|
|
581
|
+
);
|
|
470
582
|
Log.d("CameraPreview", "========================");
|
|
471
|
-
int computedWidth = width != 0
|
|
472
|
-
|
|
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();
|
|
473
589
|
computedHeight -= (int) (paddingBottom * pixelRatio);
|
|
474
590
|
|
|
475
|
-
CameraSessionConfiguration config = new CameraSessionConfiguration(
|
|
591
|
+
CameraSessionConfiguration config = new CameraSessionConfiguration(
|
|
592
|
+
finalDeviceId,
|
|
593
|
+
position,
|
|
594
|
+
computedX,
|
|
595
|
+
computedY,
|
|
596
|
+
computedWidth,
|
|
597
|
+
computedHeight,
|
|
598
|
+
paddingBottom,
|
|
599
|
+
toBack,
|
|
600
|
+
storeToFile,
|
|
601
|
+
enableOpacity,
|
|
602
|
+
enableZoom,
|
|
603
|
+
disableExifHeaderStripping,
|
|
604
|
+
disableAudio,
|
|
605
|
+
1.0f,
|
|
606
|
+
aspectRatio,
|
|
607
|
+
gridMode
|
|
608
|
+
);
|
|
476
609
|
config.setTargetZoom(finalTargetZoom);
|
|
477
610
|
|
|
478
611
|
bridge.saveCall(call);
|
|
479
612
|
cameraStartCallbackId = call.getCallbackId();
|
|
480
613
|
cameraXView.startSession(config);
|
|
481
|
-
}
|
|
482
|
-
);
|
|
614
|
+
});
|
|
483
615
|
}
|
|
484
616
|
|
|
485
617
|
@Override
|
|
@@ -511,18 +643,21 @@ public class CameraPreview
|
|
|
511
643
|
public void onCameraStarted(int width, int height, int x, int y) {
|
|
512
644
|
PluginCall call = bridge.getSavedCall(cameraStartCallbackId);
|
|
513
645
|
if (call != null) {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
646
|
+
// Convert pixel values back to logical units
|
|
647
|
+
DisplayMetrics metrics = getBridge()
|
|
648
|
+
.getActivity()
|
|
649
|
+
.getResources()
|
|
650
|
+
.getDisplayMetrics();
|
|
651
|
+
float pixelRatio = metrics.density;
|
|
652
|
+
|
|
653
|
+
JSObject result = new JSObject();
|
|
654
|
+
result.put("width", width / pixelRatio);
|
|
655
|
+
result.put("height", height / pixelRatio);
|
|
656
|
+
result.put("x", x / pixelRatio);
|
|
657
|
+
result.put("y", y / pixelRatio);
|
|
658
|
+
call.resolve(result);
|
|
659
|
+
bridge.releaseCall(call);
|
|
660
|
+
cameraStartCallbackId = null; // Prevent re-use
|
|
526
661
|
}
|
|
527
662
|
}
|
|
528
663
|
|
|
@@ -542,9 +677,9 @@ public class CameraPreview
|
|
|
542
677
|
public void onCameraStartError(String message) {
|
|
543
678
|
PluginCall call = bridge.getSavedCall(cameraStartCallbackId);
|
|
544
679
|
if (call != null) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
680
|
+
call.reject(message);
|
|
681
|
+
bridge.releaseCall(call);
|
|
682
|
+
cameraStartCallbackId = null;
|
|
548
683
|
}
|
|
549
684
|
}
|
|
550
685
|
|
|
@@ -557,19 +692,20 @@ public class CameraPreview
|
|
|
557
692
|
String aspectRatio = call.getString("aspectRatio", "4:3");
|
|
558
693
|
Float x = call.getFloat("x");
|
|
559
694
|
Float y = call.getFloat("y");
|
|
560
|
-
|
|
561
|
-
getActivity()
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
695
|
+
|
|
696
|
+
getActivity()
|
|
697
|
+
.runOnUiThread(() -> {
|
|
698
|
+
cameraXView.setAspectRatio(aspectRatio, x, y, () -> {
|
|
699
|
+
// Return the actual preview bounds after layout and camera operations are complete
|
|
700
|
+
int[] bounds = cameraXView.getCurrentPreviewBounds();
|
|
701
|
+
JSObject ret = new JSObject();
|
|
702
|
+
ret.put("x", bounds[0]);
|
|
703
|
+
ret.put("y", bounds[1]);
|
|
704
|
+
ret.put("width", bounds[2]);
|
|
705
|
+
ret.put("height", bounds[3]);
|
|
706
|
+
call.resolve(ret);
|
|
707
|
+
});
|
|
571
708
|
});
|
|
572
|
-
});
|
|
573
709
|
}
|
|
574
710
|
|
|
575
711
|
@PluginMethod
|
|
@@ -591,10 +727,11 @@ public class CameraPreview
|
|
|
591
727
|
return;
|
|
592
728
|
}
|
|
593
729
|
String gridMode = call.getString("gridMode", "none");
|
|
594
|
-
getActivity()
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
730
|
+
getActivity()
|
|
731
|
+
.runOnUiThread(() -> {
|
|
732
|
+
cameraXView.setGridMode(gridMode);
|
|
733
|
+
call.resolve();
|
|
734
|
+
});
|
|
598
735
|
}
|
|
599
736
|
|
|
600
737
|
@PluginMethod
|
|
@@ -614,11 +751,14 @@ public class CameraPreview
|
|
|
614
751
|
call.reject("Camera is not running");
|
|
615
752
|
return;
|
|
616
753
|
}
|
|
617
|
-
|
|
754
|
+
|
|
618
755
|
// Convert pixel values back to logical units
|
|
619
|
-
DisplayMetrics metrics = getBridge()
|
|
756
|
+
DisplayMetrics metrics = getBridge()
|
|
757
|
+
.getActivity()
|
|
758
|
+
.getResources()
|
|
759
|
+
.getDisplayMetrics();
|
|
620
760
|
float pixelRatio = metrics.density;
|
|
621
|
-
|
|
761
|
+
|
|
622
762
|
JSObject ret = new JSObject();
|
|
623
763
|
ret.put("x", cameraXView.getPreviewX() / pixelRatio);
|
|
624
764
|
ret.put("y", cameraXView.getPreviewY() / pixelRatio);
|
|
@@ -626,28 +766,36 @@ public class CameraPreview
|
|
|
626
766
|
ret.put("height", cameraXView.getPreviewHeight() / pixelRatio);
|
|
627
767
|
call.resolve(ret);
|
|
628
768
|
}
|
|
769
|
+
|
|
629
770
|
@PluginMethod
|
|
630
771
|
public void setPreviewSize(PluginCall call) {
|
|
631
772
|
if (cameraXView == null || !cameraXView.isRunning()) {
|
|
632
773
|
call.reject("Camera is not running");
|
|
633
774
|
return;
|
|
634
775
|
}
|
|
635
|
-
|
|
776
|
+
|
|
636
777
|
// Get values from call - null values will become 0
|
|
637
778
|
Integer xParam = call.getInt("x");
|
|
638
779
|
Integer yParam = call.getInt("y");
|
|
639
780
|
Integer widthParam = call.getInt("width");
|
|
640
781
|
Integer heightParam = call.getInt("height");
|
|
641
|
-
|
|
782
|
+
|
|
642
783
|
// Apply pixel ratio conversion to non-null values
|
|
643
|
-
DisplayMetrics metrics = getBridge()
|
|
784
|
+
DisplayMetrics metrics = getBridge()
|
|
785
|
+
.getActivity()
|
|
786
|
+
.getResources()
|
|
787
|
+
.getDisplayMetrics();
|
|
644
788
|
float pixelRatio = metrics.density;
|
|
645
|
-
|
|
789
|
+
|
|
646
790
|
int x = (xParam != null && xParam > 0) ? (int) (xParam * pixelRatio) : 0;
|
|
647
791
|
int y = (yParam != null && yParam > 0) ? (int) (yParam * pixelRatio) : 0;
|
|
648
|
-
int width = (widthParam != null && widthParam > 0)
|
|
649
|
-
|
|
650
|
-
|
|
792
|
+
int width = (widthParam != null && widthParam > 0)
|
|
793
|
+
? (int) (widthParam * pixelRatio)
|
|
794
|
+
: 0;
|
|
795
|
+
int height = (heightParam != null && heightParam > 0)
|
|
796
|
+
? (int) (heightParam * pixelRatio)
|
|
797
|
+
: 0;
|
|
798
|
+
|
|
651
799
|
cameraXView.setPreviewSize(x, y, width, height, () -> {
|
|
652
800
|
// Return the actual preview bounds after layout operations are complete
|
|
653
801
|
int[] bounds = cameraXView.getCurrentPreviewBounds();
|