@capacitor-community/camera-preview 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/ios/Plugin/CameraController.swift +82 -0
- package/ios/Plugin/Plugin.swift +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,10 +77,11 @@ Starts the camera preview instance.
|
|
|
77
77
|
| rotateWhenOrientationChanged | boolean | (optional) Rotate preview when orientation changes (applicable to the ios platforms only; default value is true) |
|
|
78
78
|
| storeToFile | boolean | (optional) Capture images to a file and return back the file path instead of returning base64 encoded data, default false. |
|
|
79
79
|
| disableExifHeaderStripping | boolean | (optional) Disable automatic rotation of the image, and let the browser deal with it, default true (applicable to the android and ios platforms only) |
|
|
80
|
+
| enableHighResolution | boolean | (optional) Defaults to false - iOS only - Activate high resolution image capture so that output images are from the highest resolution possible on the device |
|
|
80
81
|
| disableAudio | boolean | (optional) Disables audio stream to prevent permission requests, default false. (applicable to web only) |
|
|
81
82
|
| lockAndroidOrientation | boolean | (optional) Locks device orientation when camera is showing, default false. (applicable to Android only) |
|
|
82
83
|
| enableOpacity | boolean | (optional) Make the camera preview see-through. Ideal for augmented reality uses. Default false (applicable to Android and web only)
|
|
83
|
-
| enableZoom | boolean | (optional) Set if you can pinch to zoom. Default false (applicable to
|
|
84
|
+
| enableZoom | boolean | (optional) Set if you can pinch to zoom. Default false (applicable to the android and ios platforms only)
|
|
84
85
|
|
|
85
86
|
<!-- <strong>Options:</strong>
|
|
86
87
|
All options stated are optional and will default to values here
|
|
@@ -98,9 +99,7 @@ All options stated are optional and will default to values here
|
|
|
98
99
|
* `disableExifHeaderStripping` - Defaults to false - **Android Only** - Disable automatic rotation of the image, and let the browser deal with it (keep reading on how to achieve it) -->
|
|
99
100
|
|
|
100
101
|
```javascript
|
|
101
|
-
import {
|
|
102
|
-
const { CameraPreview } = Plugins;
|
|
103
|
-
import { CameraPreviewOptions } from '@capacitor-community/camera-preview';
|
|
102
|
+
import { CameraPreview, CameraPreviewOptions } from '@capacitor-community/camera-preview';
|
|
104
103
|
|
|
105
104
|
const cameraPreviewOptions: CameraPreviewOptions = {
|
|
106
105
|
position: 'rear',
|
|
@@ -117,6 +116,7 @@ ion-content {
|
|
|
117
116
|
--background: transparent;
|
|
118
117
|
}
|
|
119
118
|
```
|
|
119
|
+
|
|
120
120
|
Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a custom class to your ion-content and make it transparent:
|
|
121
121
|
|
|
122
122
|
```css
|
|
@@ -125,6 +125,23 @@ Take into account that this will make transparent all ion-content on application
|
|
|
125
125
|
}
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
If the camera preview is not displaying after applying the above styles, apply transparent background color to the root div element of the parent component
|
|
129
|
+
Ex: VueJS >> App.vue component
|
|
130
|
+
```html
|
|
131
|
+
<template>
|
|
132
|
+
<ion-app id="app">
|
|
133
|
+
<ion-router-outlet />
|
|
134
|
+
</ion-app>
|
|
135
|
+
</template>
|
|
136
|
+
|
|
137
|
+
<style>
|
|
138
|
+
#app {
|
|
139
|
+
background-color: transparent !important;
|
|
140
|
+
}
|
|
141
|
+
<style>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
|
|
128
145
|
### stop()
|
|
129
146
|
|
|
130
147
|
<info>Stops the camera preview instance.</info><br/>
|
|
@@ -174,7 +191,7 @@ CameraPreview.hide();
|
|
|
174
191
|
<!-- <info>Take the picture. If width and height are not specified or are 0 it will use the defaults. If width and height are specified, it will choose a supported photo size that is closest to width and height specified and has closest aspect ratio to the preview. The argument `quality` defaults to `85` and specifies the quality/compression value: `0=max compression`, `100=max quality`.</info><br/> -->
|
|
175
192
|
|
|
176
193
|
```javascript
|
|
177
|
-
import {
|
|
194
|
+
import { CameraPreviewPictureOptions } from '@capacitor-community/camera-preview';
|
|
178
195
|
|
|
179
196
|
const cameraPreviewPictureOptions: CameraPreviewPictureOptions = {
|
|
180
197
|
quality: 50
|
|
@@ -34,6 +34,8 @@ class CameraController: NSObject {
|
|
|
34
34
|
|
|
35
35
|
var audioDevice: AVCaptureDevice?
|
|
36
36
|
var audioInput: AVCaptureDeviceInput?
|
|
37
|
+
|
|
38
|
+
var zoomFactor: CGFloat = 1.0
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
extension CameraController {
|
|
@@ -162,6 +164,25 @@ extension CameraController {
|
|
|
162
164
|
self.previewLayer?.frame = view.frame
|
|
163
165
|
}
|
|
164
166
|
|
|
167
|
+
func setupGestures(target: UIView, enableZoom: Bool) {
|
|
168
|
+
setupTapGesture(target: target, selector: #selector(handleTap(_:)), delegate: self)
|
|
169
|
+
if (enableZoom) {
|
|
170
|
+
setupPinchGesture(target: target, selector: #selector(handlePinch(_:)), delegate: self)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
func setupTapGesture(target: UIView, selector: Selector, delegate: UIGestureRecognizerDelegate?) {
|
|
175
|
+
let tapGesture = UITapGestureRecognizer(target: self, action: selector)
|
|
176
|
+
tapGesture.delegate = delegate
|
|
177
|
+
target.addGestureRecognizer(tapGesture)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
func setupPinchGesture(target: UIView, selector: Selector, delegate: UIGestureRecognizerDelegate?) {
|
|
181
|
+
let pinchGesture = UIPinchGestureRecognizer(target: self, action: selector)
|
|
182
|
+
pinchGesture.delegate = delegate
|
|
183
|
+
target.addGestureRecognizer(pinchGesture)
|
|
184
|
+
}
|
|
185
|
+
|
|
165
186
|
func updateVideoOrientation() {
|
|
166
187
|
assert(Thread.isMainThread) // UIApplication.statusBarOrientation requires the main thread.
|
|
167
188
|
|
|
@@ -416,6 +437,67 @@ extension CameraController {
|
|
|
416
437
|
}
|
|
417
438
|
}
|
|
418
439
|
|
|
440
|
+
extension CameraController: UIGestureRecognizerDelegate {
|
|
441
|
+
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
@objc
|
|
446
|
+
func handleTap(_ tap: UITapGestureRecognizer) {
|
|
447
|
+
guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
|
|
448
|
+
|
|
449
|
+
let point = tap.location(in: tap.view)
|
|
450
|
+
let devicePoint = self.previewLayer?.captureDevicePointConverted(fromLayerPoint: point)
|
|
451
|
+
|
|
452
|
+
do {
|
|
453
|
+
try device.lockForConfiguration()
|
|
454
|
+
defer { device.unlockForConfiguration() }
|
|
455
|
+
|
|
456
|
+
let focusMode = AVCaptureDevice.FocusMode.autoFocus
|
|
457
|
+
if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(focusMode) {
|
|
458
|
+
device.focusPointOfInterest = CGPoint(x: CGFloat(devicePoint?.x ?? 0), y: CGFloat(devicePoint?.y ?? 0))
|
|
459
|
+
device.focusMode = focusMode
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
let exposureMode = AVCaptureDevice.ExposureMode.autoExpose
|
|
463
|
+
if device.isExposurePointOfInterestSupported && device.isExposureModeSupported(exposureMode) {
|
|
464
|
+
device.exposurePointOfInterest = CGPoint(x: CGFloat(devicePoint?.x ?? 0), y: CGFloat(devicePoint?.y ?? 0))
|
|
465
|
+
device.exposureMode = exposureMode
|
|
466
|
+
}
|
|
467
|
+
} catch {
|
|
468
|
+
debugPrint(error)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
@objc
|
|
473
|
+
private func handlePinch(_ pinch: UIPinchGestureRecognizer) {
|
|
474
|
+
guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
|
|
475
|
+
|
|
476
|
+
func minMaxZoom(_ factor: CGFloat) -> CGFloat { return max(1.0, min(factor, device.activeFormat.videoMaxZoomFactor)) }
|
|
477
|
+
|
|
478
|
+
func update(scale factor: CGFloat) {
|
|
479
|
+
do {
|
|
480
|
+
try device.lockForConfiguration()
|
|
481
|
+
defer { device.unlockForConfiguration() }
|
|
482
|
+
|
|
483
|
+
device.videoZoomFactor = factor
|
|
484
|
+
} catch {
|
|
485
|
+
debugPrint(error)
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
switch pinch.state {
|
|
490
|
+
case .began: fallthrough
|
|
491
|
+
case .changed:
|
|
492
|
+
let newScaleFactor = minMaxZoom(pinch.scale * zoomFactor)
|
|
493
|
+
update(scale: newScaleFactor)
|
|
494
|
+
case .ended:
|
|
495
|
+
zoomFactor = device.videoZoomFactor
|
|
496
|
+
default: break
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
419
501
|
extension CameraController: AVCapturePhotoCaptureDelegate {
|
|
420
502
|
public func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
|
|
421
503
|
resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Swift.Error?) {
|
package/ios/Plugin/Plugin.swift
CHANGED
|
@@ -19,6 +19,7 @@ public class CameraPreview: CAPPlugin {
|
|
|
19
19
|
var rotateWhenOrientationChanged: Bool?
|
|
20
20
|
var toBack: Bool?
|
|
21
21
|
var storeToFile: Bool?
|
|
22
|
+
var enableZoom: Bool?
|
|
22
23
|
var highResolutionOutput: Bool = false
|
|
23
24
|
|
|
24
25
|
@objc func rotated() {
|
|
@@ -78,6 +79,7 @@ public class CameraPreview: CAPPlugin {
|
|
|
78
79
|
self.rotateWhenOrientationChanged = call.getBool("rotateWhenOrientationChanged") ?? true
|
|
79
80
|
self.toBack = call.getBool("toBack") ?? false
|
|
80
81
|
self.storeToFile = call.getBool("storeToFile") ?? false
|
|
82
|
+
self.enableZoom = call.getBool("enableZoom") ?? false
|
|
81
83
|
|
|
82
84
|
AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
|
|
83
85
|
guard granted else {
|
|
@@ -106,6 +108,9 @@ public class CameraPreview: CAPPlugin {
|
|
|
106
108
|
}
|
|
107
109
|
try? self.cameraController.displayPreview(on: self.previewView)
|
|
108
110
|
|
|
111
|
+
let frontView = self.toBack! ? self.webView : self.previewView;
|
|
112
|
+
self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
|
|
113
|
+
|
|
109
114
|
if (self.rotateWhenOrientationChanged == true) {
|
|
110
115
|
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
111
116
|
}
|