@carviz/capacitor-camera-preview 7.1.1 → 7.2.1

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.
@@ -43,6 +43,7 @@ class CameraController: NSObject {
43
43
  var captureSession: AVCaptureSession?
44
44
 
45
45
  var photoOutput = AVCapturePhotoOutput()
46
+ var videoDataOutput = AVCaptureVideoDataOutput()
46
47
  var photoCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
47
48
  var sampleBufferCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
48
49
 
@@ -91,6 +92,18 @@ class CameraController: NSObject {
91
92
  captureSession.addOutput(self.photoOutput)
92
93
  }
93
94
 
95
+ // Configure video data output for sample capture
96
+ self.videoDataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
97
+ self.videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
98
+ if captureSession.canAddOutput(self.videoDataOutput) {
99
+ captureSession.addOutput(self.videoDataOutput)
100
+
101
+ // Set the video orientation to match the preview layer
102
+ if let connection = self.videoDataOutput.connection(with: .video) {
103
+ connection.videoOrientation = self.previewLayer.connection?.videoOrientation ?? .portrait
104
+ }
105
+ }
106
+
94
107
  captureSession.startRunning()
95
108
 
96
109
  // Lastly setting the video zoom factor
@@ -214,6 +227,11 @@ class CameraController: NSObject {
214
227
 
215
228
  previewLayer.connection?.videoOrientation = videoOrientation
216
229
  photoOutput.connections.forEach { $0.videoOrientation = videoOrientation }
230
+
231
+ // Also update video data output orientation
232
+ if let connection = videoDataOutput.connection(with: .video) {
233
+ connection.videoOrientation = videoOrientation
234
+ }
217
235
  }
218
236
 
219
237
  public func switchCameras() throws {
@@ -293,6 +311,7 @@ class CameraController: NSObject {
293
311
  return
294
312
  }
295
313
 
314
+ // Store the completion block to be called when we receive the next video frame
296
315
  self.sampleBufferCaptureCompletionBlock = completion
297
316
  }
298
317
 
@@ -517,6 +536,77 @@ extension CameraController: AVCapturePhotoCaptureDelegate {
517
536
  }
518
537
  }
519
538
 
539
+ extension CameraController: AVCaptureVideoDataOutputSampleBufferDelegate {
540
+ func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
541
+ // Only process if we have a pending sample capture request
542
+ guard let completion = self.sampleBufferCaptureCompletionBlock else { return }
543
+
544
+ // Clear the completion block to avoid capturing multiple frames for one request
545
+ self.sampleBufferCaptureCompletionBlock = nil
546
+
547
+ // Convert sample buffer to UIImage
548
+ guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
549
+ DispatchQueue.main.async {
550
+ completion(nil, CameraControllerError.unknown)
551
+ }
552
+ return
553
+ }
554
+
555
+ // Create CIImage from pixel buffer
556
+ var ciImage = CIImage(cvPixelBuffer: pixelBuffer)
557
+
558
+ // Apply orientation correction based on video orientation
559
+ let videoOrientation = connection.videoOrientation
560
+ let transform = self.transformForVideoOrientation(videoOrientation, pixelBuffer: pixelBuffer)
561
+ ciImage = ciImage.transformed(by: transform)
562
+
563
+ let context = CIContext()
564
+
565
+ guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
566
+ DispatchQueue.main.async {
567
+ completion(nil, CameraControllerError.unknown)
568
+ }
569
+ return
570
+ }
571
+
572
+ let image = UIImage(cgImage: cgImage, scale: 1.0, orientation: .up)
573
+
574
+ // Call completion on main queue
575
+ DispatchQueue.main.async {
576
+ completion(image, nil)
577
+ }
578
+ }
579
+
580
+ private func transformForVideoOrientation(_ orientation: AVCaptureVideoOrientation, pixelBuffer: CVPixelBuffer) -> CGAffineTransform {
581
+ let bufferWidth = CGFloat(CVPixelBufferGetWidth(pixelBuffer))
582
+ let bufferHeight = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
583
+
584
+ var transform = CGAffineTransform.identity
585
+
586
+ switch orientation {
587
+ case .portrait:
588
+ // No rotation needed for portrait
589
+ break
590
+ case .portraitUpsideDown:
591
+ // Rotate 180 degrees
592
+ transform = transform.translatedBy(x: bufferWidth, y: bufferHeight)
593
+ transform = transform.rotated(by: .pi)
594
+ case .landscapeRight:
595
+ // Rotate 90 degrees clockwise
596
+ transform = transform.translatedBy(x: bufferHeight, y: 0)
597
+ transform = transform.rotated(by: .pi / 2)
598
+ case .landscapeLeft:
599
+ // Rotate 90 degrees counter-clockwise
600
+ transform = transform.translatedBy(x: 0, y: bufferWidth)
601
+ transform = transform.rotated(by: -.pi / 2)
602
+ @unknown default:
603
+ break
604
+ }
605
+
606
+ return transform
607
+ }
608
+ }
609
+
520
610
  extension CameraController: UIGestureRecognizerDelegate {
521
611
  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
522
612
  return true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carviz/capacitor-camera-preview",
3
- "version": "7.1.1",
3
+ "version": "7.2.1",
4
4
  "description": "Fork of the capacitor-community/camera-preview plugin focusing on high resolution photos without bloating up the code.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.cjs.js",