From d9222af8e26d1c9ad434e8f86c6f0f1f4e2d727b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrick=20B=C3=A4cker?= Date: Mon, 4 Sep 2017 11:01:57 +0200 Subject: [PATCH 1/5] Add finder and add branch for dev --- barcode-finder.js | 108 +++++++++++++++++++ index.js | 22 +++- package-lock.json | 257 ++++++++++++++-------------------------------- 3 files changed, 207 insertions(+), 180 deletions(-) create mode 100644 barcode-finder.js diff --git a/barcode-finder.js b/barcode-finder.js new file mode 100644 index 000000000..1ca8fa65b --- /dev/null +++ b/barcode-finder.js @@ -0,0 +1,108 @@ +import React, { + Component, + PropTypes, +} from 'react'; +import { + Platform, + StyleSheet, + View, +} from 'react-native'; + +class BarcodeFinder extends Component { + constructor(props) { + super(props); + } + + getSizeStyles() { + return ({ + width: this.props.width, + height: this.props.height + }); + } + + render() { + return ( + + + + + + + + + ); + } +}; + +BarcodeFinder.propTypes = { + borderWidth: PropTypes.number, + color: PropTypes.string, + width: PropTypes.number, + height: PropTypes.number +}; + +var styles = StyleSheet.create({ + container: { + alignItems: 'center', + justifyContent: 'center', + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + finder: { + alignItems: 'center', + justifyContent: 'center', + }, + topLeftEdge: { + position: 'absolute', + top: 0, + left: 0, + }, + topRightEdge: { + position: 'absolute', + top: 0, + right: 0, + }, + bottomLeftEdge: { + position: 'absolute', + bottom: 0, + left: 0, + }, + bottomRightEdge: { + position: 'absolute', + bottom: 0, + right: 0, + }, +}); + +module.exports = BarcodeFinder; diff --git a/index.js b/index.js index f1957e9e1..0afe3eff3 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ import { View, ViewPropTypes } from 'react-native'; +import BarcodeFinder from './barcode-finder'; const CameraManager = NativeModules.CameraManager || NativeModules.CameraModule; const CAMERA_REF = 'camera'; @@ -116,7 +117,12 @@ export default class Camera extends Component { type: PropTypes.oneOfType([ PropTypes.string, PropTypes.number - ]) + ]), + barcodeFinderVisible: PropTypes.bool, + barcodeFinderWidth: PropTypes.number, + barcodeFinderHeight: PropTypes.number, + barcodeBorderColor: PropTypes.string, + barcodeBorderBorder: PropTypes.number }; static defaultProps = { @@ -134,6 +140,11 @@ export default class Camera extends Component { torchMode: CameraManager.TorchMode.off, mirrorImage: false, barCodeTypes: Object.values(CameraManager.BarCodeType), + barcodeFinderVisible: false, + barcodeFinderWidth: 200, + barcodeFinderHeight: 200, + barcodeFinderBorderColor: "rgba(255,255,255,0.6)", + barcodeFinderBorderWidth: 2, }; static checkDeviceAuthorizationStatus = CameraManager.checkDeviceAuthorizationStatus; @@ -201,7 +212,14 @@ export default class Camera extends Component { const style = [styles.base, this.props.style]; const nativeProps = convertNativeProps(this.props); - return ; + return ( + {this.props.barcodeFinderVisible && }; + ); } _onBarCodeRead = (data) => { diff --git a/package-lock.json b/package-lock.json index 3776169d5..1b832b4a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,46 +2,12 @@ "name": "react-native-camera", "version": "0.10.0", "lockfileVersion": 1, + "requires": true, "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=" - }, - "babel-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=" - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=" - }, - "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "core-js": { "version": "2.4.1", @@ -51,167 +17,102 @@ "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=" + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.18" + } + }, + "fbjs": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.14.tgz", + "integrity": "sha1-0dviviVMNakeCfMfnNUKQLKg7Rw=", + "requires": { + "core-js": "2.4.1", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.14" + } }, "iconv-lite": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" }, - "inquirer": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", - "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, - "jschardet": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.4.2.tgz", - "integrity": "sha1-KqEH8UKvQSHRRWWdRPUIMJYeaZo=" - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.6.3", + "whatwg-fetch": "2.0.3" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } }, "node-fetch": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", - "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=" + "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=" - }, - "opencollective": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", - "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=" - }, - "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=" - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=" - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=" - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "string-width": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=" + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.5.10", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", + "integrity": "sha1-J5ffwxJhguOpXj37suiT3ddFYVQ=", + "requires": { + "fbjs": "0.8.14", + "loose-envify": "1.3.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "ua-parser-js": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", + "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=" + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" } } } From 7ce7b97e9c92ff632d045418e3b93afee55a927a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrick=20B=C3=A4cker?= Date: Mon, 4 Sep 2017 12:52:35 +0200 Subject: [PATCH 2/5] iOS barcode rect Limit scanning to specific size --- barcode-finder.js | 18 +++++++++++++----- index.js | 14 +++++++------- ios/RCTCameraManager.h | 3 +++ ios/RCTCameraManager.m | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/barcode-finder.js b/barcode-finder.js index 1ca8fa65b..311187c51 100644 --- a/barcode-finder.js +++ b/barcode-finder.js @@ -25,7 +25,7 @@ class BarcodeFinder extends Component { - {this.props.barcodeFinderVisible && }; + />} ); } diff --git a/ios/RCTCameraManager.h b/ios/RCTCameraManager.h index bf32d23e4..75d4dadcd 100644 --- a/ios/RCTCameraManager.h +++ b/ios/RCTCameraManager.h @@ -71,6 +71,9 @@ typedef NS_ENUM(NSInteger, RCTCameraTorchMode) { @property (nonatomic, assign) NSInteger videoTarget; @property (nonatomic, assign) NSInteger orientation; @property (nonatomic, assign) BOOL mirrorImage; +@property (nonatomic, assign) BOOL barcodeFinderVisible; +@property (nonatomic, assign) float barcodeFinderWidth; +@property (nonatomic, assign) float barcodeFinderHeight; @property (nonatomic, strong) NSArray* barCodeTypes; @property (nonatomic, strong) RCTPromiseResolveBlock videoResolve; @property (nonatomic, strong) RCTPromiseRejectBlock videoReject; diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 231008055..3dd53d7d0 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -293,6 +293,18 @@ - (void)setFlashMode { self.barCodeTypes = [RCTConvert NSArray:json]; } +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderVisible, BOOL, RCTCamera) { + self.barcodeFinderVisible = [RCTConvert BOOL:json]; +} + +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderWidth, float, RCTCamera) { + self.barcodeFinderWidth = [RCTConvert float:json]; +} + +RCT_CUSTOM_VIEW_PROPERTY(barcodeFinderHeight, float, RCTCamera) { + self.barcodeFinderHeight = [RCTConvert float:json]; +} + RCT_CUSTOM_VIEW_PROPERTY(captureAudio, BOOL, RCTCamera) { BOOL captureAudio = [RCTConvert BOOL:json]; if (captureAudio) { @@ -312,6 +324,7 @@ - (NSArray *)customDirectEventTypes - (id)init { if ((self = [super init])) { self.mirrorImage = false; + self.barcodeFinderVisible = false; self.sessionQueue = dispatch_queue_create("cameraManagerQueue", DISPATCH_QUEUE_SERIAL); @@ -447,6 +460,13 @@ - (void)startSession { [self.session addOutput:metadataOutput]; [metadataOutput setMetadataObjectTypes:self.barCodeTypes]; self.metadataOutput = metadataOutput; + if (self.barcodeFinderVisible) { + double cameraViewWidth = [[UIScreen mainScreen] bounds].size.height; + double cameraViewHeight = [[UIScreen mainScreen] bounds].size.width; + CGRect scanLimit = CGRectMake((cameraViewHeight/2)-(self.barcodeFinderHeight/2),(cameraViewWidth/2)-(self.barcodeFinderWidth/2), self.barcodeFinderHeight, self.barcodeFinderWidth); + [self.previewLayer metadataOutputRectOfInterestForRect: scanLimit]; + } + } __weak RCTCameraManager *weakSelf = self; From 6e75efb881f96a0df2244d9555aa88366d360d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrick=20B=C3=A4cker?= Date: Tue, 5 Sep 2017 10:40:09 +0200 Subject: [PATCH 3/5] barcode android - Add barcodes to static const - Add custom barcode scan area - update readme for android / ios --- README.md | 45 ++++++++++++++++--- .../com/lwansbrough/RCTCamera/RCTCamera.java | 27 +++++++++++ .../RCTCamera/RCTCameraModule.java | 18 +++++++- .../lwansbrough/RCTCamera/RCTCameraView.java | 12 +++++ .../RCTCamera/RCTCameraViewFinder.java | 24 +++++++--- 5 files changed, 112 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9e098956f..cd482cb7a 100644 --- a/README.md +++ b/README.md @@ -223,21 +223,41 @@ Will call the specified method when a barcode is detected in the camera's view. Event contains `data` (the data in the barcode) and `bounds` (the rectangle which outlines the barcode.) -The following barcode types can be recognised: +The following barcode types can be recognised for iOS: - `aztec` -- `code128` - `code39` - `code39mod43` - `code93` -- `ean13` +- `code128` +- `datamatrix` (when available) - `ean8` +- `ean13` +- `interleaved2of5` (when available) +- `itf14` (when available) - `pdf417` - `qr` - `upce` -- `interleaved2of5` (when available) -- `itf14` (when available) -- `datamatrix` (when available) + +The following barcode types can be recognised for Android: + +- `aztec` +- `codabar` +- `code39` +- `code93` +- `code128` +- `datamatrix` +- `ean8` +- `ean13` +- `itf14` +- `maxicode` +- `qr` +- `pdf417` +- `rss` +- `rss14` +- `upca` +- `upce` +- `upc` The barcode type is provided in the `data` object. @@ -245,6 +265,19 @@ The barcode type is provided in the `data` object. An array of barcode types to search for. Defaults to all types listed above. No effect if `onBarCodeRead` is undefined. +Use static const `Camera.constants.BarCodeType` for selecting scan types in `barCodeTypes` and to very the results in `onBarCodeRead`. + +#### `barcodeFinderVisible` + +Displays an rectangle over the camera to show the area of barcode scanning. If this is used the actual area that is scanned in cropped to the rectangle. This can significantly increase the performance. + +Adjust size and style: +`barcodeFinderWidth`, +`barcodeFinderHeight`, +`barcodeFinderBorderColor`, +`barcodeFinderBorderWidth` + + #### `flashMode` Values: diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java index e433f9d5d..4f5b7c093 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java @@ -22,6 +22,9 @@ public class RCTCamera { private static final Resolution RESOLUTION_720P = new Resolution(1280, 720); private static final Resolution RESOLUTION_1080P = new Resolution(1920, 1080); private boolean _barcodeScannerEnabled = false; + private boolean _barcodeFinderVisible = false; + private float _barcodeFinderWidth = 0; + private float _barcodeFinderHeight = 0; private List _barCodeTypes = null; private int _orientation = -1; private int _actualDeviceOrientation = 0; @@ -168,6 +171,30 @@ public void setBarcodeScannerEnabled(boolean barcodeScannerEnabled) { _barcodeScannerEnabled = barcodeScannerEnabled; } + public void setBarcodeFinderVisible(boolean barcodeFinderVisible) { + _barcodeFinderVisible = barcodeFinderVisible; + } + + public boolean barcodeFinderVisible() { + return _barcodeFinderVisible; + } + + public void setBarcodeFinderWidth(float barcodeFinderWidth) { + _barcodeFinderWidth = barcodeFinderWidth; + } + + public float barcodeFinderWidth() { + return _barcodeFinderWidth; + } + + public void setBarcodeFinderHeight(float barcodeFinderHeight) { + _barcodeFinderHeight = barcodeFinderHeight; + } + + public float barcodeFinderHeight() { + return _barcodeFinderHeight; + } + public List getBarCodeTypes() { return _barCodeTypes; } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java index 10b59f9c5..8cd93d390 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java @@ -165,7 +165,23 @@ private Map getAspectConstants() { private Map getBarCodeConstants() { return Collections.unmodifiableMap(new HashMap() { { - // @TODO add barcode types + put("aztec", "AZTEC"); + put("codabar", "CODABAR"); + put("code128", "CODE_128"); + put("code93", "CODE_93"); + put("code39", "CODE_39"); + put("datamatrix", "DATA_MATRIX"); + put("ean13", "EAN_13"); + put("ean8", "EAN_8"); + put("itf14", "ITF"); + put("maxicode", "MAXICODE"); + put("pdf417", "PDF_417"); + put("qr", "QR_CODE"); + put("rss14", "RSS_14"); + put("rss", "RSS_EXPANDED"); + put("upca", "UPC_A"); + put("upce", "UPC_E"); + put("upc", "UPC_EAN_EXTENSION"); } }); } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java index f9fe98ede..a05c3bd2b 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java @@ -119,6 +119,18 @@ public void setBarcodeScannerEnabled(boolean barcodeScannerEnabled) { RCTCamera.getInstance().setBarcodeScannerEnabled(barcodeScannerEnabled); } + public void setBarcodeFinderVisible(boolean barcodeFinderVisible) { + RCTCamera.getInstance().setBarcodeFinderVisible(barcodeFinderVisible); + } + + public void setBarcodeFinderWidth(float barcodeFinderWidth) { + RCTCamera.getInstance().setBarcodeFinderWidth(barcodeFinderWidth); + } + + public void setBarcodeFinderHeight(float barcodeFinderHeight) { + RCTCamera.getInstance().setBarcodeFinderHeight(barcodeFinderHeight); + } + public void setBarCodeTypes(List types) { RCTCamera.getInstance().setBarCodeTypes(types); } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java index e308474d3..c4687dfbd 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java @@ -307,25 +307,35 @@ protected Void doInBackground(Void... ignored) { } Camera.Size size = camera.getParameters().getPreviewSize(); - + int x = 0; + int y = 0; int width = size.width; int height = size.height; + // If using a barcode finder, limit the search area + if ( RCTCamera.getInstance().barcodeFinderVisible() ){ + x = (width/2) - ((int)RCTCamera.getInstance().barcodeFinderWidth()/2); + y = (height/2) - ((int)RCTCamera.getInstance().barcodeFinderHeight()/2); + width = (int)RCTCamera.getInstance().barcodeFinderWidth(); + height = (int)RCTCamera.getInstance().barcodeFinderHeight(); + } + // rotate for zxing if orientation is portrait if (RCTCamera.getInstance().getActualDeviceOrientation() == 0) { byte[] rotated = new byte[imageData.length]; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - rotated[x * height + height - y - 1] = imageData[x + y * width]; + for (int ypos = y; ypos < height; ypos++) { + for (int xpos = x; xpos < width; xpos++) { + rotated[xpos * height + height - ypos - 1] = imageData[xpos + ypos * width]; } } - width = size.height; - height = size.width; + int tmp = width; + width = height; + height = tmp; imageData = rotated; } try { - PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(imageData, width, height, 0, 0, width, height, false); + PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(imageData, width, height, x, y, width, height, false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result = _multiFormatReader.decodeWithState(bitmap); From caa6cb8a77282c1aa823dde44b7dabfc5c8a2e61 Mon Sep 17 00:00:00 2001 From: PUNCHH_GARIMA Date: Mon, 9 Apr 2018 17:11:34 +0530 Subject: [PATCH 4/5] Fixed Android Crashes RuntimeException: Camera is being used after Camera.release RuntimeException: getParameters failed (empty parameters) --- .../RCTCamera/RCTCameraViewFinder.java | 105 +++++++++++------- 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java index c4687dfbd..415533330 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java @@ -49,6 +49,15 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText // reader instance for the barcode scanner private final MultiFormatReader _multiFormatReader = new MultiFormatReader(); + private static Camera.Parameters getCameraParameters(Camera camera) { + try { + return camera != null ? camera.getParameters() : null; + } catch (RuntimeException e) { + // The camera has been released + return null; + } + } + public RCTCameraViewFinder(Context context, int type) { super(context); this.setSurfaceTextureListener(this); @@ -137,7 +146,7 @@ synchronized private void startCamera() { _isStarting = true; try { _camera = RCTCamera.getInstance().acquireCameraInstance(_cameraType); - Camera.Parameters parameters = _camera.getParameters(); + Camera.Parameters parameters = getCameraParameters(_camera); final boolean isCaptureModeStill = (_captureMode == RCTCameraModule.RCT_CAMERA_CAPTURE_MODE_STILL); final boolean isCaptureModeVideo = (_captureMode == RCTCameraModule.RCT_CAMERA_CAPTURE_MODE_VIDEO); @@ -306,35 +315,43 @@ protected Void doInBackground(Void... ignored) { return null; } - Camera.Size size = camera.getParameters().getPreviewSize(); + Camera.Parameters parameters = getCameraParameters(camera); + if (parameters == null) { + // The camera was released after onPreviewFrame() was called + // but before this async task actually ran + return null; + } + + Camera.Size size = parameters.getPreviewSize(); + int x = 0; int y = 0; int width = size.width; int height = size.height; - // If using a barcode finder, limit the search area - if ( RCTCamera.getInstance().barcodeFinderVisible() ){ - x = (width/2) - ((int)RCTCamera.getInstance().barcodeFinderWidth()/2); - y = (height/2) - ((int)RCTCamera.getInstance().barcodeFinderHeight()/2); - width = (int)RCTCamera.getInstance().barcodeFinderWidth(); - height = (int)RCTCamera.getInstance().barcodeFinderHeight(); - } + try { + // If using a barcode finder, limit the search area + if ( RCTCamera.getInstance().barcodeFinderVisible() ){ + x = (width/2) - ((int)RCTCamera.getInstance().barcodeFinderWidth()/2); + y = (height/2) - ((int)RCTCamera.getInstance().barcodeFinderHeight()/2); + width = (int)RCTCamera.getInstance().barcodeFinderWidth(); + height = (int)RCTCamera.getInstance().barcodeFinderHeight(); + } - // rotate for zxing if orientation is portrait - if (RCTCamera.getInstance().getActualDeviceOrientation() == 0) { - byte[] rotated = new byte[imageData.length]; - for (int ypos = y; ypos < height; ypos++) { - for (int xpos = x; xpos < width; xpos++) { - rotated[xpos * height + height - ypos - 1] = imageData[xpos + ypos * width]; + // rotate for zxing if orientation is portrait + if (RCTCamera.getInstance().getActualDeviceOrientation() == 0) { + byte[] rotated = new byte[imageData.length]; + for (int ypos = y; ypos < height; ypos++) { + for (int xpos = x; xpos < width; xpos++) { + rotated[xpos * height + height - ypos - 1] = imageData[xpos + ypos * width]; + } } + int tmp = width; + width = height; + height = tmp; + imageData = rotated; } - int tmp = width; - width = height; - height = tmp; - imageData = rotated; - } - try { PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(imageData, width, height, x, y, width, height, false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result = _multiFormatReader.decodeWithState(bitmap); @@ -369,26 +386,32 @@ protected Void doInBackground(Void... ignored) { @Override public boolean onTouchEvent(MotionEvent event) { - // Get the pointer ID - Camera.Parameters params = _camera.getParameters(); - int action = event.getAction(); - - - if (event.getPointerCount() > 1) { - // handle multi-touch events - if (action == MotionEvent.ACTION_POINTER_DOWN) { - mFingerSpacing = getFingerSpacing(event); - } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { - _camera.cancelAutoFocus(); - handleZoom(event, params); - } - } else { - // handle single touch events - if (action == MotionEvent.ACTION_UP) { - handleFocus(event, params); - } - } - return true; + // Get the pointer ID + if (_camera == null) { + return false; + } + + Camera.Parameters params = getCameraParameters(_camera); + if (params != null) { + // Get the pointer ID + int action = event.getAction(); + + if (event.getPointerCount() > 1) { + // handle multi-touch events + if (action == MotionEvent.ACTION_POINTER_DOWN) { + mFingerSpacing = getFingerSpacing(event); + } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { + _camera.cancelAutoFocus(); + handleZoom(event, params); + } + } else { + // handle single touch events + if (action == MotionEvent.ACTION_UP) { + handleFocus(event, params); + } + } + } + return true; } private void handleZoom(MotionEvent event, Camera.Parameters params) { From 53e889b78efe6e65635482d93909d84a3330e9e0 Mon Sep 17 00:00:00 2001 From: Ishant Sagar Date: Thu, 12 Apr 2018 17:31:32 +0530 Subject: [PATCH 5/5] Added PropTypes from 'prop-types' dependency --- barcode-finder.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barcode-finder.js b/barcode-finder.js index 311187c51..eb78ff565 100644 --- a/barcode-finder.js +++ b/barcode-finder.js @@ -1,7 +1,7 @@ import React, { - Component, - PropTypes, + Component } from 'react'; +import PropTypes from 'prop-types'; import { Platform, StyleSheet,