capacitor-camera-view 1.0.4 → 1.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/Package.swift +1 -1
- package/README.md +25 -15
- package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraView.kt +112 -43
- package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraViewPlugin.kt +8 -6
- package/dist/docs.json +56 -26
- package/dist/esm/definitions.d.ts +34 -15
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -7
- package/dist/esm/web.js +18 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +18 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +18 -2
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CameraViewPlugin/CameraSessionConfiguration.swift +1 -1
- package/ios/Sources/CameraViewPlugin/CameraViewManager+BarcodeScan.swift +5 -5
- package/ios/Sources/CameraViewPlugin/CameraViewManager+PhotoCapture.swift +0 -1
- package/ios/Sources/CameraViewPlugin/CameraViewManager.swift +11 -12
- package/ios/Sources/CameraViewPlugin/CameraViewPlugin.swift +53 -15
- package/ios/Sources/CameraViewPlugin/Utils.swift +8 -0
- package/package.json +11 -10
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/utils.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\n/**\n * The main Capacitor Camera View plugin instance.\n */\nconst CameraView = registerPlugin('CameraView', {\n web: () => import('./web').then((m) => new m.CameraViewWeb()),\n});\nexport * from './definitions';\nexport { CameraView };\n//# sourceMappingURL=index.js.map","/**\n * Converts canvas to base64 string\n */\nexport function canvasToBase64(canvas, quality) {\n const dataUrl = canvas.toDataURL('image/jpeg', quality);\n return dataUrl.split(',')[1];\n}\n/**\n * Calculates the visible area of the video based on object-fit: cover\n */\nexport function calculateVisibleArea(video) {\n // Get the displayed dimensions of the video element\n const videoRect = video.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get the intrinsic dimensions of the video\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n // Calculate which portion of the video is visible (for object-fit: cover)\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let sourceX = 0;\n let sourceY = 0;\n let sourceWidth = videoWidth;\n let sourceHeight = videoHeight;\n // If video aspect ratio is greater than display aspect ratio,\n // the video is cropped on the sides\n if (videoAspect > displayAspect) {\n sourceWidth = videoHeight * displayAspect;\n sourceX = (videoWidth - sourceWidth) / 2;\n }\n // Otherwise the video is cropped on the top and bottom\n else {\n sourceHeight = videoWidth / displayAspect;\n sourceY = (videoHeight - sourceHeight) / 2;\n }\n return {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n displayWidth,\n displayHeight,\n };\n}\n/**\n * Draws the visible area of the video to the canvas\n */\nexport function drawVisibleAreaToCanvas(canvas, videoElement, area) {\n const { sourceX, sourceY, sourceWidth, sourceHeight, displayWidth, displayHeight } = area;\n // Set canvas size to match the displayed dimensions\n canvas.width = displayWidth;\n canvas.height = displayHeight;\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) {\n throw new Error('Could not get canvas context');\n }\n // Draw only the visible portion of the video to match what the user sees\n ctx.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, displayWidth, displayHeight);\n}\n/**\n * Transforms barcode coordinates from the video source space to display space\n * accounting for object-fit: cover scaling and cropping.\n *\n * @param barcodeBoundingBox The original barcode bounding box from the detector\n * @param videoElement The video element with the camera stream\n * @returns The transformed bounding box coordinates in display space\n */\nexport function transformBarcodeBoundingBox(barcodeBoundingBox, videoElement) {\n // Get the video element's displayed dimensions\n const videoRect = videoElement.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get original video dimensions\n const videoWidth = videoElement.videoWidth;\n const videoHeight = videoElement.videoHeight;\n // Calculate scaling and positioning for object-fit: cover\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let scaledX, scaledY, scaledWidth, scaledHeight;\n if (videoAspect > displayAspect) {\n // Video is wider than display area - height matches, width is centered and cropped\n const scale = displayHeight / videoHeight;\n const scaledVideoWidth = videoWidth * scale;\n const cropX = (scaledVideoWidth - displayWidth) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale - cropX;\n scaledY = barcodeBoundingBox.y * scale;\n }\n else {\n // Video is taller than display area - width matches, height is centered and cropped\n const scale = displayWidth / videoWidth;\n const scaledVideoHeight = videoHeight * scale;\n const cropY = (scaledVideoHeight - displayHeight) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale;\n scaledY = barcodeBoundingBox.y * scale - cropY;\n }\n return {\n x: scaledX,\n y: scaledY,\n width: scaledWidth,\n height: scaledHeight,\n };\n}\n//# sourceMappingURL=utils.js.map","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n};\nvar _isRunning;\nimport { WebPlugin } from '@capacitor/core';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin {\n constructor() {\n super();\n // DOM elements\n this.videoElement = null;\n this.canvasElement = null;\n // Stream state\n this.stream = null;\n _isRunning.set(this, false);\n // Configuration state\n this.currentCamera = 'environment'; // Default to back camera\n this.currentZoom = 1.0;\n this.currentFlashMode = 'off';\n // Barcode detection support\n this.barcodeDetectionSupported = false;\n this.barcodeDetector = null;\n this.checkBarcodeDetectionSupport();\n }\n /**\n * Start the camera with the given configuration\n */\n async start(options) {\n if (__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options === null || options === void 0 ? void 0 : options.containerElementId);\n }\n // Set up video constraints based on options\n const videoConstraints = {};\n // Prefer deviceId if specified\n if (options === null || options === void 0 ? void 0 : options.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n }\n else {\n // Fall back to facing mode\n const facingMode = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n const constraints = {\n video: videoConstraints,\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n __classPrivateFieldSet(this, _isRunning, true);\n // If barcode detection is enabled and supported, start detection\n if ((options === null || options === void 0 ? void 0 : options.enableBarcodeDetection) && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n }\n catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Stop the camera and release resources\n */\n async stop() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n __classPrivateFieldSet(this, _isRunning, false);\n }\n catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Check if the camera is currently running\n */\n async isRunning() {\n return { isRunning: __classPrivateFieldGet(this, _isRunning) };\n }\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture(options) {\n const videoElement = this.videoElement;\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement) {\n throw new Error('Camera is not running');\n }\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data };\n }\n catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample(options) {\n return this.capture(options);\n }\n /**\n * Flip between front and back camera\n */\n async flipCamera() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n throw new Error('Camera is not running');\n }\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n // Restart with new facing mode\n const constraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n }\n catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Get available camera devices\n */\n async getAvailableDevices() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n }\n catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n /**\n * Get current zoom information (web has limited zoom support)\n */\n async getZoom() {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n /**\n * Set zoom level (limited support in web)\n */\n async setZoom(options) {\n // Store the requested zoom level\n this.currentZoom = options.level;\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n /**\n * Get current flash mode\n */\n async getFlashMode() {\n return { flashMode: this.currentFlashMode };\n }\n /**\n * Get supported flash modes\n */\n async getSupportedFlashModes() {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n /**\n * Set flash mode (limited support in web)\n */\n async setFlashMode(options) {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n /**\n * Check camera permission without requesting\n */\n async checkPermissions() {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n }\n catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n /**\n * Request camera permission from the user\n */\n async requestPermissions() {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n return { camera: 'granted' };\n }\n catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n /**\n * Start barcode detection if supported\n */\n async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement || !barcodeDetector) {\n return;\n }\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n }\n catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n if (__classPrivateFieldGet(this, _isRunning)) {\n requestAnimationFrame(detectFrame);\n }\n };\n requestAnimationFrame(detectFrame);\n }\n /**\n * Clean up resources when the plugin is disposed\n */\n async handleOnDestroy() {\n var _a;\n await this.stop();\n // Remove elements from DOM\n if ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n this.barcodeDetector = null;\n }\n /**\n * Check if barcode detection is supported in this browser\n */\n async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n }\n catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n /**\n * Set up the video element for the camera view\n */\n async setupVideoElement(containerElementId) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n }\n else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n /**\n * Ensures canvas element exists and returns it\n */\n getCanvasElement() {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n /**\n * Format error message\n */\n formatError(err) {\n return err instanceof Error ? err.message : String(err);\n }\n}\n_isRunning = new WeakMap();\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/utils.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\n/**\n * The main Capacitor Camera View plugin instance.\n */\nconst CameraView = registerPlugin('CameraView', {\n web: () => import('./web').then((m) => new m.CameraViewWeb()),\n});\nexport * from './definitions';\nexport { CameraView };\n//# sourceMappingURL=index.js.map","/**\n * Converts canvas to base64 string\n */\nexport function canvasToBase64(canvas, quality) {\n const dataUrl = canvas.toDataURL('image/jpeg', quality);\n return dataUrl.split(',')[1];\n}\n/**\n * Calculates the visible area of the video based on object-fit: cover\n */\nexport function calculateVisibleArea(video) {\n // Get the displayed dimensions of the video element\n const videoRect = video.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get the intrinsic dimensions of the video\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n // Calculate which portion of the video is visible (for object-fit: cover)\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let sourceX = 0;\n let sourceY = 0;\n let sourceWidth = videoWidth;\n let sourceHeight = videoHeight;\n // If video aspect ratio is greater than display aspect ratio,\n // the video is cropped on the sides\n if (videoAspect > displayAspect) {\n sourceWidth = videoHeight * displayAspect;\n sourceX = (videoWidth - sourceWidth) / 2;\n }\n // Otherwise the video is cropped on the top and bottom\n else {\n sourceHeight = videoWidth / displayAspect;\n sourceY = (videoHeight - sourceHeight) / 2;\n }\n return {\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n displayWidth,\n displayHeight,\n };\n}\n/**\n * Draws the visible area of the video to the canvas\n */\nexport function drawVisibleAreaToCanvas(canvas, videoElement, area) {\n const { sourceX, sourceY, sourceWidth, sourceHeight, displayWidth, displayHeight } = area;\n // Set canvas size to match the displayed dimensions\n canvas.width = displayWidth;\n canvas.height = displayHeight;\n const ctx = canvas.getContext('2d', { alpha: false });\n if (!ctx) {\n throw new Error('Could not get canvas context');\n }\n // Draw only the visible portion of the video to match what the user sees\n ctx.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, displayWidth, displayHeight);\n}\n/**\n * Transforms barcode coordinates from the video source space to display space\n * accounting for object-fit: cover scaling and cropping.\n *\n * @param barcodeBoundingBox The original barcode bounding box from the detector\n * @param videoElement The video element with the camera stream\n * @returns The transformed bounding box coordinates in display space\n */\nexport function transformBarcodeBoundingBox(barcodeBoundingBox, videoElement) {\n // Get the video element's displayed dimensions\n const videoRect = videoElement.getBoundingClientRect();\n const displayWidth = videoRect.width;\n const displayHeight = videoRect.height;\n // Get original video dimensions\n const videoWidth = videoElement.videoWidth;\n const videoHeight = videoElement.videoHeight;\n // Calculate scaling and positioning for object-fit: cover\n const videoAspect = videoWidth / videoHeight;\n const displayAspect = displayWidth / displayHeight;\n let scaledX, scaledY, scaledWidth, scaledHeight;\n if (videoAspect > displayAspect) {\n // Video is wider than display area - height matches, width is centered and cropped\n const scale = displayHeight / videoHeight;\n const scaledVideoWidth = videoWidth * scale;\n const cropX = (scaledVideoWidth - displayWidth) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale - cropX;\n scaledY = barcodeBoundingBox.y * scale;\n }\n else {\n // Video is taller than display area - width matches, height is centered and cropped\n const scale = displayWidth / videoWidth;\n const scaledVideoHeight = videoHeight * scale;\n const cropY = (scaledVideoHeight - displayHeight) / 2;\n scaledWidth = barcodeBoundingBox.width * scale;\n scaledHeight = barcodeBoundingBox.height * scale;\n scaledX = barcodeBoundingBox.x * scale;\n scaledY = barcodeBoundingBox.y * scale - cropY;\n }\n return {\n x: scaledX,\n y: scaledY,\n width: scaledWidth,\n height: scaledHeight,\n };\n}\n//# sourceMappingURL=utils.js.map","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n};\nvar _isRunning;\nimport { WebPlugin } from '@capacitor/core';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin {\n constructor() {\n super();\n // DOM elements\n this.videoElement = null;\n this.canvasElement = null;\n // Stream state\n this.stream = null;\n _isRunning.set(this, false);\n // Configuration state\n this.currentCamera = 'environment'; // Default to back camera\n this.currentZoom = 1.0;\n this.currentFlashMode = 'off';\n // Barcode detection support\n this.barcodeDetectionSupported = false;\n this.barcodeDetector = null;\n this.checkBarcodeDetectionSupport();\n }\n /**\n * Start the camera with the given configuration\n */\n async start(options) {\n if (__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options === null || options === void 0 ? void 0 : options.containerElementId);\n }\n // Set up video constraints based on options\n const videoConstraints = {};\n // Prefer deviceId if specified\n if (options === null || options === void 0 ? void 0 : options.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n }\n else {\n // Fall back to facing mode\n const facingMode = (options === null || options === void 0 ? void 0 : options.position) === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n const constraints = {\n video: videoConstraints,\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n __classPrivateFieldSet(this, _isRunning, true);\n // If barcode detection is enabled and supported, start detection\n if ((options === null || options === void 0 ? void 0 : options.enableBarcodeDetection) && this.barcodeDetectionSupported) {\n this.startBarcodeDetection();\n }\n }\n }\n catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Stop the camera and release resources\n */\n async stop() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n return;\n }\n try {\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n __classPrivateFieldSet(this, _isRunning, false);\n }\n catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Check if the camera is currently running\n */\n async isRunning() {\n return { isRunning: __classPrivateFieldGet(this, _isRunning) };\n }\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture(options) {\n const videoElement = this.videoElement;\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement) {\n throw new Error('Camera is not running');\n }\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n if (options.saveToFile) {\n // Create a blob from canvas and return a blob URL\n return new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (!blob) {\n reject(new Error('Failed to create blob from canvas'));\n return;\n }\n const url = URL.createObjectURL(blob);\n resolve({ webPath: url });\n }, 'image/jpeg', quality);\n });\n }\n else {\n // Return base64 data\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data };\n }\n }\n catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample(options) {\n return this.capture(options);\n }\n /**\n * Flip between front and back camera\n */\n async flipCamera() {\n if (!__classPrivateFieldGet(this, _isRunning)) {\n throw new Error('Camera is not running');\n }\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n // Restart with new facing mode\n const constraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n }\n catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n /**\n * Get available camera devices\n */\n async getAvailableDevices() {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n }\n catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n /**\n * Get current zoom information (web has limited zoom support)\n */\n async getZoom() {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n /**\n * Set zoom level (limited support in web)\n */\n async setZoom(options) {\n // Store the requested zoom level\n this.currentZoom = options.level;\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n /**\n * Get current flash mode\n */\n async getFlashMode() {\n return { flashMode: this.currentFlashMode };\n }\n /**\n * Get supported flash modes\n */\n async getSupportedFlashModes() {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n /**\n * Set flash mode (limited support in web)\n */\n async setFlashMode(options) {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n /**\n * Check camera permission without requesting\n */\n async checkPermissions() {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const result = await navigator.permissions.query({ name: 'camera' });\n return {\n camera: result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt',\n };\n }\n // If Permissions API is not available, check if we have an active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n };\n }\n catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n };\n }\n }\n /**\n * Request camera permission from the user\n */\n async requestPermissions() {\n try {\n // Try to access the camera to trigger the permission prompt\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n // If we get here, permission was granted\n // Clean up the test stream\n stream.getTracks().forEach((track) => track.stop());\n return { camera: 'granted' };\n }\n catch (err) {\n // Permission denied or other error\n return { camera: 'denied' };\n }\n }\n /**\n * Start barcode detection if supported\n */\n async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!__classPrivateFieldGet(this, _isRunning) || !videoElement || !barcodeDetector) {\n return;\n }\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n }\n catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n if (__classPrivateFieldGet(this, _isRunning)) {\n requestAnimationFrame(detectFrame);\n }\n };\n requestAnimationFrame(detectFrame);\n }\n /**\n * Clean up resources when the plugin is disposed\n */\n async handleOnDestroy() {\n var _a;\n await this.stop();\n // Remove elements from DOM\n if ((_a = this.videoElement) === null || _a === void 0 ? void 0 : _a.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n this.barcodeDetector = null;\n }\n /**\n * Check if barcode detection is supported in this browser\n */\n async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n }\n catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n /**\n * Set up the video element for the camera view\n */\n async setupVideoElement(containerElementId) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n }\n else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n /**\n * Ensures canvas element exists and returns it\n */\n getCanvasElement() {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n /**\n * Format error message\n */\n formatError(err) {\n return err instanceof Error ? err.message : String(err);\n }\n}\n_isRunning = new WeakMap();\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin"],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@ public func sessionConfigFromPluginCall(_ call: CAPPluginCall) -> CameraSessionC
|
|
|
18
18
|
let enableBarcodeDetection = call.getBool("enableBarcodeDetection", false)
|
|
19
19
|
let position: AVCaptureDevice.Position = call.getString("position") == "front" ? .front : .back
|
|
20
20
|
let preferredCameraDeviceTypes = call.getArray("preferredCameraDeviceTypes") as? [String]
|
|
21
|
-
let useTripleCameraIfAvailable = call.getBool("useTripleCameraIfAvailable",
|
|
21
|
+
let useTripleCameraIfAvailable = call.getBool("useTripleCameraIfAvailable", false)
|
|
22
22
|
let zoomFactor = call.getDouble("zoomFactor").map { CGFloat($0) }
|
|
23
23
|
|
|
24
24
|
return CameraSessionConfiguration(
|
|
@@ -36,7 +36,7 @@ extension CameraViewManager: AVCaptureMetadataOutputObjectsDelegate {
|
|
|
36
36
|
.pdf417,
|
|
37
37
|
.aztec,
|
|
38
38
|
.dataMatrix,
|
|
39
|
-
.upce
|
|
39
|
+
.upce
|
|
40
40
|
]
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -67,15 +67,15 @@ extension CameraViewManager: AVCaptureMetadataOutputObjectsDelegate {
|
|
|
67
67
|
// Which in our case should always equal to the device's screen
|
|
68
68
|
// This way we can simply use pixel coordinates to get the bounding box of the detected barcode and easily show it in the webview
|
|
69
69
|
guard let transformedMetadataObject = videoPreviewLayer.transformedMetadataObject(for: metadataObject)
|
|
70
|
-
else {
|
|
71
|
-
return
|
|
70
|
+
else {
|
|
71
|
+
return
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
let boundingRect: [String: Double] = [
|
|
75
75
|
"x": Double(transformedMetadataObject.bounds.origin.x),
|
|
76
76
|
"y": Double(transformedMetadataObject.bounds.origin.y),
|
|
77
77
|
"width": Double(transformedMetadataObject.bounds.width),
|
|
78
|
-
"height": Double(transformedMetadataObject.bounds.height)
|
|
78
|
+
"height": Double(transformedMetadataObject.bounds.height)
|
|
79
79
|
]
|
|
80
80
|
|
|
81
81
|
NotificationCenter.default.post(
|
|
@@ -84,7 +84,7 @@ extension CameraViewManager: AVCaptureMetadataOutputObjectsDelegate {
|
|
|
84
84
|
userInfo: [
|
|
85
85
|
"value": barcodeValue,
|
|
86
86
|
"type": barcodeType,
|
|
87
|
-
"boundingRect": boundingRect
|
|
87
|
+
"boundingRect": boundingRect
|
|
88
88
|
]
|
|
89
89
|
)
|
|
90
90
|
}
|
|
@@ -10,7 +10,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
10
10
|
.builtInDualCamera,
|
|
11
11
|
.builtInDualWideCamera,
|
|
12
12
|
.builtInTripleCamera,
|
|
13
|
-
.builtInTrueDepthCamera
|
|
13
|
+
.builtInTrueDepthCamera
|
|
14
14
|
]
|
|
15
15
|
|
|
16
16
|
/// A camera implementation that handles camera session management and photo capture.
|
|
@@ -41,7 +41,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
41
41
|
/// Callback for when snapshot capture completes.
|
|
42
42
|
internal var snapshotCompletionHandler: ((UIImage?, Error?) -> Void)?
|
|
43
43
|
|
|
44
|
-
public
|
|
44
|
+
override public init() {
|
|
45
45
|
super.init()
|
|
46
46
|
setupOrientationObserver()
|
|
47
47
|
setupAppLifecycleObservers()
|
|
@@ -52,7 +52,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
52
52
|
NotificationCenter.default.removeObserver(self)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
// MARK: - Plugin API
|
|
56
56
|
|
|
57
57
|
/// Starts capture session for the specified camera position.
|
|
58
58
|
/// This will reuse the existing capture session if it is already running.
|
|
@@ -152,7 +152,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
152
152
|
|
|
153
153
|
// Ensure proper orientation
|
|
154
154
|
if let photoConnection = avPhotoOutput.connection(with: .video),
|
|
155
|
-
|
|
155
|
+
let previewConnection = videoPreviewLayer.connection {
|
|
156
156
|
if photoConnection.isVideoOrientationSupported {
|
|
157
157
|
photoConnection.videoOrientation = previewConnection.videoOrientation
|
|
158
158
|
}
|
|
@@ -178,7 +178,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
178
178
|
|
|
179
179
|
// Ensure proper orientation
|
|
180
180
|
if let videoConnection = avVideoDataOutput.connection(with: .video),
|
|
181
|
-
|
|
181
|
+
let previewConnection = videoPreviewLayer.connection {
|
|
182
182
|
if videoConnection.isVideoOrientationSupported {
|
|
183
183
|
videoConnection.videoOrientation = previewConnection.videoOrientation
|
|
184
184
|
}
|
|
@@ -371,7 +371,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
371
371
|
/// Returns a list of available camera devices based on the preferences by the user
|
|
372
372
|
///
|
|
373
373
|
/// - Returns: a list of camera devices based on the preferredCameraDeviceTypes
|
|
374
|
-
private func getPreferredCameraDevices()
|
|
374
|
+
private func getPreferredCameraDevices() -> [AVCaptureDevice] {
|
|
375
375
|
return AVCaptureDevice.DiscoverySession(
|
|
376
376
|
deviceTypes: self.preferredCameraDeviceTypes,
|
|
377
377
|
mediaType: .video,
|
|
@@ -387,8 +387,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
387
387
|
/// - position: The position of the camera device to get
|
|
388
388
|
/// - Returns: The camera device for the specified position
|
|
389
389
|
/// - Throws: An error if no camera device is found.
|
|
390
|
-
private func getCameraDevice(for position: AVCaptureDevice.Position?) throws -> AVCaptureDevice
|
|
391
|
-
{
|
|
390
|
+
private func getCameraDevice(for position: AVCaptureDevice.Position?) throws -> AVCaptureDevice {
|
|
392
391
|
let preferredDevices = getPreferredCameraDevices()
|
|
393
392
|
|
|
394
393
|
// First try to get the best match based on the users preferred camera device types
|
|
@@ -430,7 +429,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
430
429
|
return device
|
|
431
430
|
}
|
|
432
431
|
|
|
433
|
-
|
|
432
|
+
// MARK: - UI Preview Layer
|
|
434
433
|
|
|
435
434
|
/// Sets up the preview layer for the capture session which will
|
|
436
435
|
/// display the camera feed in the view.
|
|
@@ -465,7 +464,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
465
464
|
}
|
|
466
465
|
}
|
|
467
466
|
|
|
468
|
-
|
|
467
|
+
// MARK: - Triple Camera
|
|
469
468
|
|
|
470
469
|
/// Upgrades the camera to the triple camera if available.
|
|
471
470
|
/// Initializing the triple camera is an expensive operation and takes some time.
|
|
@@ -549,7 +548,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
549
548
|
}
|
|
550
549
|
}
|
|
551
550
|
|
|
552
|
-
|
|
551
|
+
// MARK: - Orientation Observer
|
|
553
552
|
|
|
554
553
|
/// Sets up an observer for device orientation changes to update the preview layer orientation.
|
|
555
554
|
private func setupOrientationObserver() {
|
|
@@ -593,7 +592,7 @@ internal let SUPPORTED_CAMERA_DEVICE_TYPES: [AVCaptureDevice.DeviceType] = [
|
|
|
593
592
|
}
|
|
594
593
|
}
|
|
595
594
|
|
|
596
|
-
|
|
595
|
+
// MARK: - App Lifecycle Observers
|
|
597
596
|
|
|
598
597
|
/// Sets up observers for app lifecycle events to pause and resume the camera session.
|
|
599
598
|
private func setupAppLifecycleObservers() {
|
|
@@ -13,14 +13,14 @@ public class CameraViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
13
13
|
private let strToFlashModeMap: [String: AVCaptureDevice.FlashMode] = [
|
|
14
14
|
"off": .off,
|
|
15
15
|
"on": .on,
|
|
16
|
-
"auto": .auto
|
|
16
|
+
"auto": .auto
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
/// Maps AVCaptureDevice.FlashMode enum values to string values.
|
|
20
20
|
private let flashModeToStrMap: [AVCaptureDevice.FlashMode: String] = [
|
|
21
21
|
.off: "off",
|
|
22
22
|
.on: "on",
|
|
23
|
-
.auto: "auto"
|
|
23
|
+
.auto: "auto"
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
@@ -37,7 +37,7 @@ public class CameraViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
37
37
|
CAPPluginMethod(name: "getSupportedFlashModes", returnType: CAPPluginReturnPromise),
|
|
38
38
|
CAPPluginMethod(name: "setFlashMode", returnType: CAPPluginReturnPromise),
|
|
39
39
|
CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise),
|
|
40
|
-
CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise)
|
|
40
|
+
CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise)
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
private let implementation = CameraViewManager()
|
|
@@ -104,6 +104,7 @@ public class CameraViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
104
104
|
|
|
105
105
|
@objc func capture(_ call: CAPPluginCall) {
|
|
106
106
|
let quality = call.getDouble("quality", 90.0)
|
|
107
|
+
let saveToFile = call.getBool("saveToFile", false)
|
|
107
108
|
|
|
108
109
|
guard quality >= 0.0 && quality <= 100.0 else {
|
|
109
110
|
call.reject("Quality must be between 0 and 100")
|
|
@@ -117,48 +118,85 @@ public class CameraViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
guard let image = image else {
|
|
120
|
-
call.reject("No image data"
|
|
121
|
+
call.reject("No image data")
|
|
121
122
|
return
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
guard let imageData = image.jpegData(compressionQuality: quality / 100.0) else {
|
|
125
|
-
call.reject("Failed to compress image"
|
|
126
|
+
call.reject("Failed to compress image")
|
|
126
127
|
return
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
if saveToFile {
|
|
131
|
+
do {
|
|
132
|
+
let tempFileURL = try createTempImageFile()
|
|
133
|
+
try imageData.write(to: tempFileURL)
|
|
134
|
+
|
|
135
|
+
// Convert file URL to webView-accessible path using Capacitor bridge
|
|
136
|
+
guard let webPath = self.bridge?.portablePath(fromLocalURL: tempFileURL)?.absoluteString else {
|
|
137
|
+
call.reject("Failed to create web-accessible path")
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
call.resolve(["webPath": webPath])
|
|
142
|
+
} catch {
|
|
143
|
+
call.reject("Failed to save image to file", nil, error)
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
// Return as base64
|
|
147
|
+
call.resolve([
|
|
148
|
+
"photo": imageData.base64EncodedString()
|
|
149
|
+
])
|
|
150
|
+
}
|
|
132
151
|
})
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
@objc func captureSample(_ call: CAPPluginCall) {
|
|
136
155
|
let quality = call.getDouble("quality", 90.0)
|
|
156
|
+
let saveToFile = call.getBool("saveToFile", false)
|
|
137
157
|
|
|
138
158
|
guard quality >= 0.0 && quality <= 100.0 else {
|
|
139
159
|
call.reject("Quality must be between 0 and 100")
|
|
140
160
|
return
|
|
141
161
|
}
|
|
142
162
|
|
|
143
|
-
implementation.captureSnapshot
|
|
163
|
+
implementation.captureSnapshot { (image, error) in
|
|
144
164
|
if let error = error {
|
|
145
165
|
call.reject("Failed to capture frame", nil, error)
|
|
146
166
|
return
|
|
147
167
|
}
|
|
148
168
|
|
|
149
169
|
guard let image = image else {
|
|
150
|
-
call.reject("No frame data"
|
|
170
|
+
call.reject("No frame data")
|
|
151
171
|
return
|
|
152
172
|
}
|
|
153
173
|
|
|
154
174
|
guard let imageData = image.jpegData(compressionQuality: quality / 100.0) else {
|
|
155
|
-
call.reject("Failed to compress image"
|
|
175
|
+
call.reject("Failed to compress image")
|
|
156
176
|
return
|
|
157
177
|
}
|
|
158
178
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
179
|
+
if saveToFile {
|
|
180
|
+
do {
|
|
181
|
+
let tempFileURL = try createTempImageFile()
|
|
182
|
+
try imageData.write(to: tempFileURL)
|
|
183
|
+
|
|
184
|
+
// Convert file URL to webView-accessible path using Capacitor bridge
|
|
185
|
+
guard let webPath = self.bridge?.portablePath(fromLocalURL: tempFileURL)?.absoluteString else {
|
|
186
|
+
call.reject("Failed to create web-accessible path")
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
call.resolve(["webPath": webPath])
|
|
191
|
+
} catch {
|
|
192
|
+
call.reject("Failed to save sample to file", nil, error)
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
// Return as base64
|
|
196
|
+
call.resolve([
|
|
197
|
+
"photo": imageData.base64EncodedString()
|
|
198
|
+
])
|
|
199
|
+
}
|
|
162
200
|
}
|
|
163
201
|
}
|
|
164
202
|
|
|
@@ -196,7 +234,7 @@ public class CameraViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
196
234
|
call.resolve([
|
|
197
235
|
"min": zoom.min,
|
|
198
236
|
"max": zoom.max,
|
|
199
|
-
"current": zoom.current
|
|
237
|
+
"current": zoom.current
|
|
200
238
|
])
|
|
201
239
|
}
|
|
202
240
|
|
|
@@ -54,3 +54,11 @@ public func convertToStringCameraType(_ deviceType: AVCaptureDevice.DeviceType)
|
|
|
54
54
|
public func convertToNativeCameraTypes(_ stringTypes: [String]) -> [AVCaptureDevice.DeviceType] {
|
|
55
55
|
return stringTypes.compactMap { convertToNativeCameraType($0) }
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
/// Creates a temporary file URL for storing captured images
|
|
59
|
+
public func createTempImageFile() throws -> URL {
|
|
60
|
+
let timestamp = Int(Date().timeIntervalSince1970 * 1000)
|
|
61
|
+
let fileName = "camera_capture_\(timestamp).jpg"
|
|
62
|
+
let tempDir = FileManager.default.temporaryDirectory
|
|
63
|
+
return tempDir.appendingPathComponent(fileName)
|
|
64
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-camera-view",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A Capacitor plugin for embedding a live camera feed directly into your app.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"prepublishOnly": "npm run build"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@capacitor/android": "^7.
|
|
52
|
-
"@capacitor/core": "^7.
|
|
51
|
+
"@capacitor/android": "^7.4.2",
|
|
52
|
+
"@capacitor/core": "^7.4.2",
|
|
53
53
|
"@capacitor/docgen": "^0.3.0",
|
|
54
|
-
"@capacitor/ios": "^7.
|
|
54
|
+
"@capacitor/ios": "^7.4.2",
|
|
55
55
|
"@commitlint/config-conventional": "^19.8.1",
|
|
56
56
|
"@ionic/eslint-config": "^0.4.0",
|
|
57
57
|
"@ionic/prettier-config": "^4.0.0",
|
|
@@ -60,18 +60,19 @@
|
|
|
60
60
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
61
61
|
"@semantic-release/git": "^10.0.1",
|
|
62
62
|
"@semantic-release/github": "^11.0.3",
|
|
63
|
-
"@semantic-release/npm": "^12.0.
|
|
63
|
+
"@semantic-release/npm": "^12.0.2",
|
|
64
64
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
65
66
|
"commitlint": "^19.8.1",
|
|
66
67
|
"eslint": "^8.57.0",
|
|
67
68
|
"husky": "^9.1.7",
|
|
68
|
-
"prettier": "^3.
|
|
69
|
-
"prettier-plugin-java": "^2.
|
|
69
|
+
"prettier": "^3.6.2",
|
|
70
|
+
"prettier-plugin-java": "^2.7.3",
|
|
70
71
|
"prettier-plugin-organize-imports": "^4.1.0",
|
|
71
|
-
"prettier-plugin-packagejson": "^2.5.
|
|
72
|
+
"prettier-plugin-packagejson": "^2.5.18",
|
|
72
73
|
"rimraf": "^6.0.1",
|
|
73
|
-
"rollup": "^4.
|
|
74
|
-
"semantic-release": "^24.2.
|
|
74
|
+
"rollup": "^4.45.1",
|
|
75
|
+
"semantic-release": "^24.2.7",
|
|
75
76
|
"swiftlint": "^2.0.0",
|
|
76
77
|
"typescript": "~4.1.5"
|
|
77
78
|
},
|