@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 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 Android only)
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 { Plugins } from "@capacitor/core"
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 { CameraPreviewFlashMode } from '@capacitor-community/camera-preview';
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?) {
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor-community/camera-preview",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Camera preview",
5
5
  "main": "dist/esm/index.js",
6
6
  "types": "dist/esm/index.d.ts",