expo-camera 16.0.1 → 16.0.3
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/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 16.0.3 — 2024-10-28
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- [iOS] Fix build issue with after switch to Swift concurrency. ([#32379](https://github.com/expo/expo/pull/32379) by [@Eingin](https://github.com/Eingin))
|
|
18
|
+
|
|
19
|
+
## 16.0.2 — 2024-10-25
|
|
20
|
+
|
|
21
|
+
_This version does not introduce any user-facing changes._
|
|
22
|
+
|
|
13
23
|
## 16.0.1 — 2024-10-24
|
|
14
24
|
|
|
15
25
|
_This version does not introduce any user-facing changes._
|
|
@@ -33,6 +43,8 @@ _This version does not introduce any user-facing changes._
|
|
|
33
43
|
- Fixed issue regarding using the "back"-facing on mobile web browswer. ([#30811](https://github.com/expo/expo/pull/30811) by [@entiendoNull](https://github.com/entiendoNull))
|
|
34
44
|
- Fix `takePictureAsync` `quality` option when set to 0. ([#31587](https://github.com/expo/expo/pull/31587) by [@davidavz](https://github.com/davidavz))
|
|
35
45
|
- [iOS] Fix crash related to `sublayers` on 0.75 and above on the new architecture. ([#32194](https://github.com/expo/expo/pull/32194) by [@alanjhughes](https://github.com/alanjhughes))
|
|
46
|
+
- [iOS] Fix regression in running the cameras cleanup function. ([#32333](https://github.com/expo/expo/pull/32333) by [@alanjhughes](https://github.com/alanjhughes))
|
|
47
|
+
- [iOS] Use an `Actor` to ensure correct order of changes to the barcode scanners outputs. ([#32353](https://github.com/expo/expo/pull/32353) by [@alanjhughes](https://github.com/alanjhughes))
|
|
36
48
|
|
|
37
49
|
### 💡 Others
|
|
38
50
|
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'host.exp.exponent'
|
|
4
|
-
version = '16.0.
|
|
4
|
+
version = '16.0.3'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -14,7 +14,7 @@ android {
|
|
|
14
14
|
namespace "expo.modules.camera"
|
|
15
15
|
defaultConfig {
|
|
16
16
|
versionCode 32
|
|
17
|
-
versionName "16.0.
|
|
17
|
+
versionName "16.0.3"
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -3,8 +3,8 @@ import AVFoundation
|
|
|
3
3
|
|
|
4
4
|
let BARCODE_TYPES_KEY = "barcodeTypes"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
var onBarcodeScanned: (([String: Any]?) -> Void)?
|
|
6
|
+
actor BarcodeScanner: NSObject, BarcodeScanningResponseHandler {
|
|
7
|
+
private var onBarcodeScanned: (([String: Any]?) -> Void)?
|
|
8
8
|
var isScanningBarcodes = false
|
|
9
9
|
|
|
10
10
|
// MARK: - Properties
|
|
@@ -21,8 +21,8 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
21
21
|
AVMetadataObject.ObjectType.code39: ZXCode39Reader()
|
|
22
22
|
]
|
|
23
23
|
private var previewLayer: AVCaptureVideoPreviewLayer?
|
|
24
|
-
private var zxingFPSProcessed = 6.0
|
|
25
24
|
private var zxingEnabled = true
|
|
25
|
+
private var delegate: MetatDataDelegate?
|
|
26
26
|
|
|
27
27
|
init(session: AVCaptureSession, sessionQueue: DispatchQueue) {
|
|
28
28
|
self.session = session
|
|
@@ -42,7 +42,7 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
42
42
|
let zxingCoveredTypes = Set(zxingBarcodeReaders.keys)
|
|
43
43
|
zxingEnabled = !zxingCoveredTypes.isDisjoint(with: newTypes)
|
|
44
44
|
Task {
|
|
45
|
-
await
|
|
45
|
+
await maybeStartBarcodeScanning()
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -52,23 +52,21 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
52
52
|
self.previewLayer = layer
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
func setIsEnabled(_ enabled: Bool) {
|
|
55
|
+
func setIsEnabled(_ enabled: Bool) async {
|
|
56
56
|
guard isScanningBarcodes != enabled else {
|
|
57
57
|
return
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
isScanningBarcodes = enabled
|
|
61
|
-
|
|
62
|
-
if
|
|
63
|
-
|
|
64
|
-
setConnection(enabled: true)
|
|
65
|
-
} else {
|
|
66
|
-
await maybeStartBarcodeScanning()
|
|
67
|
-
}
|
|
61
|
+
if isScanningBarcodes {
|
|
62
|
+
if metadataOutput != nil {
|
|
63
|
+
setConnection(enabled: true)
|
|
68
64
|
} else {
|
|
69
|
-
|
|
70
|
-
await stopBarcodeScanning()
|
|
65
|
+
await maybeStartBarcodeScanning()
|
|
71
66
|
}
|
|
67
|
+
} else {
|
|
68
|
+
setConnection(enabled: false)
|
|
69
|
+
await stopBarcodeScanning()
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
@@ -78,6 +76,10 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
79
|
+
func setOnBarcodeScanned(_ onBarcodeScanned: @escaping ([String: Any]?) -> Void) {
|
|
80
|
+
self.onBarcodeScanned = onBarcodeScanned
|
|
81
|
+
}
|
|
82
|
+
|
|
81
83
|
func maybeStartBarcodeScanning() async {
|
|
82
84
|
guard isScanningBarcodes else {
|
|
83
85
|
return
|
|
@@ -105,43 +107,20 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
func scanBarcodes(from image: CGImage, completion: @escaping (ZXResult) -> Void) {
|
|
109
|
-
let source = ZXCGImageLuminanceSource(cgImage: image)
|
|
110
|
-
let binarizer = ZXHybridBinarizer(source: source)
|
|
111
|
-
let bitmap = ZXBinaryBitmap(binarizer: binarizer)
|
|
112
|
-
|
|
113
|
-
var result: ZXResult?
|
|
114
|
-
|
|
115
|
-
for reader in zxingBarcodeReaders.values {
|
|
116
|
-
result = try? reader.decode(bitmap, hints: nil)
|
|
117
|
-
if result != nil {
|
|
118
|
-
break
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if result == nil && bitmap?.rotateSupported == true {
|
|
123
|
-
if let rotatedBitmap = bitmap?.rotateCounterClockwise() {
|
|
124
|
-
for reader in zxingBarcodeReaders.values {
|
|
125
|
-
result = try? reader.decode(rotatedBitmap, hints: nil)
|
|
126
|
-
if result != nil {
|
|
127
|
-
break
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if let result {
|
|
134
|
-
completion(result)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
110
|
private func addOutputs() async {
|
|
139
111
|
session.beginConfiguration()
|
|
140
112
|
defer { session.commitConfiguration() }
|
|
141
113
|
|
|
114
|
+
delegate = MetatDataDelegate(
|
|
115
|
+
settings: settings,
|
|
116
|
+
previewLayer: previewLayer,
|
|
117
|
+
zxingBarcodeReaders: zxingBarcodeReaders,
|
|
118
|
+
zxingEnabled: zxingEnabled,
|
|
119
|
+
metadataResultHandler: self)
|
|
120
|
+
|
|
142
121
|
if metadataOutput == nil {
|
|
143
122
|
let output = AVCaptureMetadataOutput()
|
|
144
|
-
output.setMetadataObjectsDelegate(
|
|
123
|
+
output.setMetadataObjectsDelegate(delegate, queue: sessionQueue)
|
|
145
124
|
if session.canAddOutput(output) {
|
|
146
125
|
session.addOutput(output)
|
|
147
126
|
metadataOutput = output
|
|
@@ -152,7 +131,7 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
152
131
|
let output = AVCaptureVideoDataOutput()
|
|
153
132
|
output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]
|
|
154
133
|
output.alwaysDiscardsLateVideoFrames = true
|
|
155
|
-
output.setSampleBufferDelegate(
|
|
134
|
+
output.setSampleBufferDelegate(delegate, queue: zxingCaptureQueue)
|
|
156
135
|
if session.canAddOutput(output) {
|
|
157
136
|
session.addOutput(output)
|
|
158
137
|
videoDataOutput = output
|
|
@@ -179,55 +158,7 @@ class BarcodeScanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptur
|
|
|
179
158
|
}
|
|
180
159
|
}
|
|
181
160
|
|
|
182
|
-
func
|
|
183
|
-
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
for metadata in metadataObjects {
|
|
188
|
-
var codeMetadata = metadata as? AVMetadataMachineReadableCodeObject
|
|
189
|
-
if let previewLayer {
|
|
190
|
-
codeMetadata = previewLayer.transformedMetadataObject(for: metadata) as? AVMetadataMachineReadableCodeObject
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
for barcodeType in settings {
|
|
194
|
-
if zxingBarcodeReaders[barcodeType] != nil {
|
|
195
|
-
continue
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if let codeMetadata {
|
|
199
|
-
if codeMetadata.stringValue != nil && codeMetadata.type == barcodeType {
|
|
200
|
-
onBarcodeScanned?(BarcodeScannerUtils.avMetadataCodeObjectToDictionary(codeMetadata))
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
208
|
-
guard let barcodeTypes = settings[BARCODE_TYPES_KEY],
|
|
209
|
-
let metadataOutput,
|
|
210
|
-
zxingEnabled else {
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
let kMinMargin = 1.0 / zxingFPSProcessed
|
|
215
|
-
let presentTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
|
216
|
-
|
|
217
|
-
var curFrameTimeStamp = 0.0
|
|
218
|
-
var lastFrameTimeStamp = 0.0
|
|
219
|
-
|
|
220
|
-
curFrameTimeStamp = Double(presentTimeStamp.value) / Double(presentTimeStamp.timescale)
|
|
221
|
-
|
|
222
|
-
if curFrameTimeStamp - lastFrameTimeStamp > Double(kMinMargin) {
|
|
223
|
-
lastFrameTimeStamp = curFrameTimeStamp
|
|
224
|
-
|
|
225
|
-
if let videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer),
|
|
226
|
-
let videoFrameImage = ZXCGImageLuminanceSource.createImage(from: videoFrame) {
|
|
227
|
-
self.scanBarcodes(from: videoFrameImage) { barcodeScannerResult in
|
|
228
|
-
self.onBarcodeScanned?(BarcodeScannerUtils.zxResultToDictionary(barcodeScannerResult))
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
161
|
+
func onScanningResult(_ result: [String: Any]) {
|
|
162
|
+
self.onBarcodeScanned?(result)
|
|
232
163
|
}
|
|
233
164
|
}
|
|
@@ -49,7 +49,9 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
49
49
|
|
|
50
50
|
var isScanningBarcodes = false {
|
|
51
51
|
didSet {
|
|
52
|
-
|
|
52
|
+
Task {
|
|
53
|
+
await barcodeScanner.setIsEnabled(isScanningBarcodes)
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -145,7 +147,7 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
145
147
|
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
|
|
146
148
|
NotificationCenter.default.addObserver(
|
|
147
149
|
self,
|
|
148
|
-
selector: #selector(orientationChanged
|
|
150
|
+
selector: #selector(orientationChanged),
|
|
149
151
|
name: UIDevice.orientationDidChangeNotification,
|
|
150
152
|
object: nil)
|
|
151
153
|
lifecycleManager?.register(self)
|
|
@@ -303,7 +305,9 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
303
305
|
}
|
|
304
306
|
|
|
305
307
|
func setBarcodeScannerSettings(settings: BarcodeSettings) {
|
|
306
|
-
|
|
308
|
+
Task {
|
|
309
|
+
await barcodeScanner.setSettings([BARCODE_TYPES_KEY: settings.toMetadataObjectType()])
|
|
310
|
+
}
|
|
307
311
|
}
|
|
308
312
|
|
|
309
313
|
func updateResponsiveOrientation() {
|
|
@@ -592,12 +596,6 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
592
596
|
}
|
|
593
597
|
}
|
|
594
598
|
|
|
595
|
-
public override func didMoveToWindow() {
|
|
596
|
-
if window == nil {
|
|
597
|
-
cleanupCamera()
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
599
|
func updateSessionAudioIsMuted() async {
|
|
602
600
|
session.beginConfiguration()
|
|
603
601
|
defer { session.commitConfiguration() }
|
|
@@ -655,12 +653,12 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
655
653
|
self.layer.insertSublayer(previewLayer, at: 0)
|
|
656
654
|
}
|
|
657
655
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
lifecycleManager?.unregisterAppLifecycleListener(self)
|
|
656
|
+
public override func removeFromSuperview() {
|
|
657
|
+
super.removeFromSuperview()
|
|
661
658
|
Task {
|
|
662
659
|
await stopSession()
|
|
663
660
|
}
|
|
661
|
+
lifecycleManager?.unregisterAppLifecycleListener(self)
|
|
664
662
|
UIDevice.current.endGeneratingDeviceOrientationNotifications()
|
|
665
663
|
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
666
664
|
}
|
|
@@ -751,8 +749,6 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
751
749
|
#if targetEnvironment(simulator)
|
|
752
750
|
return
|
|
753
751
|
#endif
|
|
754
|
-
// self.previewLayer.layer.removeFromSuperlayer()
|
|
755
|
-
|
|
756
752
|
session.beginConfiguration()
|
|
757
753
|
for input in self.session.inputs {
|
|
758
754
|
session.removeInput(input)
|
|
@@ -778,8 +774,10 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
778
774
|
previewLayer.connection?.isEnabled = false
|
|
779
775
|
}
|
|
780
776
|
|
|
781
|
-
@objc func orientationChanged(
|
|
782
|
-
|
|
777
|
+
@objc func orientationChanged() {
|
|
778
|
+
Task {
|
|
779
|
+
await changePreviewOrientation()
|
|
780
|
+
}
|
|
783
781
|
}
|
|
784
782
|
|
|
785
783
|
@MainActor
|
|
@@ -794,13 +792,16 @@ public class CameraView: ExpoView, EXAppLifecycleListener,
|
|
|
794
792
|
|
|
795
793
|
private func createBarcodeScanner() -> BarcodeScanner {
|
|
796
794
|
let scanner = BarcodeScanner(session: session, sessionQueue: sessionQueue)
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
795
|
+
|
|
796
|
+
Task {
|
|
797
|
+
await scanner.setPreviewLayer(layer: previewLayer)
|
|
798
|
+
await scanner.setOnBarcodeScanned { [weak self] body in
|
|
799
|
+
guard let self else {
|
|
800
|
+
return
|
|
801
|
+
}
|
|
802
|
+
if let body {
|
|
803
|
+
self.onBarcodeScanned(body)
|
|
804
|
+
}
|
|
804
805
|
}
|
|
805
806
|
}
|
|
806
807
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import ZXingObjC
|
|
2
|
+
|
|
3
|
+
protocol BarcodeScanningResponseHandler {
|
|
4
|
+
func onScanningResult(_ result: [String: Any]) async
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class MetatDataDelegate: NSObject, AVCaptureMetadataOutputObjectsDelegate, AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
8
|
+
private var settings: [String: [AVMetadataObject.ObjectType]]
|
|
9
|
+
private var previewLayer: AVCaptureVideoPreviewLayer?
|
|
10
|
+
private var zxingBarcodeReaders: [AVMetadataObject.ObjectType: ZXReader]
|
|
11
|
+
private var zxingEnabled = true
|
|
12
|
+
private var zxingFPSProcessed = 6.0
|
|
13
|
+
private let responseHandler: BarcodeScanningResponseHandler
|
|
14
|
+
|
|
15
|
+
init(
|
|
16
|
+
settings: [String: [AVMetadataObject.ObjectType]],
|
|
17
|
+
previewLayer: AVCaptureVideoPreviewLayer?,
|
|
18
|
+
zxingBarcodeReaders: [AVMetadataObject.ObjectType: ZXReader],
|
|
19
|
+
zxingEnabled: Bool,
|
|
20
|
+
metadataResultHandler: BarcodeScanningResponseHandler
|
|
21
|
+
) {
|
|
22
|
+
self.settings = settings
|
|
23
|
+
self.previewLayer = previewLayer
|
|
24
|
+
self.zxingEnabled = zxingEnabled
|
|
25
|
+
self.responseHandler = metadataResultHandler
|
|
26
|
+
self.zxingBarcodeReaders = zxingBarcodeReaders
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
|
|
30
|
+
guard let settings = settings[BARCODE_TYPES_KEY] else {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for metadata in metadataObjects {
|
|
35
|
+
var codeMetadata = metadata as? AVMetadataMachineReadableCodeObject
|
|
36
|
+
if let previewLayer {
|
|
37
|
+
codeMetadata = previewLayer.transformedMetadataObject(for: metadata) as? AVMetadataMachineReadableCodeObject
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for barcodeType in settings {
|
|
41
|
+
if zxingBarcodeReaders[barcodeType] != nil {
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if let codeMetadata {
|
|
46
|
+
if codeMetadata.stringValue != nil && codeMetadata.type == barcodeType {
|
|
47
|
+
Task {
|
|
48
|
+
await responseHandler.onScanningResult(BarcodeScannerUtils.avMetadataCodeObjectToDictionary(codeMetadata))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
57
|
+
guard zxingEnabled else {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let kMinMargin = 1.0 / zxingFPSProcessed
|
|
62
|
+
let presentTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
|
63
|
+
|
|
64
|
+
var curFrameTimeStamp = 0.0
|
|
65
|
+
var lastFrameTimeStamp = 0.0
|
|
66
|
+
|
|
67
|
+
curFrameTimeStamp = Double(presentTimeStamp.value) / Double(presentTimeStamp.timescale)
|
|
68
|
+
|
|
69
|
+
if curFrameTimeStamp - lastFrameTimeStamp > Double(kMinMargin) {
|
|
70
|
+
lastFrameTimeStamp = curFrameTimeStamp
|
|
71
|
+
|
|
72
|
+
if let videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer),
|
|
73
|
+
let videoFrameImage = ZXCGImageLuminanceSource.createImage(from: videoFrame) {
|
|
74
|
+
self.scanBarcodes(from: videoFrameImage) { barcodeScannerResult in
|
|
75
|
+
Task {
|
|
76
|
+
await self.responseHandler.onScanningResult(BarcodeScannerUtils.zxResultToDictionary(barcodeScannerResult))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func scanBarcodes(from image: CGImage, completion: @escaping (ZXResult) -> Void) {
|
|
84
|
+
let source = ZXCGImageLuminanceSource(cgImage: image)
|
|
85
|
+
let binarizer = ZXHybridBinarizer(source: source)
|
|
86
|
+
let bitmap = ZXBinaryBitmap(binarizer: binarizer)
|
|
87
|
+
|
|
88
|
+
var result: ZXResult?
|
|
89
|
+
|
|
90
|
+
for reader in zxingBarcodeReaders.values {
|
|
91
|
+
result = try? reader.decode(bitmap, hints: nil)
|
|
92
|
+
if result != nil {
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if result == nil && bitmap?.rotateSupported == true {
|
|
98
|
+
if let rotatedBitmap = bitmap?.rotateCounterClockwise() {
|
|
99
|
+
for reader in zxingBarcodeReaders.values {
|
|
100
|
+
result = try? reader.decode(rotatedBitmap, hints: nil)
|
|
101
|
+
if result != nil {
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if let result {
|
|
109
|
+
completion(result)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-camera",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.3",
|
|
4
4
|
"description": "A React component that renders a preview for the device's either front or back camera. Camera's parameters like zoom, auto focus, white balance and flash mode are adjustable. With expo-camera, one can also take photos and record videos that are saved to the app's cache. Morever, the component is also capable of detecting faces and bar codes appearing on the preview.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"optional": true
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "fc8a1408cab82e003dd2424db2994d7dea958067"
|
|
54
54
|
}
|