capacitor-community-multilens-camerapreview 0.0.3 → 0.0.5
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/CapacitorCommunityMultilensCamerapreview.podspec +17 -17
- package/README.md +16 -16
- package/android/build.gradle +55 -55
- package/android/src/main/AndroidManifest.xml +4 -4
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +1006 -1005
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +544 -544
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +23 -23
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +29 -29
- package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +386 -386
- package/android/src/main/java/com/ahm/capacitor/camera/preview/TapGestureDetector.java +24 -24
- package/android/src/main/res/layout/bridge_layout_main.xml +15 -15
- package/android/src/main/res/layout/camera_activity.xml +68 -68
- package/android/src/main/res/values/camera_ids.xml +4 -4
- package/android/src/main/res/values/camera_theme.xml +9 -9
- package/android/src/main/res/values/colors.xml +3 -3
- package/android/src/main/res/values/strings.xml +3 -3
- package/android/src/main/res/values/styles.xml +3 -3
- package/dist/docs.json +1 -1
- package/dist/esm/definitions.d.ts +80 -80
- package/dist/esm/definitions.js +1 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.js +6 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +28 -28
- package/dist/esm/web.js +155 -155
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +149 -149
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +149 -149
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/CameraController.swift +716 -716
- package/ios/Plugin/Info.plist +24 -24
- package/ios/Plugin/Plugin.h +10 -10
- package/ios/Plugin/Plugin.m +18 -18
- package/ios/Plugin/Plugin.swift +300 -300
- package/package.json +78 -78
package/ios/Plugin/Plugin.swift
CHANGED
|
@@ -1,300 +1,300 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
import Capacitor
|
|
3
|
-
import AVFoundation
|
|
4
|
-
/**
|
|
5
|
-
* Please read the Capacitor iOS Plugin Development Guide
|
|
6
|
-
* here: https://capacitor.ionicframework.com/docs/plugins/ios
|
|
7
|
-
*/
|
|
8
|
-
@objc(CameraPreview)
|
|
9
|
-
public class CameraPreview: CAPPlugin {
|
|
10
|
-
|
|
11
|
-
var previewView: UIView!
|
|
12
|
-
var cameraPosition = String()
|
|
13
|
-
let cameraController = CameraController()
|
|
14
|
-
var x: CGFloat?
|
|
15
|
-
var y: CGFloat?
|
|
16
|
-
var width: CGFloat?
|
|
17
|
-
var height: CGFloat?
|
|
18
|
-
var paddingBottom: CGFloat?
|
|
19
|
-
var rotateWhenOrientationChanged: Bool?
|
|
20
|
-
var toBack: Bool?
|
|
21
|
-
var storeToFile: Bool?
|
|
22
|
-
var enableZoom: Bool?
|
|
23
|
-
var highResolutionOutput: Bool = false
|
|
24
|
-
var disableAudio: Bool = false
|
|
25
|
-
var zoomFactor = String()
|
|
26
|
-
|
|
27
|
-
@objc func rotated() {
|
|
28
|
-
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!;
|
|
29
|
-
|
|
30
|
-
if UIApplication.shared.statusBarOrientation.isLandscape {
|
|
31
|
-
self.previewView.frame = CGRect(x: self.y!, y: self.x!, width: max(height, self.width!), height: min(height, self.width!))
|
|
32
|
-
self.cameraController.previewLayer?.frame = self.previewView.frame
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if UIApplication.shared.statusBarOrientation.isPortrait {
|
|
36
|
-
if (self.previewView != nil && self.x != nil && self.y != nil && self.width != nil && self.height != nil) {
|
|
37
|
-
self.previewView.frame = CGRect(x: self.x!, y: self.y!, width: min(height, self.width!), height: max(height, self.width!))
|
|
38
|
-
}
|
|
39
|
-
self.cameraController.previewLayer?.frame = self.previewView.frame
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
cameraController.updateVideoOrientation()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@objc func start(_ call: CAPPluginCall) {
|
|
46
|
-
self.cameraPosition = call.getString("position") ?? "rear"
|
|
47
|
-
self.zoomFactor = call.getString("zoomFactor") ?? "wide"
|
|
48
|
-
self.highResolutionOutput = call.getBool("enableHighResolution") ?? false
|
|
49
|
-
self.cameraController.highResolutionOutput = self.highResolutionOutput
|
|
50
|
-
if call.getInt("width") != nil {
|
|
51
|
-
self.width = CGFloat(call.getInt("width")!)
|
|
52
|
-
} else {
|
|
53
|
-
self.width = UIScreen.main.bounds.size.width
|
|
54
|
-
}
|
|
55
|
-
if call.getInt("height") != nil {
|
|
56
|
-
self.height = CGFloat(call.getInt("height")!)
|
|
57
|
-
} else {
|
|
58
|
-
self.height = UIScreen.main.bounds.size.height
|
|
59
|
-
}
|
|
60
|
-
self.x = call.getInt("x") != nil ? CGFloat(call.getInt("x")!)/UIScreen.main.scale: 0
|
|
61
|
-
self.y = call.getInt("y") != nil ? CGFloat(call.getInt("y")!)/UIScreen.main.scale: 0
|
|
62
|
-
if call.getInt("paddingBottom") != nil {
|
|
63
|
-
self.paddingBottom = CGFloat(call.getInt("paddingBottom")!)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
self.rotateWhenOrientationChanged = call.getBool("rotateWhenOrientationChanged") ?? true
|
|
67
|
-
self.toBack = call.getBool("toBack") ?? false
|
|
68
|
-
self.storeToFile = call.getBool("storeToFile") ?? false
|
|
69
|
-
self.enableZoom = call.getBool("enableZoom") ?? false
|
|
70
|
-
self.disableAudio = call.getBool("disableAudio") ?? false
|
|
71
|
-
|
|
72
|
-
AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
|
|
73
|
-
guard granted else {
|
|
74
|
-
call.reject("permission failed")
|
|
75
|
-
return
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
DispatchQueue.main.async {
|
|
79
|
-
if self.cameraController.captureSession?.isRunning ?? false {
|
|
80
|
-
call.reject("camera already started")
|
|
81
|
-
} else {
|
|
82
|
-
self.cameraController.prepare(cameraPosition: self.cameraPosition, zoomFactor: self.zoomFactor, disableAudio: self.disableAudio){error in
|
|
83
|
-
if let error = error {
|
|
84
|
-
print(error)
|
|
85
|
-
call.reject(error.localizedDescription)
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!
|
|
89
|
-
self.previewView = UIView(frame: CGRect(x: self.x ?? 0, y: self.y ?? 0, width: self.width!, height: height))
|
|
90
|
-
self.webView?.isOpaque = false
|
|
91
|
-
self.webView?.backgroundColor = UIColor.clear
|
|
92
|
-
self.webView?.scrollView.backgroundColor = UIColor.clear
|
|
93
|
-
self.webView?.superview?.addSubview(self.previewView)
|
|
94
|
-
if self.toBack! {
|
|
95
|
-
self.webView?.superview?.bringSubviewToFront(self.webView!)
|
|
96
|
-
}
|
|
97
|
-
try? self.cameraController.displayPreview(on: self.previewView)
|
|
98
|
-
|
|
99
|
-
let frontView = self.toBack! ? self.webView : self.previewView
|
|
100
|
-
self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
|
|
101
|
-
|
|
102
|
-
if self.rotateWhenOrientationChanged == true {
|
|
103
|
-
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
call.resolve()
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
@objc func flip(_ call: CAPPluginCall) {
|
|
116
|
-
do {
|
|
117
|
-
try self.cameraController.switchCameras()
|
|
118
|
-
call.resolve()
|
|
119
|
-
} catch {
|
|
120
|
-
call.reject("failed to flip camera")
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
@objc func stop(_ call: CAPPluginCall) {
|
|
125
|
-
DispatchQueue.main.async {
|
|
126
|
-
if self.cameraController.captureSession?.isRunning ?? false {
|
|
127
|
-
self.cameraController.captureSession?.stopRunning()
|
|
128
|
-
self.previewView.removeFromSuperview()
|
|
129
|
-
self.webView?.isOpaque = true
|
|
130
|
-
call.resolve()
|
|
131
|
-
} else {
|
|
132
|
-
call.reject("camera already stopped")
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// Get user's cache directory path
|
|
137
|
-
@objc func getTempFilePath() -> URL {
|
|
138
|
-
let path = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
139
|
-
let identifier = UUID()
|
|
140
|
-
let randomIdentifier = identifier.uuidString.replacingOccurrences(of: "-", with: "")
|
|
141
|
-
let finalIdentifier = String(randomIdentifier.prefix(8))
|
|
142
|
-
let fileName="cpcp_capture_"+finalIdentifier+".jpg"
|
|
143
|
-
let fileUrl=path.appendingPathComponent(fileName)
|
|
144
|
-
return fileUrl
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
@objc func capture(_ call: CAPPluginCall) {
|
|
148
|
-
DispatchQueue.main.async {
|
|
149
|
-
|
|
150
|
-
let quality: Int? = call.getInt("quality", 85)
|
|
151
|
-
|
|
152
|
-
self.cameraController.captureImage { (image, error) in
|
|
153
|
-
|
|
154
|
-
guard let image = image else {
|
|
155
|
-
print(error ?? "Image capture error")
|
|
156
|
-
guard let error = error else {
|
|
157
|
-
call.reject("Image capture error")
|
|
158
|
-
return
|
|
159
|
-
}
|
|
160
|
-
call.reject(error.localizedDescription)
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
let imageData: Data?
|
|
164
|
-
if self.cameraController.currentCameraPosition == .front {
|
|
165
|
-
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
166
|
-
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
167
|
-
} else {
|
|
168
|
-
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if self.storeToFile == false {
|
|
172
|
-
let imageBase64 = imageData?.base64EncodedString()
|
|
173
|
-
call.resolve(["value": imageBase64!])
|
|
174
|
-
} else {
|
|
175
|
-
do {
|
|
176
|
-
let fileUrl=self.getTempFilePath()
|
|
177
|
-
try imageData?.write(to: fileUrl)
|
|
178
|
-
call.resolve(["value": fileUrl.absoluteString])
|
|
179
|
-
} catch {
|
|
180
|
-
call.reject("error writing image to file")
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
@objc func captureSample(_ call: CAPPluginCall) {
|
|
188
|
-
DispatchQueue.main.async {
|
|
189
|
-
let quality: Int? = call.getInt("quality", 85)
|
|
190
|
-
|
|
191
|
-
self.cameraController.captureSample { image, error in
|
|
192
|
-
guard let image = image else {
|
|
193
|
-
print("Image capture error: \(String(describing: error))")
|
|
194
|
-
call.reject("Image capture error: \(String(describing: error))")
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
let imageData: Data?
|
|
199
|
-
if self.cameraPosition == "front" {
|
|
200
|
-
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
201
|
-
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
202
|
-
} else {
|
|
203
|
-
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if self.storeToFile == false {
|
|
207
|
-
let imageBase64 = imageData?.base64EncodedString()
|
|
208
|
-
call.resolve(["value": imageBase64!])
|
|
209
|
-
} else {
|
|
210
|
-
do {
|
|
211
|
-
let fileUrl = self.getTempFilePath()
|
|
212
|
-
try imageData?.write(to: fileUrl)
|
|
213
|
-
call.resolve(["value": fileUrl.absoluteString])
|
|
214
|
-
} catch {
|
|
215
|
-
call.reject("Error writing image to file")
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
@objc func getSupportedFlashModes(_ call: CAPPluginCall) {
|
|
223
|
-
do {
|
|
224
|
-
let supportedFlashModes = try self.cameraController.getSupportedFlashModes()
|
|
225
|
-
call.resolve(["result": supportedFlashModes])
|
|
226
|
-
} catch {
|
|
227
|
-
call.reject("failed to get supported flash modes")
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
@objc func getSupportedZoomLevels(_ call: CAPPluginCall) {
|
|
231
|
-
do {
|
|
232
|
-
let supportedCameras = try self.cameraController.getSupportedCameras()
|
|
233
|
-
call.resolve(["result": supportedCameras])
|
|
234
|
-
} catch {
|
|
235
|
-
call.reject("failed to get supported cameras")
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
@objc func setFlashMode(_ call: CAPPluginCall) {
|
|
240
|
-
guard let flashMode = call.getString("flashMode") else {
|
|
241
|
-
call.reject("failed to set flash mode. required parameter flashMode is missing")
|
|
242
|
-
return
|
|
243
|
-
}
|
|
244
|
-
do {
|
|
245
|
-
var flashModeAsEnum: AVCaptureDevice.FlashMode?
|
|
246
|
-
switch flashMode {
|
|
247
|
-
case "off" :
|
|
248
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.off
|
|
249
|
-
case "on":
|
|
250
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.on
|
|
251
|
-
case "auto":
|
|
252
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.auto
|
|
253
|
-
default: break
|
|
254
|
-
}
|
|
255
|
-
if flashModeAsEnum != nil {
|
|
256
|
-
try self.cameraController.setFlashMode(flashMode: flashModeAsEnum!)
|
|
257
|
-
} else if flashMode == "torch" {
|
|
258
|
-
try self.cameraController.setTorchMode()
|
|
259
|
-
} else {
|
|
260
|
-
call.reject("Flash Mode not supported")
|
|
261
|
-
return
|
|
262
|
-
}
|
|
263
|
-
call.resolve()
|
|
264
|
-
} catch {
|
|
265
|
-
call.reject("failed to set flash mode")
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
@objc func startRecordVideo(_ call: CAPPluginCall) {
|
|
270
|
-
DispatchQueue.main.async {
|
|
271
|
-
|
|
272
|
-
let quality: Int? = call.getInt("quality", 85)
|
|
273
|
-
|
|
274
|
-
self.cameraController.captureVideo { (image, error) in
|
|
275
|
-
|
|
276
|
-
guard let image = image else {
|
|
277
|
-
print(error ?? "Image capture error")
|
|
278
|
-
guard let error = error else {
|
|
279
|
-
call.reject("Image capture error")
|
|
280
|
-
return
|
|
281
|
-
}
|
|
282
|
-
call.reject(error.localizedDescription)
|
|
283
|
-
return
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// self.videoUrl = image
|
|
287
|
-
|
|
288
|
-
call.resolve(["value": image.absoluteString])
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
@objc func stopRecordVideo(_ call: CAPPluginCall) {
|
|
294
|
-
|
|
295
|
-
self.cameraController.stopRecording { (_) in
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
}
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import AVFoundation
|
|
4
|
+
/**
|
|
5
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
|
6
|
+
* here: https://capacitor.ionicframework.com/docs/plugins/ios
|
|
7
|
+
*/
|
|
8
|
+
@objc(CameraPreview)
|
|
9
|
+
public class CameraPreview: CAPPlugin {
|
|
10
|
+
|
|
11
|
+
var previewView: UIView!
|
|
12
|
+
var cameraPosition = String()
|
|
13
|
+
let cameraController = CameraController()
|
|
14
|
+
var x: CGFloat?
|
|
15
|
+
var y: CGFloat?
|
|
16
|
+
var width: CGFloat?
|
|
17
|
+
var height: CGFloat?
|
|
18
|
+
var paddingBottom: CGFloat?
|
|
19
|
+
var rotateWhenOrientationChanged: Bool?
|
|
20
|
+
var toBack: Bool?
|
|
21
|
+
var storeToFile: Bool?
|
|
22
|
+
var enableZoom: Bool?
|
|
23
|
+
var highResolutionOutput: Bool = false
|
|
24
|
+
var disableAudio: Bool = false
|
|
25
|
+
var zoomFactor = String()
|
|
26
|
+
|
|
27
|
+
@objc func rotated() {
|
|
28
|
+
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!;
|
|
29
|
+
|
|
30
|
+
if UIApplication.shared.statusBarOrientation.isLandscape {
|
|
31
|
+
self.previewView.frame = CGRect(x: self.y!, y: self.x!, width: max(height, self.width!), height: min(height, self.width!))
|
|
32
|
+
self.cameraController.previewLayer?.frame = self.previewView.frame
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if UIApplication.shared.statusBarOrientation.isPortrait {
|
|
36
|
+
if (self.previewView != nil && self.x != nil && self.y != nil && self.width != nil && self.height != nil) {
|
|
37
|
+
self.previewView.frame = CGRect(x: self.x!, y: self.y!, width: min(height, self.width!), height: max(height, self.width!))
|
|
38
|
+
}
|
|
39
|
+
self.cameraController.previewLayer?.frame = self.previewView.frame
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
cameraController.updateVideoOrientation()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@objc func start(_ call: CAPPluginCall) {
|
|
46
|
+
self.cameraPosition = call.getString("position") ?? "rear"
|
|
47
|
+
self.zoomFactor = call.getString("zoomFactor") ?? "wide"
|
|
48
|
+
self.highResolutionOutput = call.getBool("enableHighResolution") ?? false
|
|
49
|
+
self.cameraController.highResolutionOutput = self.highResolutionOutput
|
|
50
|
+
if call.getInt("width") != nil {
|
|
51
|
+
self.width = CGFloat(call.getInt("width")!)
|
|
52
|
+
} else {
|
|
53
|
+
self.width = UIScreen.main.bounds.size.width
|
|
54
|
+
}
|
|
55
|
+
if call.getInt("height") != nil {
|
|
56
|
+
self.height = CGFloat(call.getInt("height")!)
|
|
57
|
+
} else {
|
|
58
|
+
self.height = UIScreen.main.bounds.size.height
|
|
59
|
+
}
|
|
60
|
+
self.x = call.getInt("x") != nil ? CGFloat(call.getInt("x")!)/UIScreen.main.scale: 0
|
|
61
|
+
self.y = call.getInt("y") != nil ? CGFloat(call.getInt("y")!)/UIScreen.main.scale: 0
|
|
62
|
+
if call.getInt("paddingBottom") != nil {
|
|
63
|
+
self.paddingBottom = CGFloat(call.getInt("paddingBottom")!)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
self.rotateWhenOrientationChanged = call.getBool("rotateWhenOrientationChanged") ?? true
|
|
67
|
+
self.toBack = call.getBool("toBack") ?? false
|
|
68
|
+
self.storeToFile = call.getBool("storeToFile") ?? false
|
|
69
|
+
self.enableZoom = call.getBool("enableZoom") ?? false
|
|
70
|
+
self.disableAudio = call.getBool("disableAudio") ?? false
|
|
71
|
+
|
|
72
|
+
AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
|
|
73
|
+
guard granted else {
|
|
74
|
+
call.reject("permission failed")
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
DispatchQueue.main.async {
|
|
79
|
+
if self.cameraController.captureSession?.isRunning ?? false {
|
|
80
|
+
call.reject("camera already started")
|
|
81
|
+
} else {
|
|
82
|
+
self.cameraController.prepare(cameraPosition: self.cameraPosition, zoomFactor: self.zoomFactor, disableAudio: self.disableAudio){error in
|
|
83
|
+
if let error = error {
|
|
84
|
+
print(error)
|
|
85
|
+
call.reject(error.localizedDescription)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!
|
|
89
|
+
self.previewView = UIView(frame: CGRect(x: self.x ?? 0, y: self.y ?? 0, width: self.width!, height: height))
|
|
90
|
+
self.webView?.isOpaque = false
|
|
91
|
+
self.webView?.backgroundColor = UIColor.clear
|
|
92
|
+
self.webView?.scrollView.backgroundColor = UIColor.clear
|
|
93
|
+
self.webView?.superview?.addSubview(self.previewView)
|
|
94
|
+
if self.toBack! {
|
|
95
|
+
self.webView?.superview?.bringSubviewToFront(self.webView!)
|
|
96
|
+
}
|
|
97
|
+
try? self.cameraController.displayPreview(on: self.previewView)
|
|
98
|
+
|
|
99
|
+
let frontView = self.toBack! ? self.webView : self.previewView
|
|
100
|
+
self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
|
|
101
|
+
|
|
102
|
+
if self.rotateWhenOrientationChanged == true {
|
|
103
|
+
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
call.resolve()
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@objc func flip(_ call: CAPPluginCall) {
|
|
116
|
+
do {
|
|
117
|
+
try self.cameraController.switchCameras()
|
|
118
|
+
call.resolve()
|
|
119
|
+
} catch {
|
|
120
|
+
call.reject("failed to flip camera")
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@objc func stop(_ call: CAPPluginCall) {
|
|
125
|
+
DispatchQueue.main.async {
|
|
126
|
+
if self.cameraController.captureSession?.isRunning ?? false {
|
|
127
|
+
self.cameraController.captureSession?.stopRunning()
|
|
128
|
+
self.previewView.removeFromSuperview()
|
|
129
|
+
self.webView?.isOpaque = true
|
|
130
|
+
call.resolve()
|
|
131
|
+
} else {
|
|
132
|
+
call.reject("camera already stopped")
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Get user's cache directory path
|
|
137
|
+
@objc func getTempFilePath() -> URL {
|
|
138
|
+
let path = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
139
|
+
let identifier = UUID()
|
|
140
|
+
let randomIdentifier = identifier.uuidString.replacingOccurrences(of: "-", with: "")
|
|
141
|
+
let finalIdentifier = String(randomIdentifier.prefix(8))
|
|
142
|
+
let fileName="cpcp_capture_"+finalIdentifier+".jpg"
|
|
143
|
+
let fileUrl=path.appendingPathComponent(fileName)
|
|
144
|
+
return fileUrl
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@objc func capture(_ call: CAPPluginCall) {
|
|
148
|
+
DispatchQueue.main.async {
|
|
149
|
+
|
|
150
|
+
let quality: Int? = call.getInt("quality", 85)
|
|
151
|
+
|
|
152
|
+
self.cameraController.captureImage { (image, error) in
|
|
153
|
+
|
|
154
|
+
guard let image = image else {
|
|
155
|
+
print(error ?? "Image capture error")
|
|
156
|
+
guard let error = error else {
|
|
157
|
+
call.reject("Image capture error")
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
call.reject(error.localizedDescription)
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
let imageData: Data?
|
|
164
|
+
if self.cameraController.currentCameraPosition == .front {
|
|
165
|
+
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
166
|
+
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
167
|
+
} else {
|
|
168
|
+
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if self.storeToFile == false {
|
|
172
|
+
let imageBase64 = imageData?.base64EncodedString()
|
|
173
|
+
call.resolve(["value": imageBase64!])
|
|
174
|
+
} else {
|
|
175
|
+
do {
|
|
176
|
+
let fileUrl=self.getTempFilePath()
|
|
177
|
+
try imageData?.write(to: fileUrl)
|
|
178
|
+
call.resolve(["value": fileUrl.absoluteString])
|
|
179
|
+
} catch {
|
|
180
|
+
call.reject("error writing image to file")
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@objc func captureSample(_ call: CAPPluginCall) {
|
|
188
|
+
DispatchQueue.main.async {
|
|
189
|
+
let quality: Int? = call.getInt("quality", 85)
|
|
190
|
+
|
|
191
|
+
self.cameraController.captureSample { image, error in
|
|
192
|
+
guard let image = image else {
|
|
193
|
+
print("Image capture error: \(String(describing: error))")
|
|
194
|
+
call.reject("Image capture error: \(String(describing: error))")
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let imageData: Data?
|
|
199
|
+
if self.cameraPosition == "front" {
|
|
200
|
+
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
201
|
+
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
202
|
+
} else {
|
|
203
|
+
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if self.storeToFile == false {
|
|
207
|
+
let imageBase64 = imageData?.base64EncodedString()
|
|
208
|
+
call.resolve(["value": imageBase64!])
|
|
209
|
+
} else {
|
|
210
|
+
do {
|
|
211
|
+
let fileUrl = self.getTempFilePath()
|
|
212
|
+
try imageData?.write(to: fileUrl)
|
|
213
|
+
call.resolve(["value": fileUrl.absoluteString])
|
|
214
|
+
} catch {
|
|
215
|
+
call.reject("Error writing image to file")
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@objc func getSupportedFlashModes(_ call: CAPPluginCall) {
|
|
223
|
+
do {
|
|
224
|
+
let supportedFlashModes = try self.cameraController.getSupportedFlashModes()
|
|
225
|
+
call.resolve(["result": supportedFlashModes])
|
|
226
|
+
} catch {
|
|
227
|
+
call.reject("failed to get supported flash modes")
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
@objc func getSupportedZoomLevels(_ call: CAPPluginCall) {
|
|
231
|
+
do {
|
|
232
|
+
let supportedCameras = try self.cameraController.getSupportedCameras()
|
|
233
|
+
call.resolve(["result": supportedCameras])
|
|
234
|
+
} catch {
|
|
235
|
+
call.reject("failed to get supported cameras")
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@objc func setFlashMode(_ call: CAPPluginCall) {
|
|
240
|
+
guard let flashMode = call.getString("flashMode") else {
|
|
241
|
+
call.reject("failed to set flash mode. required parameter flashMode is missing")
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
do {
|
|
245
|
+
var flashModeAsEnum: AVCaptureDevice.FlashMode?
|
|
246
|
+
switch flashMode {
|
|
247
|
+
case "off" :
|
|
248
|
+
flashModeAsEnum = AVCaptureDevice.FlashMode.off
|
|
249
|
+
case "on":
|
|
250
|
+
flashModeAsEnum = AVCaptureDevice.FlashMode.on
|
|
251
|
+
case "auto":
|
|
252
|
+
flashModeAsEnum = AVCaptureDevice.FlashMode.auto
|
|
253
|
+
default: break
|
|
254
|
+
}
|
|
255
|
+
if flashModeAsEnum != nil {
|
|
256
|
+
try self.cameraController.setFlashMode(flashMode: flashModeAsEnum!)
|
|
257
|
+
} else if flashMode == "torch" {
|
|
258
|
+
try self.cameraController.setTorchMode()
|
|
259
|
+
} else {
|
|
260
|
+
call.reject("Flash Mode not supported")
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
call.resolve()
|
|
264
|
+
} catch {
|
|
265
|
+
call.reject("failed to set flash mode")
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@objc func startRecordVideo(_ call: CAPPluginCall) {
|
|
270
|
+
DispatchQueue.main.async {
|
|
271
|
+
|
|
272
|
+
let quality: Int? = call.getInt("quality", 85)
|
|
273
|
+
|
|
274
|
+
self.cameraController.captureVideo { (image, error) in
|
|
275
|
+
|
|
276
|
+
guard let image = image else {
|
|
277
|
+
print(error ?? "Image capture error")
|
|
278
|
+
guard let error = error else {
|
|
279
|
+
call.reject("Image capture error")
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
call.reject(error.localizedDescription)
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// self.videoUrl = image
|
|
287
|
+
|
|
288
|
+
call.resolve(["value": image.absoluteString])
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
@objc func stopRecordVideo(_ call: CAPPluginCall) {
|
|
294
|
+
|
|
295
|
+
self.cameraController.stopRecording { (_) in
|
|
296
|
+
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
}
|