@hxa-rn/vision-camera-code-scanner 0.2.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.
@@ -0,0 +1,34 @@
1
+ import { useCodeScanner } from 'react-native-vision-camera';
2
+ import { useCallback, useState } from 'react';
3
+ import { mapFormatsToCodeTypes, normalizeReportedBarcode, toBarcode } from '.';
4
+
5
+ /**
6
+ * 鸿蒙端 useScanBarcodes 重实现。
7
+ *
8
+ * 鸿蒙版 @react-native-ohos/react-native-vision-camera v4 不提供 Frame Processor 机制
9
+ * (不导出 useFrameProcessor / FrameProcessorPlugin),但内置 useCodeScanner + Camera.codeScanner
10
+ * (底层为 Scan Kit customScan)。因此本 hook 基于 useCodeScanner 构造扫码器,在 onCodeScanned
11
+ * 回调中把 Code[] 转换为原 API 的 Barcode[]。
12
+ *
13
+ * ⚠️ API 变更:返回值从 `[frameProcessor, barcodes]` 变为 `[codeScanner, barcodes, clearBarcodes]`。
14
+ * 调用方需将 codeScanner 传给 `<Camera codeScanner={codeScanner}>`,而非 frameProcessor。
15
+ * 停止扫描时应调用 clearBarcodes(),避免下次开始扫描时把上次结果当作新识别上报。
16
+ *
17
+ * @param types 要检测的条码格式数组;包含 ALL_FORMATS 或为空数组时检测所有格式。
18
+ * @param options 扫描选项;checkInverted(反色条码)在鸿蒙端被忽略(Scan Kit 无反色识别选项)。
19
+ * @returns [codeScanner, barcodes, clearBarcodes]
20
+ */
21
+ export function useScanBarcodes(types, _options) {
22
+ const [barcodes, setBarcodes] = useState([]);
23
+ const clearBarcodes = useCallback(() => {
24
+ setBarcodes([]);
25
+ }, []);
26
+ const codeScanner = useCodeScanner({
27
+ codeTypes: mapFormatsToCodeTypes(types),
28
+ onCodeScanned: (codes, _frame) => {
29
+ setBarcodes(codes.map(code => normalizeReportedBarcode(toBarcode(code), types)));
30
+ }
31
+ });
32
+ return [codeScanner, barcodes, clearBarcodes];
33
+ }
34
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCodeScanner","useCallback","useState","mapFormatsToCodeTypes","normalizeReportedBarcode","toBarcode","useScanBarcodes","types","_options","barcodes","setBarcodes","clearBarcodes","codeScanner","codeTypes","onCodeScanned","codes","_frame","map","code"],"sources":["hook.tsx"],"sourcesContent":["import { Code, CodeScanner, CodeScannerFrame, useCodeScanner } from 'react-native-vision-camera';\r\nimport { useCallback, useState } from 'react';\r\n\r\nimport {\r\n Barcode,\r\n BarcodeFormat,\r\n CodeScannerOptions,\r\n mapFormatsToCodeTypes,\r\n normalizeReportedBarcode,\r\n toBarcode,\r\n} from '.';\r\n\r\n/**\r\n * 鸿蒙端 useScanBarcodes 重实现。\r\n *\r\n * 鸿蒙版 @react-native-ohos/react-native-vision-camera v4 不提供 Frame Processor 机制\r\n * (不导出 useFrameProcessor / FrameProcessorPlugin),但内置 useCodeScanner + Camera.codeScanner\r\n * (底层为 Scan Kit customScan)。因此本 hook 基于 useCodeScanner 构造扫码器,在 onCodeScanned\r\n * 回调中把 Code[] 转换为原 API 的 Barcode[]。\r\n *\r\n * ⚠️ API 变更:返回值从 `[frameProcessor, barcodes]` 变为 `[codeScanner, barcodes, clearBarcodes]`。\r\n * 调用方需将 codeScanner 传给 `<Camera codeScanner={codeScanner}>`,而非 frameProcessor。\r\n * 停止扫描时应调用 clearBarcodes(),避免下次开始扫描时把上次结果当作新识别上报。\r\n *\r\n * @param types 要检测的条码格式数组;包含 ALL_FORMATS 或为空数组时检测所有格式。\r\n * @param options 扫描选项;checkInverted(反色条码)在鸿蒙端被忽略(Scan Kit 无反色识别选项)。\r\n * @returns [codeScanner, barcodes, clearBarcodes]\r\n */\r\nexport function useScanBarcodes(\r\n types: BarcodeFormat[],\r\n _options?: CodeScannerOptions\r\n): [CodeScanner, Barcode[], () => void] {\r\n const [barcodes, setBarcodes] = useState<Barcode[]>([]);\r\n\r\n const clearBarcodes = useCallback(() => {\r\n setBarcodes([]);\r\n }, []);\r\n\r\n const codeScanner = useCodeScanner({\r\n codeTypes: mapFormatsToCodeTypes(types),\r\n onCodeScanned: (codes: Code[], _frame: CodeScannerFrame) => {\r\n setBarcodes(\r\n codes.map((code) => normalizeReportedBarcode(toBarcode(code), types))\r\n );\r\n },\r\n });\r\n\r\n return [codeScanner, barcodes, clearBarcodes];\r\n}\r\n"],"mappings":"AAAA,SAA8CA,cAAc,QAAQ,4BAA4B;AAChG,SAASC,WAAW,EAAEC,QAAQ,QAAQ,OAAO;AAE7C,SAIEC,qBAAqB,EACrBC,wBAAwB,EACxBC,SAAS,QACJ,GAAG;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,KAAsB,EACtBC,QAA6B,EACS;EACtC,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGR,QAAQ,CAAY,EAAE,CAAC;EAEvD,MAAMS,aAAa,GAAGV,WAAW,CAAC,MAAM;IACtCS,WAAW,CAAC,EAAE,CAAC;EACjB,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,WAAW,GAAGZ,cAAc,CAAC;IACjCa,SAAS,EAAEV,qBAAqB,CAACI,KAAK,CAAC;IACvCO,aAAa,EAAEA,CAACC,KAAa,EAAEC,MAAwB,KAAK;MAC1DN,WAAW,CACTK,KAAK,CAACE,GAAG,CAAEC,IAAI,IAAKd,wBAAwB,CAACC,SAAS,CAACa,IAAI,CAAC,EAAEX,KAAK,CAAC,CACtE,CAAC;IACH;EACF,CAAC,CAAC;EAEF,OAAO,CAACK,WAAW,EAAEH,QAAQ,EAAEE,aAAa,CAAC;AAC/C","ignoreList":[]}
@@ -0,0 +1,334 @@
1
+ /**
2
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.BarcodeFormat
3
+ */
4
+ export let BarcodeFormat = /*#__PURE__*/function (BarcodeFormat) {
5
+ BarcodeFormat[BarcodeFormat["UNKNOWN"] = -1] = "UNKNOWN";
6
+ BarcodeFormat[BarcodeFormat["ALL_FORMATS"] = 0] = "ALL_FORMATS";
7
+ BarcodeFormat[BarcodeFormat["CODE_128"] = 1] = "CODE_128";
8
+ BarcodeFormat[BarcodeFormat["CODE_39"] = 2] = "CODE_39";
9
+ BarcodeFormat[BarcodeFormat["CODE_93"] = 4] = "CODE_93";
10
+ BarcodeFormat[BarcodeFormat["CODABAR"] = 8] = "CODABAR";
11
+ BarcodeFormat[BarcodeFormat["DATA_MATRIX"] = 16] = "DATA_MATRIX";
12
+ BarcodeFormat[BarcodeFormat["EAN_13"] = 32] = "EAN_13";
13
+ BarcodeFormat[BarcodeFormat["EAN_8"] = 64] = "EAN_8";
14
+ BarcodeFormat[BarcodeFormat["ITF"] = 128] = "ITF";
15
+ BarcodeFormat[BarcodeFormat["QR_CODE"] = 256] = "QR_CODE";
16
+ BarcodeFormat[BarcodeFormat["UPC_A"] = 512] = "UPC_A";
17
+ BarcodeFormat[BarcodeFormat["UPC_E"] = 1024] = "UPC_E";
18
+ BarcodeFormat[BarcodeFormat["PDF417"] = 2048] = "PDF417";
19
+ BarcodeFormat[BarcodeFormat["AZTEC"] = 4096] = "AZTEC";
20
+ return BarcodeFormat;
21
+ }({});
22
+
23
+ /**
24
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.BarcodeValueType
25
+ */
26
+ export let BarcodeValueType = /*#__PURE__*/function (BarcodeValueType) {
27
+ BarcodeValueType[BarcodeValueType["UNKNOWN"] = 0] = "UNKNOWN";
28
+ BarcodeValueType[BarcodeValueType["CONTACT_INFO"] = 1] = "CONTACT_INFO";
29
+ BarcodeValueType[BarcodeValueType["EMAIL"] = 2] = "EMAIL";
30
+ BarcodeValueType[BarcodeValueType["ISBN"] = 3] = "ISBN";
31
+ BarcodeValueType[BarcodeValueType["PHONE"] = 4] = "PHONE";
32
+ BarcodeValueType[BarcodeValueType["PRODUCT"] = 5] = "PRODUCT";
33
+ BarcodeValueType[BarcodeValueType["SMS"] = 6] = "SMS";
34
+ BarcodeValueType[BarcodeValueType["TEXT"] = 7] = "TEXT";
35
+ BarcodeValueType[BarcodeValueType["URL"] = 8] = "URL";
36
+ BarcodeValueType[BarcodeValueType["WIFI"] = 9] = "WIFI";
37
+ BarcodeValueType[BarcodeValueType["GEO"] = 10] = "GEO";
38
+ BarcodeValueType[BarcodeValueType["CALENDAR_EVENT"] = 11] = "CALENDAR_EVENT";
39
+ BarcodeValueType[BarcodeValueType["DRIVER_LICENSE"] = 12] = "DRIVER_LICENSE";
40
+ return BarcodeValueType;
41
+ }({});
42
+
43
+ /**
44
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Address.AddressType
45
+ */
46
+ export let AddressType = /*#__PURE__*/function (AddressType) {
47
+ AddressType[AddressType["UNKNOWN"] = 0] = "UNKNOWN";
48
+ AddressType[AddressType["WORK"] = 1] = "WORK";
49
+ AddressType[AddressType["HOME"] = 2] = "HOME";
50
+ return AddressType;
51
+ }({});
52
+
53
+ /**
54
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Address
55
+ */
56
+
57
+ /**
58
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.PersonName
59
+ */
60
+
61
+ /**
62
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.ContactInfo
63
+ */
64
+
65
+ /**
66
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Email.FormatType
67
+ */
68
+ export let EmailType = /*#__PURE__*/function (EmailType) {
69
+ EmailType[EmailType["UNKNOWN"] = 0] = "UNKNOWN";
70
+ EmailType[EmailType["WORK"] = 1] = "WORK";
71
+ EmailType[EmailType["HOME"] = 2] = "HOME";
72
+ return EmailType;
73
+ }({});
74
+
75
+ /**
76
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Email
77
+ */
78
+
79
+ /**
80
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Phone.FormatType
81
+ */
82
+ export let PhoneType = /*#__PURE__*/function (PhoneType) {
83
+ PhoneType[PhoneType["UNKNOWN"] = 0] = "UNKNOWN";
84
+ PhoneType[PhoneType["WORK"] = 1] = "WORK";
85
+ PhoneType[PhoneType["HOME"] = 2] = "HOME";
86
+ PhoneType[PhoneType["FAX"] = 3] = "FAX";
87
+ PhoneType[PhoneType["MOBILE"] = 4] = "MOBILE";
88
+ return PhoneType;
89
+ }({});
90
+
91
+ /**
92
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Phone
93
+ */
94
+
95
+ /**
96
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Sms
97
+ */
98
+
99
+ /**
100
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.UrlBookmark
101
+ */
102
+
103
+ /**
104
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.WiFi.EncryptionType
105
+ */
106
+ export let EncryptionType = /*#__PURE__*/function (EncryptionType) {
107
+ EncryptionType[EncryptionType["OPEN"] = 1] = "OPEN";
108
+ EncryptionType[EncryptionType["WPA"] = 2] = "WPA";
109
+ EncryptionType[EncryptionType["WEP"] = 3] = "WEP";
110
+ return EncryptionType;
111
+ }({});
112
+
113
+ /**
114
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.WiFi
115
+ */
116
+
117
+ /**
118
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.GeoPoint
119
+ */
120
+
121
+ /**
122
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.CalendarDateTime
123
+ */
124
+
125
+ /**
126
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.CalendarEvent
127
+ */
128
+
129
+ /**
130
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.DriverLicense
131
+ */
132
+
133
+ /**
134
+ * @see https://developer.android.com/reference/android/graphics/Rect.html
135
+ */
136
+
137
+ /**
138
+ * @see https://developer.android.com/reference/android/graphics/Point.html
139
+ */
140
+
141
+ /**
142
+ * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode
143
+ */
144
+
145
+ /**
146
+ * 鸿蒙端 BarcodeFormat → CodeType 映射(含上游 codeType→ScanType off-by-one 补偿)。
147
+ *
148
+ * 上游 @react-native-ohos/react-native-vision-camera(4.0.3/4.7.1)ScanManager 的 codeType
149
+ * 数组多插了 'itf-14' 条目,导致 `codeType.indexOf(type)` 的索引被直接当作 ScanType 枚举值传给
150
+ * Scan Kit customScan 时,从 itf-14 之后的格式整体偏移 1(如 QR 被配置成 UPC_A)。因此对受影响的
151
+ * 四种格式传入「可命中正确 ScanType 索引」的 CodeType 字符串:
152
+ *
153
+ * | 目标 BarcodeFormat | 期望 ScanType | 传入 CodeType | indexOf |
154
+ * |--------------------|---------------|---------------|---------|
155
+ * | QR_CODE | QR_CODE(11) | 'pdf-417' | 11 |
156
+ * | PDF417 | PDF417(10) | 'itf-14' | 10 |
157
+ * | UPC_A | UPC_A(12) | 'qr' | 12 |
158
+ * | UPC_E | UPC_E(13) | 'upc-a' | 13 |
159
+ *
160
+ * @internal
161
+ */
162
+ const FORMAT_TO_CODE_TYPE = {
163
+ [BarcodeFormat.UNKNOWN]: null,
164
+ [BarcodeFormat.ALL_FORMATS]: null,
165
+ [BarcodeFormat.CODE_128]: 'code-128',
166
+ [BarcodeFormat.CODE_39]: 'code-39',
167
+ [BarcodeFormat.CODE_93]: 'code-93',
168
+ [BarcodeFormat.CODABAR]: 'codabar',
169
+ [BarcodeFormat.DATA_MATRIX]: 'data-matrix',
170
+ [BarcodeFormat.EAN_13]: 'ean-13',
171
+ [BarcodeFormat.EAN_8]: 'ean-8',
172
+ [BarcodeFormat.ITF]: 'itf',
173
+ [BarcodeFormat.QR_CODE]: 'pdf-417',
174
+ [BarcodeFormat.UPC_A]: 'qr',
175
+ [BarcodeFormat.UPC_E]: 'upc-a',
176
+ [BarcodeFormat.PDF417]: 'itf-14',
177
+ [BarcodeFormat.AZTEC]: 'aztec'
178
+ };
179
+
180
+ /**
181
+ * 鸿蒙端 Code.type → BarcodeFormat 反向映射(含补偿反向翻译)。
182
+ *
183
+ * 上报方向:ScanManager 用 `this.codeType[data.scanType]` 报告 code.type。因请求时已用补偿后的
184
+ * CodeType,扫码命中后 scanType 为正确的 ScanType 数值,故 code.type 即为补偿字符串本身,需按
185
+ * 反向表翻译回原 BarcodeFormat。'upc-e' 无有效 ScanType(indexOf 落在 14),映射为 UNKNOWN。
186
+ *
187
+ * @internal
188
+ */
189
+ const CODE_TYPE_TO_FORMAT = {
190
+ unknown: BarcodeFormat.UNKNOWN,
191
+ aztec: BarcodeFormat.AZTEC,
192
+ codabar: BarcodeFormat.CODABAR,
193
+ 'code-39': BarcodeFormat.CODE_39,
194
+ 'code-93': BarcodeFormat.CODE_93,
195
+ 'code-128': BarcodeFormat.CODE_128,
196
+ 'data-matrix': BarcodeFormat.DATA_MATRIX,
197
+ 'ean-8': BarcodeFormat.EAN_8,
198
+ 'ean-13': BarcodeFormat.EAN_13,
199
+ itf: BarcodeFormat.ITF,
200
+ 'itf-14': BarcodeFormat.PDF417,
201
+ 'pdf-417': BarcodeFormat.QR_CODE,
202
+ qr: BarcodeFormat.UPC_A,
203
+ 'upc-a': BarcodeFormat.UPC_E,
204
+ 'upc-e': BarcodeFormat.UNKNOWN
205
+ };
206
+
207
+ /**
208
+ * 将 JS 层 BarcodeFormat[] 转换为 vision-camera codeScanner 需要的 CodeType[]。
209
+ *
210
+ * - 空数组或包含 ALL_FORMATS:返回空数组,触发 Scan Kit customScan 的 ALL 默认扫描。
211
+ * - 其余格式经 FORMAT_TO_CODE_TYPE 映射(含上游 off-by-one 补偿)。
212
+ *
213
+ * @internal
214
+ */
215
+ export function mapFormatsToCodeTypes(types) {
216
+ if (!types || types.length === 0) {
217
+ return [];
218
+ }
219
+ if (types.includes(BarcodeFormat.ALL_FORMATS)) {
220
+ return [];
221
+ }
222
+ const result = [];
223
+ for (const format of types) {
224
+ const codeType = FORMAT_TO_CODE_TYPE[format];
225
+ if (codeType) {
226
+ result.push(codeType);
227
+ }
228
+ }
229
+ return result;
230
+ }
231
+
232
+ /**
233
+ * 将 vision-camera 扫码回调的 Code 转换为原 API 的 Barcode 类型。
234
+ *
235
+ * 鸿蒙 Scan Kit 的 ScanResult 仅提供 originalValue / scanCodeRect / cornerPoints,
236
+ * 无 MLKit/iOS Vision 的丰富结构化字段,因此 content 统一降级为
237
+ * `{ type: BarcodeValueType.TEXT, data: rawValue }`。
238
+ *
239
+ * @internal
240
+ */
241
+ export function toBarcode(code) {
242
+ const format = CODE_TYPE_TO_FORMAT[code.type] ?? BarcodeFormat.UNKNOWN;
243
+ const value = code.value;
244
+ const barcode = {
245
+ format,
246
+ content: {
247
+ type: BarcodeValueType.TEXT,
248
+ data: value ?? ''
249
+ }
250
+ };
251
+ if (value !== undefined) {
252
+ barcode.rawValue = value;
253
+ barcode.displayValue = value;
254
+ }
255
+ if (code.frame) {
256
+ barcode.boundingBox = {
257
+ left: code.frame.x,
258
+ top: code.frame.y,
259
+ right: code.frame.x + code.frame.width,
260
+ bottom: code.frame.y + code.frame.height
261
+ };
262
+ }
263
+ if (code.corners) {
264
+ barcode.cornerPoints = code.corners;
265
+ }
266
+ return barcode;
267
+ }
268
+
269
+ /**
270
+ * 按调用方请求的格式,归一化 UPC_A / EAN_13 上报结果。
271
+ *
272
+ * UPC_A 与「前导 0 的 EAN_13」条纹图案完全等价,Scan Kit / 多数扫码库常把 UPC_A
273
+ * 报成 EAN_13(13 位且以 0 开头),或把 EAN_13 报成 UPC_A(去掉前导 0)。
274
+ * 当请求格式仅包含其中一种时,按请求意图纠正 format 与数值,便于格式过滤用例验证。
275
+ *
276
+ * @internal
277
+ */
278
+ export function normalizeReportedBarcode(barcode, requestedTypes) {
279
+ if (!requestedTypes || requestedTypes.length === 0 || requestedTypes.includes(BarcodeFormat.ALL_FORMATS)) {
280
+ return barcode;
281
+ }
282
+ const wantsUpcA = requestedTypes.includes(BarcodeFormat.UPC_A);
283
+ const wantsEan13 = requestedTypes.includes(BarcodeFormat.EAN_13);
284
+ const value = barcode.rawValue ?? barcode.displayValue ?? '';
285
+
286
+ // 仅请求 UPC_A:Scan Kit 常把 UPC_A 报成带前导 0 的 EAN_13
287
+ if (wantsUpcA && !wantsEan13 && barcode.format === BarcodeFormat.EAN_13 && value.length === 13 && value.startsWith('0')) {
288
+ const upc = value.slice(1);
289
+ return {
290
+ ...barcode,
291
+ format: BarcodeFormat.UPC_A,
292
+ rawValue: upc,
293
+ displayValue: upc,
294
+ content: {
295
+ type: BarcodeValueType.TEXT,
296
+ data: upc
297
+ }
298
+ };
299
+ }
300
+
301
+ // 仅请求 EAN_13:偶发把等价码报成 12 位 UPC_A
302
+ if (wantsEan13 && !wantsUpcA && barcode.format === BarcodeFormat.UPC_A && value.length === 12) {
303
+ const ean = '0' + value;
304
+ return {
305
+ ...barcode,
306
+ format: BarcodeFormat.EAN_13,
307
+ rawValue: ean,
308
+ displayValue: ean,
309
+ content: {
310
+ type: BarcodeValueType.TEXT,
311
+ data: ean
312
+ }
313
+ };
314
+ }
315
+ return barcode;
316
+ }
317
+
318
+ /**
319
+ * Scans barcodes in the passed frame with MLKit
320
+ *
321
+ * @param frame Camera frame
322
+ * @param types Array of barcode types to detect (for optimal performance, use less types)
323
+ * @param options Scan options
324
+ * @returns Detected barcodes from MLKit
325
+ *
326
+ * 鸿蒙端不支持:Frame Processor 工作集机制在 @react-native-ohos/react-native-vision-camera v4
327
+ * 中不存在(不导出 useFrameProcessor / FrameProcessorPlugin)。此函数在鸿蒙端导出为抛错 stub,
328
+ * 请改用 `useScanBarcodes` 返回的 codeScanner 并传给 `<Camera codeScanner={...}>`。
329
+ */
330
+ export function scanBarcodes(_frame, _types, _options) {
331
+ throw new Error('Harmony 不支持 Frame Processor worklet,请使用 useScanBarcodes 返回的 codeScanner 并传给 <Camera codeScanner={...}>');
332
+ }
333
+ export * from './hook';
334
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BarcodeFormat","BarcodeValueType","AddressType","EmailType","PhoneType","EncryptionType","FORMAT_TO_CODE_TYPE","UNKNOWN","ALL_FORMATS","CODE_128","CODE_39","CODE_93","CODABAR","DATA_MATRIX","EAN_13","EAN_8","ITF","QR_CODE","UPC_A","UPC_E","PDF417","AZTEC","CODE_TYPE_TO_FORMAT","unknown","aztec","codabar","itf","qr","mapFormatsToCodeTypes","types","length","includes","result","format","codeType","push","toBarcode","code","type","value","barcode","content","TEXT","data","undefined","rawValue","displayValue","frame","boundingBox","left","x","top","y","right","width","bottom","height","corners","cornerPoints","normalizeReportedBarcode","requestedTypes","wantsUpcA","wantsEan13","startsWith","upc","slice","ean","scanBarcodes","_frame","_types","_options","Error"],"sources":["index.ts"],"sourcesContent":["import type { Code, CodeType, Frame } from 'react-native-vision-camera';\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.BarcodeFormat\r\n */\r\nexport enum BarcodeFormat {\r\n UNKNOWN = -1,\r\n ALL_FORMATS = 0,\r\n CODE_128 = 1,\r\n CODE_39 = 2,\r\n CODE_93 = 4,\r\n CODABAR = 8,\r\n DATA_MATRIX = 16,\r\n EAN_13 = 32,\r\n EAN_8 = 64,\r\n ITF = 128,\r\n QR_CODE = 256,\r\n UPC_A = 512,\r\n UPC_E = 1024,\r\n PDF417 = 2048,\r\n AZTEC = 4096,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.BarcodeValueType\r\n */\r\nexport enum BarcodeValueType {\r\n UNKNOWN = 0,\r\n CONTACT_INFO = 1,\r\n EMAIL = 2,\r\n ISBN = 3,\r\n PHONE = 4,\r\n PRODUCT = 5,\r\n SMS = 6,\r\n TEXT = 7,\r\n URL = 8,\r\n WIFI = 9,\r\n GEO = 10,\r\n CALENDAR_EVENT = 11,\r\n DRIVER_LICENSE = 12,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Address.AddressType\r\n */\r\nexport enum AddressType {\r\n UNKNOWN = 0,\r\n WORK = 1,\r\n HOME = 2,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Address\r\n */\r\nexport interface Address {\r\n addressLines?: string[];\r\n type?: AddressType;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.PersonName\r\n */\r\nexport interface PersonName {\r\n first?: string;\r\n formattedName?: string;\r\n last?: string;\r\n middle?: string;\r\n prefix?: string;\r\n pronunciation?: string;\r\n suffix?: string;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.ContactInfo\r\n */\r\nexport interface ContactInfo {\r\n addresses?: Address[];\r\n emails?: Email[];\r\n name?: PersonName;\r\n organization?: string;\r\n phones?: Phone[];\r\n title?: string;\r\n urls?: string[];\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Email.FormatType\r\n */\r\nexport enum EmailType {\r\n UNKNOWN = 0,\r\n WORK = 1,\r\n HOME = 2,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Email\r\n */\r\nexport interface Email {\r\n address?: string;\r\n body?: string;\r\n subject?: string;\r\n type?: EmailType;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Phone.FormatType\r\n */\r\nexport enum PhoneType {\r\n UNKNOWN = 0,\r\n WORK = 1,\r\n HOME = 2,\r\n FAX = 3,\r\n MOBILE = 4,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Phone\r\n */\r\nexport interface Phone {\r\n number?: string;\r\n type?: PhoneType;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.Sms\r\n */\r\nexport interface Sms {\r\n message?: string;\r\n phoneNumber?: string;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.UrlBookmark\r\n */\r\nexport interface UrlBookmark {\r\n title?: string;\r\n url?: string;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.WiFi.EncryptionType\r\n */\r\nexport enum EncryptionType {\r\n OPEN = 1,\r\n WPA = 2,\r\n WEP = 3,\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.WiFi\r\n */\r\nexport interface Wifi {\r\n encryptionType?: EncryptionType;\r\n password?: string;\r\n ssid?: string;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.GeoPoint\r\n */\r\nexport interface GeoPoint {\r\n lat?: number;\r\n lng?: number;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.CalendarDateTime\r\n */\r\nexport interface Date {\r\n day: number;\r\n hours: number;\r\n minutes: number;\r\n month: number;\r\n rawValue: string;\r\n seconds: number;\r\n year: number;\r\n isUtc: boolean;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.CalendarEvent\r\n */\r\nexport interface CalendarEvent {\r\n description?: string;\r\n end?: Date;\r\n location?: string;\r\n organizer?: string;\r\n start?: Date;\r\n status?: string;\r\n summary?: string;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode.DriverLicense\r\n */\r\nexport interface DriverLicense {\r\n addressCity?: string;\r\n addressState?: string;\r\n addressStreet?: string;\r\n addressZip?: string;\r\n birthDate?: string;\r\n documentType?: string;\r\n expiryDate?: string;\r\n firstName?: string;\r\n gender?: string;\r\n issueDate?: string;\r\n issuingCountry?: string;\r\n lastName?: string;\r\n licenseNumber?: string;\r\n middleName?: string;\r\n}\r\n\r\n/**\r\n * @see https://developer.android.com/reference/android/graphics/Rect.html\r\n */\r\nexport interface Rect {\r\n bottom: number;\r\n left: number;\r\n right: number;\r\n top: number;\r\n}\r\n\r\n/**\r\n * @see https://developer.android.com/reference/android/graphics/Point.html\r\n */\r\nexport interface Point {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * @see https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/Barcode\r\n */\r\nexport type Barcode = {\r\n boundingBox?: Rect;\r\n cornerPoints?: Point[];\r\n displayValue?: string;\r\n rawValue?: string;\r\n format: BarcodeFormat;\r\n content:\r\n | {\r\n type:\r\n | BarcodeValueType.UNKNOWN\r\n | BarcodeValueType.ISBN\r\n | BarcodeValueType.TEXT;\r\n data: string;\r\n }\r\n | {\r\n type: BarcodeValueType.CONTACT_INFO;\r\n data: ContactInfo;\r\n }\r\n | {\r\n type: BarcodeValueType.EMAIL;\r\n data: Email;\r\n }\r\n | {\r\n type: BarcodeValueType.PHONE;\r\n data: Phone;\r\n }\r\n | {\r\n type: BarcodeValueType.SMS;\r\n data: Sms;\r\n }\r\n | {\r\n type: BarcodeValueType.URL;\r\n data: UrlBookmark;\r\n }\r\n | {\r\n type: BarcodeValueType.WIFI;\r\n data: Wifi;\r\n }\r\n | {\r\n type: BarcodeValueType.GEO;\r\n data: GeoPoint;\r\n }\r\n | {\r\n type: BarcodeValueType.CALENDAR_EVENT;\r\n data: CalendarEvent;\r\n }\r\n | {\r\n type: BarcodeValueType.DRIVER_LICENSE;\r\n data: DriverLicense;\r\n };\r\n};\r\n\r\nexport interface CodeScannerOptions {\r\n /**\r\n * checkInverted: `Allows you to also scan white barcode with black backgrounds`\r\n *\r\n * 注意:鸿蒙(HarmonyOS)Scan Kit 无图像反色识别选项,此选项在鸿蒙端被忽略。\r\n */\r\n checkInverted?: boolean;\r\n}\r\n\r\n/**\r\n * 鸿蒙端 BarcodeFormat → CodeType 映射(含上游 codeType→ScanType off-by-one 补偿)。\r\n *\r\n * 上游 @react-native-ohos/react-native-vision-camera(4.0.3/4.7.1)ScanManager 的 codeType\r\n * 数组多插了 'itf-14' 条目,导致 `codeType.indexOf(type)` 的索引被直接当作 ScanType 枚举值传给\r\n * Scan Kit customScan 时,从 itf-14 之后的格式整体偏移 1(如 QR 被配置成 UPC_A)。因此对受影响的\r\n * 四种格式传入「可命中正确 ScanType 索引」的 CodeType 字符串:\r\n *\r\n * | 目标 BarcodeFormat | 期望 ScanType | 传入 CodeType | indexOf |\r\n * |--------------------|---------------|---------------|---------|\r\n * | QR_CODE | QR_CODE(11) | 'pdf-417' | 11 |\r\n * | PDF417 | PDF417(10) | 'itf-14' | 10 |\r\n * | UPC_A | UPC_A(12) | 'qr' | 12 |\r\n * | UPC_E | UPC_E(13) | 'upc-a' | 13 |\r\n *\r\n * @internal\r\n */\r\nconst FORMAT_TO_CODE_TYPE: Record<BarcodeFormat, CodeType | null> = {\r\n [BarcodeFormat.UNKNOWN]: null,\r\n [BarcodeFormat.ALL_FORMATS]: null,\r\n [BarcodeFormat.CODE_128]: 'code-128',\r\n [BarcodeFormat.CODE_39]: 'code-39',\r\n [BarcodeFormat.CODE_93]: 'code-93',\r\n [BarcodeFormat.CODABAR]: 'codabar',\r\n [BarcodeFormat.DATA_MATRIX]: 'data-matrix',\r\n [BarcodeFormat.EAN_13]: 'ean-13',\r\n [BarcodeFormat.EAN_8]: 'ean-8',\r\n [BarcodeFormat.ITF]: 'itf',\r\n [BarcodeFormat.QR_CODE]: 'pdf-417',\r\n [BarcodeFormat.UPC_A]: 'qr',\r\n [BarcodeFormat.UPC_E]: 'upc-a',\r\n [BarcodeFormat.PDF417]: 'itf-14' as CodeType,\r\n [BarcodeFormat.AZTEC]: 'aztec',\r\n};\r\n\r\n/**\r\n * 鸿蒙端 Code.type → BarcodeFormat 反向映射(含补偿反向翻译)。\r\n *\r\n * 上报方向:ScanManager 用 `this.codeType[data.scanType]` 报告 code.type。因请求时已用补偿后的\r\n * CodeType,扫码命中后 scanType 为正确的 ScanType 数值,故 code.type 即为补偿字符串本身,需按\r\n * 反向表翻译回原 BarcodeFormat。'upc-e' 无有效 ScanType(indexOf 落在 14),映射为 UNKNOWN。\r\n *\r\n * @internal\r\n */\r\nconst CODE_TYPE_TO_FORMAT: Record<string, BarcodeFormat> = {\r\n unknown: BarcodeFormat.UNKNOWN,\r\n aztec: BarcodeFormat.AZTEC,\r\n codabar: BarcodeFormat.CODABAR,\r\n 'code-39': BarcodeFormat.CODE_39,\r\n 'code-93': BarcodeFormat.CODE_93,\r\n 'code-128': BarcodeFormat.CODE_128,\r\n 'data-matrix': BarcodeFormat.DATA_MATRIX,\r\n 'ean-8': BarcodeFormat.EAN_8,\r\n 'ean-13': BarcodeFormat.EAN_13,\r\n itf: BarcodeFormat.ITF,\r\n 'itf-14': BarcodeFormat.PDF417,\r\n 'pdf-417': BarcodeFormat.QR_CODE,\r\n qr: BarcodeFormat.UPC_A,\r\n 'upc-a': BarcodeFormat.UPC_E,\r\n 'upc-e': BarcodeFormat.UNKNOWN,\r\n};\r\n\r\n/**\r\n * 将 JS 层 BarcodeFormat[] 转换为 vision-camera codeScanner 需要的 CodeType[]。\r\n *\r\n * - 空数组或包含 ALL_FORMATS:返回空数组,触发 Scan Kit customScan 的 ALL 默认扫描。\r\n * - 其余格式经 FORMAT_TO_CODE_TYPE 映射(含上游 off-by-one 补偿)。\r\n *\r\n * @internal\r\n */\r\nexport function mapFormatsToCodeTypes(types: BarcodeFormat[]): CodeType[] {\r\n if (!types || types.length === 0) {\r\n return [];\r\n }\r\n if (types.includes(BarcodeFormat.ALL_FORMATS)) {\r\n return [];\r\n }\r\n const result: CodeType[] = [];\r\n for (const format of types) {\r\n const codeType = FORMAT_TO_CODE_TYPE[format];\r\n if (codeType) {\r\n result.push(codeType);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * 将 vision-camera 扫码回调的 Code 转换为原 API 的 Barcode 类型。\r\n *\r\n * 鸿蒙 Scan Kit 的 ScanResult 仅提供 originalValue / scanCodeRect / cornerPoints,\r\n * 无 MLKit/iOS Vision 的丰富结构化字段,因此 content 统一降级为\r\n * `{ type: BarcodeValueType.TEXT, data: rawValue }`。\r\n *\r\n * @internal\r\n */\r\nexport function toBarcode(code: Code): Barcode {\r\n const format = CODE_TYPE_TO_FORMAT[code.type] ?? BarcodeFormat.UNKNOWN;\r\n const value = code.value;\r\n const barcode: Barcode = {\r\n format,\r\n content: {\r\n type: BarcodeValueType.TEXT,\r\n data: value ?? '',\r\n },\r\n };\r\n if (value !== undefined) {\r\n barcode.rawValue = value;\r\n barcode.displayValue = value;\r\n }\r\n if (code.frame) {\r\n barcode.boundingBox = {\r\n left: code.frame.x,\r\n top: code.frame.y,\r\n right: code.frame.x + code.frame.width,\r\n bottom: code.frame.y + code.frame.height,\r\n };\r\n }\r\n if (code.corners) {\r\n barcode.cornerPoints = code.corners;\r\n }\r\n return barcode;\r\n}\r\n\r\n/**\r\n * 按调用方请求的格式,归一化 UPC_A / EAN_13 上报结果。\r\n *\r\n * UPC_A 与「前导 0 的 EAN_13」条纹图案完全等价,Scan Kit / 多数扫码库常把 UPC_A\r\n * 报成 EAN_13(13 位且以 0 开头),或把 EAN_13 报成 UPC_A(去掉前导 0)。\r\n * 当请求格式仅包含其中一种时,按请求意图纠正 format 与数值,便于格式过滤用例验证。\r\n *\r\n * @internal\r\n */\r\nexport function normalizeReportedBarcode(\r\n barcode: Barcode,\r\n requestedTypes: BarcodeFormat[]\r\n): Barcode {\r\n if (\r\n !requestedTypes ||\r\n requestedTypes.length === 0 ||\r\n requestedTypes.includes(BarcodeFormat.ALL_FORMATS)\r\n ) {\r\n return barcode;\r\n }\r\n\r\n const wantsUpcA = requestedTypes.includes(BarcodeFormat.UPC_A);\r\n const wantsEan13 = requestedTypes.includes(BarcodeFormat.EAN_13);\r\n const value = barcode.rawValue ?? barcode.displayValue ?? '';\r\n\r\n // 仅请求 UPC_A:Scan Kit 常把 UPC_A 报成带前导 0 的 EAN_13\r\n if (\r\n wantsUpcA &&\r\n !wantsEan13 &&\r\n barcode.format === BarcodeFormat.EAN_13 &&\r\n value.length === 13 &&\r\n value.startsWith('0')\r\n ) {\r\n const upc = value.slice(1);\r\n return {\r\n ...barcode,\r\n format: BarcodeFormat.UPC_A,\r\n rawValue: upc,\r\n displayValue: upc,\r\n content: { type: BarcodeValueType.TEXT, data: upc },\r\n };\r\n }\r\n\r\n // 仅请求 EAN_13:偶发把等价码报成 12 位 UPC_A\r\n if (\r\n wantsEan13 &&\r\n !wantsUpcA &&\r\n barcode.format === BarcodeFormat.UPC_A &&\r\n value.length === 12\r\n ) {\r\n const ean = '0' + value;\r\n return {\r\n ...barcode,\r\n format: BarcodeFormat.EAN_13,\r\n rawValue: ean,\r\n displayValue: ean,\r\n content: { type: BarcodeValueType.TEXT, data: ean },\r\n };\r\n }\r\n\r\n return barcode;\r\n}\r\n\r\n/**\r\n * Scans barcodes in the passed frame with MLKit\r\n *\r\n * @param frame Camera frame\r\n * @param types Array of barcode types to detect (for optimal performance, use less types)\r\n * @param options Scan options\r\n * @returns Detected barcodes from MLKit\r\n *\r\n * 鸿蒙端不支持:Frame Processor 工作集机制在 @react-native-ohos/react-native-vision-camera v4\r\n * 中不存在(不导出 useFrameProcessor / FrameProcessorPlugin)。此函数在鸿蒙端导出为抛错 stub,\r\n * 请改用 `useScanBarcodes` 返回的 codeScanner 并传给 `<Camera codeScanner={...}>`。\r\n */\r\nexport function scanBarcodes(\r\n _frame: Frame,\r\n _types: BarcodeFormat[],\r\n _options?: CodeScannerOptions\r\n): Barcode[] {\r\n throw new Error(\r\n 'Harmony 不支持 Frame Processor worklet,请使用 useScanBarcodes 返回的 codeScanner 并传给 <Camera codeScanner={...}>'\r\n );\r\n}\r\n\r\nexport * from './hook';\r\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ import { CodeScanner } from 'react-native-vision-camera';
2
+ import { Barcode, BarcodeFormat, CodeScannerOptions } from '.';
3
+ /**
4
+ * 鸿蒙端 useScanBarcodes 重实现。
5
+ *
6
+ * 鸿蒙版 @react-native-ohos/react-native-vision-camera v4 不提供 Frame Processor 机制
7
+ * (不导出 useFrameProcessor / FrameProcessorPlugin),但内置 useCodeScanner + Camera.codeScanner
8
+ * (底层为 Scan Kit customScan)。因此本 hook 基于 useCodeScanner 构造扫码器,在 onCodeScanned
9
+ * 回调中把 Code[] 转换为原 API 的 Barcode[]。
10
+ *
11
+ * ⚠️ API 变更:返回值从 `[frameProcessor, barcodes]` 变为 `[codeScanner, barcodes, clearBarcodes]`。
12
+ * 调用方需将 codeScanner 传给 `<Camera codeScanner={codeScanner}>`,而非 frameProcessor。
13
+ * 停止扫描时应调用 clearBarcodes(),避免下次开始扫描时把上次结果当作新识别上报。
14
+ *
15
+ * @param types 要检测的条码格式数组;包含 ALL_FORMATS 或为空数组时检测所有格式。
16
+ * @param options 扫描选项;checkInverted(反色条码)在鸿蒙端被忽略(Scan Kit 无反色识别选项)。
17
+ * @returns [codeScanner, barcodes, clearBarcodes]
18
+ */
19
+ export declare function useScanBarcodes(types: BarcodeFormat[], _options?: CodeScannerOptions): [CodeScanner, Barcode[], () => void];