capacitor-community-multilens-camerapreview 7.0.1 → 7.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/ios/Plugin/CameraController.swift +48 -21
- package/ios/Plugin/Plugin.swift +33 -4
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Plugin
|
|
4
4
|
//
|
|
5
5
|
// Created by Ariel Hernandez Musa on 7/14/19.
|
|
6
|
-
//
|
|
6
|
+
// Modified by Pete Kraguljac on 11/5/2025
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
import AVFoundation
|
|
@@ -192,10 +192,18 @@ extension CameraController {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
func updateVideoOrientation() {
|
|
195
|
-
assert(Thread.isMainThread)
|
|
195
|
+
assert(Thread.isMainThread)
|
|
196
|
+
|
|
197
|
+
// Prefer the interfaceOrientation from the active window scene (iOS 13+)
|
|
198
|
+
let interfaceOrientation: UIInterfaceOrientation = (
|
|
199
|
+
UIApplication.shared.connectedScenes
|
|
200
|
+
.compactMap { $0 as? UIWindowScene }
|
|
201
|
+
.first(where: { $0.activationState == .foregroundActive })?
|
|
202
|
+
.interfaceOrientation
|
|
203
|
+
) ?? UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait
|
|
196
204
|
|
|
197
205
|
let videoOrientation: AVCaptureVideoOrientation
|
|
198
|
-
switch
|
|
206
|
+
switch interfaceOrientation {
|
|
199
207
|
case .portrait:
|
|
200
208
|
videoOrientation = .portrait
|
|
201
209
|
case .landscapeLeft:
|
|
@@ -204,9 +212,7 @@ extension CameraController {
|
|
|
204
212
|
videoOrientation = .landscapeRight
|
|
205
213
|
case .portraitUpsideDown:
|
|
206
214
|
videoOrientation = .portraitUpsideDown
|
|
207
|
-
|
|
208
|
-
fallthrough
|
|
209
|
-
@unknown default:
|
|
215
|
+
default:
|
|
210
216
|
videoOrientation = .portrait
|
|
211
217
|
}
|
|
212
218
|
|
|
@@ -395,19 +401,22 @@ extension CameraController {
|
|
|
395
401
|
|
|
396
402
|
}
|
|
397
403
|
func getSupportedCameras() throws -> [String] {
|
|
398
|
-
var supportedCameras: [String] = []
|
|
399
|
-
|
|
404
|
+
var supportedCameras: [String] = []
|
|
405
|
+
|
|
406
|
+
if AVCaptureDevice.default(.builtInUltraWideCamera, for: .video, position: .back) != nil {
|
|
400
407
|
supportedCameras.append("ultra")
|
|
401
408
|
}
|
|
402
|
-
if
|
|
409
|
+
if AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) != nil {
|
|
403
410
|
supportedCameras.append("wide")
|
|
404
411
|
}
|
|
405
|
-
if
|
|
412
|
+
if AVCaptureDevice.default(.builtInTelephotoCamera, for: .video, position: .back) != nil {
|
|
406
413
|
supportedCameras.append("tele")
|
|
407
414
|
}
|
|
408
|
-
|
|
415
|
+
|
|
416
|
+
return supportedCameras
|
|
409
417
|
}
|
|
410
418
|
|
|
419
|
+
|
|
411
420
|
func setFlashMode(flashMode: AVCaptureDevice.FlashMode) throws {
|
|
412
421
|
var currentCamera: AVCaptureDevice?
|
|
413
422
|
switch currentCameraPosition {
|
|
@@ -568,17 +577,32 @@ extension CameraController: UIGestureRecognizerDelegate {
|
|
|
568
577
|
}
|
|
569
578
|
|
|
570
579
|
extension CameraController: AVCapturePhotoCaptureDelegate {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
if let error = error {
|
|
574
|
-
|
|
580
|
+
|
|
581
|
+
public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
|
|
582
|
+
if let error = error {
|
|
583
|
+
self.photoCaptureCompletionBlock?(nil, error)
|
|
584
|
+
return
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// Prefer modern data extraction
|
|
588
|
+
if let data = photo.fileDataRepresentation(),
|
|
589
|
+
let image = UIImage(data: data) {
|
|
575
590
|
self.photoCaptureCompletionBlock?(image.fixedOrientation(), nil)
|
|
576
|
-
|
|
577
|
-
|
|
591
|
+
return
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Fallback to cgImageRepresentation if available
|
|
595
|
+
if let cgImage = photo.cgImageRepresentation() {
|
|
596
|
+
let image = UIImage(cgImage: cgImage)
|
|
597
|
+
self.photoCaptureCompletionBlock?(image.fixedOrientation(), nil)
|
|
598
|
+
return
|
|
578
599
|
}
|
|
600
|
+
|
|
601
|
+
self.photoCaptureCompletionBlock?(nil, CameraControllerError.unknown)
|
|
579
602
|
}
|
|
580
603
|
}
|
|
581
604
|
|
|
605
|
+
|
|
582
606
|
extension CameraController: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
583
607
|
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
584
608
|
guard let completion = sampleBufferCaptureCompletionBlock else { return }
|
|
@@ -697,12 +721,14 @@ extension UIImage {
|
|
|
697
721
|
// Flip image one more time if needed to, this is to prevent flipped image
|
|
698
722
|
switch imageOrientation {
|
|
699
723
|
case .upMirrored, .downMirrored:
|
|
700
|
-
transform.translatedBy(x: size.width, y: 0)
|
|
701
|
-
transform.scaledBy(x: -1, y: 1)
|
|
724
|
+
transform = transform.translatedBy(x: size.width, y: 0)
|
|
725
|
+
transform = transform.scaledBy(x: -1, y: 1)
|
|
726
|
+
transform = transform.scaledBy(x: -1, y: 1)
|
|
702
727
|
break
|
|
703
728
|
case .leftMirrored, .rightMirrored:
|
|
704
|
-
transform.translatedBy(x: size.height, y: 0)
|
|
705
|
-
transform.scaledBy(x: -1, y: 1)
|
|
729
|
+
transform = transform.translatedBy(x: size.height, y: 0)
|
|
730
|
+
transform = transform.scaledBy(x: -1, y: 1)
|
|
731
|
+
transform = transform.scaledBy(x: -1, y: 1)
|
|
706
732
|
case .up, .down, .left, .right:
|
|
707
733
|
break
|
|
708
734
|
}
|
|
@@ -730,3 +756,4 @@ extension CameraController: AVCaptureFileOutputRecordingDelegate {
|
|
|
730
756
|
}*/
|
|
731
757
|
}
|
|
732
758
|
}
|
|
759
|
+
|
package/ios/Plugin/Plugin.swift
CHANGED
|
@@ -24,15 +24,40 @@ public class CameraPreviewMultiLens: CAPPlugin {
|
|
|
24
24
|
var disableAudio: Bool = false
|
|
25
25
|
var zoomFactor = String()
|
|
26
26
|
|
|
27
|
+
private func currentInterfaceOrientation() -> UIInterfaceOrientation? {
|
|
28
|
+
if let window = self.webView?.window ?? self.bridge?.viewController?.view.window {
|
|
29
|
+
return window.windowScene?.interfaceOrientation
|
|
30
|
+
}
|
|
31
|
+
// Fallback to device orientation mapping
|
|
32
|
+
let deviceOrientation = UIDevice.current.orientation
|
|
33
|
+
switch deviceOrientation {
|
|
34
|
+
case .landscapeLeft: return .landscapeRight // device vs interface are mirrored
|
|
35
|
+
case .landscapeRight: return .landscapeLeft
|
|
36
|
+
case .portrait: return .portrait
|
|
37
|
+
case .portraitUpsideDown: return .portraitUpsideDown
|
|
38
|
+
default: return nil
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
@objc func rotated() {
|
|
28
43
|
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
// Determine orientation without using deprecated statusBarOrientation and without relying on missing viewController
|
|
46
|
+
let orientation = self.currentInterfaceOrientation()
|
|
47
|
+
let isLandscape: Bool
|
|
48
|
+
if let orientation = orientation {
|
|
49
|
+
isLandscape = orientation.isLandscape
|
|
50
|
+
} else {
|
|
51
|
+
// Default to portrait when unknown
|
|
52
|
+
isLandscape = false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if isLandscape {
|
|
31
56
|
self.previewView.frame = CGRect(x: self.y!, y: self.x!, width: max(height, self.width!), height: min(height, self.width!))
|
|
32
57
|
self.cameraController.previewLayer?.frame = self.previewView.frame
|
|
33
58
|
}
|
|
34
59
|
|
|
35
|
-
if
|
|
60
|
+
if !isLandscape {
|
|
36
61
|
if self.previewView != nil && self.x != nil && self.y != nil && self.width != nil && self.height != nil {
|
|
37
62
|
self.previewView.frame = CGRect(x: self.x!, y: self.y!, width: min(height, self.width!), height: max(height, self.width!))
|
|
38
63
|
}
|
|
@@ -102,6 +127,10 @@ public class CameraPreviewMultiLens: CAPPlugin {
|
|
|
102
127
|
|
|
103
128
|
if self.rotateWhenOrientationChanged == true {
|
|
104
129
|
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
130
|
+
if let scene = self.webView?.window?.windowScene ?? self.bridge?.viewController?.view.window?.windowScene {
|
|
131
|
+
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIWindowScene.willEnterForegroundNotification, object: scene)
|
|
132
|
+
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIWindowScene.didActivateNotification, object: scene)
|
|
133
|
+
}
|
|
105
134
|
}
|
|
106
135
|
|
|
107
136
|
call.resolve()
|
|
@@ -197,7 +226,7 @@ public class CameraPreviewMultiLens: CAPPlugin {
|
|
|
197
226
|
}
|
|
198
227
|
|
|
199
228
|
let imageData: Data?
|
|
200
|
-
if self.
|
|
229
|
+
if self.cameraController.currentCameraPosition == .front {
|
|
201
230
|
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
202
231
|
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
203
232
|
} else {
|
|
@@ -278,7 +307,7 @@ public class CameraPreviewMultiLens: CAPPlugin {
|
|
|
278
307
|
@objc func startRecordVideo(_ call: CAPPluginCall) {
|
|
279
308
|
DispatchQueue.main.async {
|
|
280
309
|
|
|
281
|
-
let
|
|
310
|
+
let _ = call.getInt("quality", 85)
|
|
282
311
|
|
|
283
312
|
self.cameraController.captureVideo { (image, error) in
|
|
284
313
|
|
package/package.json
CHANGED