Skip to content
This repository was archived by the owner on Jun 16, 2023. It is now read-only.

Conversation

@fbacker
Copy link

@fbacker fbacker commented Sep 5, 2017

I've added a 'barcode finder' rect that can be enabled. When doing this it will also crop the area that is scanned. It will significantly increase the read lag. Possible to set the size, color and border.

Also I've added correct static const for barcodes on android and updated the readme.

  • barcode finder
  • ios: crop search area
  • android: crop search area
  • android: add static const of barcode types
  • updated readme

and add branch for dev
Limit scanning to specific size
- Add barcodes to static const
- Add custom barcode scan area
- update readme for android / ios
@sahir
Copy link

sahir commented Sep 19, 2017

Hey, any news when it's going to merge ? can you please provide your branch link I did not find your branch for npm install. I want to customize react native camera something like this

screenshot-1505813796156

@fbacker
Copy link
Author

fbacker commented Sep 19, 2017

https://github.com/fbacker/react-native-camera/tree/barcode-finder

until this branch is merged I'm using package.json
"react-native-camera": "github:fbacker/react-native-camera#barcode-finder"

@sahir
Copy link

sahir commented Sep 20, 2017

Thanks 👍

@truongthanh1303
Copy link

I tried your implementation, but I cannot get the expected result. All children node inside Camera component does not appear.
Did you have this issue?

Thanks.

@sahir
Copy link

sahir commented Sep 21, 2017

@truongthanh1303 you can use topOverlay and bottomOverlay style to appeared all children node inside camera component. for example https://github.com/lwansbrough/react-native-camera/blob/master/Example/Example.js

Able to create a custom finder on top of camera component. also fixed proptypes deprecation in barcode-finder
@fbacker
Copy link
Author

fbacker commented Sep 21, 2017

Try it out. Made it possible to change the default finder design. Having issues starting the package Example so developing against my own project so hope I don't miss anything or f**k up something :)

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,
barcodeFinderStyle

The default viewer style has borderColor and borderWidth.

Make a custom barcode finder
  1. make a copy of barcode-finder.js and place it in your project
  2. add it to your project
  3. add it as a child to the Camera
<Camera>
    <MyCustomBarcodeFinder />
</Camera>

NOTE: The scan area is cropped and as long the first to components remain intact it should show the correct size.

<View style={[styles.container]}>
    <View style={[styles.finder, this.getSizeStyles()]}>
        { place your design here }

@truongthanh1303
Copy link

@sahir Thanks for your suggestion! It works fine :)
@fbacker I chose the first solution that @sahir suggested because it's simple. But thanks for your work!

Regards,

@sahir
Copy link

sahir commented Sep 25, 2017

@truongthanh1303 @fbacker I implement barcode reader https://github.com/sahir/react-native-barcode-reader successfully but facing this issue #476 I have also tried the solution (bind - unbind lifecycle methods) but no success. I guess you also face this issue let me know if you found any solution.

@fbacker
Copy link
Author

fbacker commented Sep 25, 2017

When attaching the camera display I set an empty array. Then just check if it's been used.

barcodeReceived(e) {
      console.log('Barcode: ' + e.data);
      console.log('Type: ' + e.type);
      if(e!=null && (e.type==Camera.constants.BarCodeType.datamatrix||e.type==Camera.constants.BarCodeType.qr)){
        let code = e.data;
        if(!this._codes.includes(code)){

          if(Platform.OS === 'ios'){
            Vibration.vibrate(500, false);
          }
          else{
            Vibration.vibrate([0, 500], false);
          }

          this._codes.push(code);
          this.props.onCode(code);
        }
      }
    }

@gablorquet
Copy link

gablorquet commented Sep 27, 2017

It seems that the viewfinder doesn't properly restrict the barcode scanning area.

It looks like the setBarcodeFinderVisible is never invoked in Java. I'm not too familiar with Android development so I might just be missing it (still trying to figure out how to debug java code)

EDIT : From what I think I got, it seems there are missing the ViewFinder ReactProp in the RCTCameraViewManager

@GarimaMathur07
Copy link

@gablorquet

https://github.com/fbacker/react-native-camera/tree/barcode-finder

until this branch is merged, you have to use package.json
"react-native-camera": "github:fbacker/react-native-camera#barcode-finder"

Use:
barcodeFinderVisible={true}

<Camera
					ref={cam => {
						this.camera = cam;
					}}
					style={styles.preview}
					aspect={this.state.camera.aspect}
					captureTarget={this.state.camera.captureTarget}
					type={this.state.camera.type}
					flashMode={this.state.camera.flashMode}
					onFocusChanged={() => {}}
					onZoomChanged={() => {}}
					defaultTouchToFocus
					mirrorImage={false}
					barcodeFinderVisible={true}
					barcodeFinderWidth={280}
					barcodeFinderHeight={220}
					barcodeFinderBorderColor="red"
					barcodeFinderBorderWidth={2}
					onBarCodeRead={this.onBarCodeRead.bind(this)}
				/>

@gablorquet
Copy link

gablorquet commented Sep 28, 2017

I am doing that. The thing is that that in the Java class RTCCameraViewManager, the added properties are never implemented thus the barcodeScannerViewFinderEnabled variable is always false. Without them, you can still get scans from outside the ViewFinder

@fbacker
Copy link
Author

fbacker commented Sep 28, 2017

@GarimaMathur07 if update thru git I've changed the properties
Adjust size and style:
barcodeFinderWidth,
barcodeFinderHeight,
barcodeFinderStyle

also a way to make the viewfinder custom. check the updated readme.md

@gablorquet you are absolutely correct. There's so many weird steps. I'll try to fix this. Having some math calculation issues. Will try to fix this tomorrow.

I noticed that setting barcode types happend 1 time and was triggered before the properties was passed from react. So it was always scanning all possible formats.

Also I've changed the crop size to be based on % size. This because different resolutions on cameras didn't match up with size from react.
There's an commented code section when capture image that can be used to tweak the cropsize, so we know what we actually are looking at.
@fbacker
Copy link
Author

fbacker commented Oct 5, 2017

I've made a new commit that should solve android crop size and also a bug in setting barcode types.

from commit:

I noticed that setting barcode types happend 1 time and was triggered before the properties was passed from react. So it was always scanning all possible formats.

Also I've changed the crop size to be based on % size. This because different resolutions on cameras didn't match up with size from react.
There's an commented code section when capture image that can be used to tweak the cropsize, so we know what we actually are looking at.

@wanderSX
Copy link

@fbacker I'm getting error after latest commit

Camera has no propType for native prop RCTCamera.barcodeFinderPercentageSize of native type Array
If you haven't changed this prop yourself, this usually means that your versions of the native code and Javascript code are out of sync. Updating both should make this error go away

@gvlamadrid
Copy link

@fbacker @wanderSX I think its missing define barcodeFinderPercentageSize on propType https://github.com/fbacker/react-native-camera/blob/barcode-finder/index.js#L77

Added missed changes
@fbacker
Copy link
Author

fbacker commented Oct 11, 2017

@wanderSX @gvlamadrid yeah, sorry about that. Missed the index.js file in commit.

Still haven't figured out how to update npm packages outside a project. So making changes in the project folder and then copy to external git project. Tried npm link and other things. But when running multiple react-native projects it always messes up the package-manager :(

@ploureiro
Copy link

ploureiro commented Oct 18, 2017

I also got codes scans outside the scanning area in iOS 11 (react v0.47), here is my code:

        <Camera
          ref={(cam) => {
            this.camera = cam;
          }}
          style={styles.preview}
          aspect={this.props.camera.aspect}
          captureTarget={this.props.camera.captureTarget}
          type={this.props.camera.type}
          keepAwake={true}
          barCodeTypes={ !this.props.NFCReader.pkgMode? ['org.iso.QRCode']:['org.iso.DataMatrix']}
          onBarCodeRead={this._onBarCodeRead}
          torchMode={this.props.camera.flashMode}
          onFocusChanged={() => {}}
          defaultTouchToFocus
          barcodeFinderVisible={true}
          barcodeFinderWidth={160}
          barcodeFinderHeight={160}>
        </Camera>

I used latest branch as described above.

Try to fix android issue that occures sometimes. When in doubt, try catch.
Change cropping to use % of size (as android) to handle different resolutions correctly.
@fbacker
Copy link
Author

fbacker commented Nov 9, 2017

@ploureiro try latest.

these commits handles 1. some android devices crash sometimes for some reason and 2. hopefullt an correct crop for ios.

@HZSamir
Copy link

HZSamir commented Dec 18, 2017

Any progress on this?
I would love to include it in my project, the simple camera view seems a little barren

@fanzkday
Copy link

@fbacker How to add a black backgroundColor around the rectangle?

@b-asaf
Copy link

b-asaf commented Dec 19, 2017

@fbacker great addition to the package!
I am joining @fanzkday question - how can I style the backgroundColor around the rectangle.
And another question - can I style the border - for example make the edges round and bold?

@fanzkday
Copy link

@assafb81 Ok.

@fbacker
Copy link
Author

fbacker commented Jan 2, 2018

@fanzkday @assafb81 Guessing that you want the actual scan area to be transparent and a background color around the actual scanning area.

To do this. Create this outside the camera component.

@b-asaf
Copy link

b-asaf commented Jan 2, 2018

@fbacker thanks for the help.
I finally implemented it a bit differently, similar to what is done in #121.
but without the graying out the area outside the rectangle.

@efstathiosntonas
Copy link

@fbacker if i scan a barcode and leave the camera pointing to the barcode, the scanner will continuously scan the barcode.

Is there a way to stop the scanning when the scanner successfully scans it the 1st time?

@moonbrv
Copy link

moonbrv commented Jan 14, 2018

hello @fbacker, what if we have a lot of QR codes on 1 page, I try to catch code that is in the center of BarcodeFinder, but scanning catch barcode that is above this one. See pic, I try to scan QR code 101007, but instead of this camera capture 101006, or even 101005. As I know camera do scan from top to bottom, this means that area of Barcode recognition is not limited by BarcodeFinder size. How can I say to the camera to scan only specific area?

Click to see screenshot

@fbacker
Copy link
Author

fbacker commented Jan 22, 2018

I've now run my latest in prod environment, old react-native-camera crash on android no longer exists. Yaay.

It's hard for me to keep this PR alive because the repo owners never merges to master. A lot of other stuff gets implemented and keeps breaking my PR.

So I'll close this now. Been open since September :(

@zedtux
Copy link

zedtux commented Oct 24, 2018

@sibelius you seem to be active on this project. Could you please help @fbacker, who did a nice feature implementation, that a lot of people are looking for?

@sibelius
Copy link
Collaborator

sorry about this one

anybody want to bring only the native parts of this PR?

I think the js part can be done in userland

this would solve this one #1435

@sibelius sibelius reopened this Mar 25, 2019
@leeroybrun
Copy link
Contributor

I've started implementing this some months ago for iOS and Android on the latest version of RNCamera based on the work of @fbacker, but never had the time to completely test it as I had to switch to another project at work. But it's used in production in one of our apps for many months now and seems to work fine.

The only part I'm not 100% sure about is the adaptation of the bounding rects coordinates when we crop the scanning area. Especially on Android and when rotating the phone, something strange seemed to be going on there.

If I find the time soon I will try to finish it and send a pull request.

In the meantime you can check it out here : https://github.com/leeroybrun/react-native-camera

This adds a new cropScanArea={[WIDTH_PERCENTAGE, HEIGHT_PERCENTAGE]} param to <RNCamera />.

For example <RNCamera [...] cropScanArea={[0.9, 0.25]}></RNCamera> will crop the scanning area to 90% of the camera width and 25% of its height (at the center).

The UI part is left to the developer, nothing is displayed on the screen when using this param.

Here is an example of what ~ a crop of "90% of the camera width and 25% of its height" represents.

Sans titre-1

Limiting the area where we need to search for a barcode results in a much faster scan for the user, especially on older phones.

@andresmtz98
Copy link

I've started implementing this some months ago for iOS and Android on the latest version of RNCamera based on the work of @fbacker, but never had the time to completely test it as I had to switch to another project at work. But it's used in production in one of our apps for many months now and seems to work fine.

The only part I'm not 100% sure about is the adaptation of the bounding rects coordinates when we crop the scanning area. Especially on Android and when rotating the phone, something strange seemed to be going on there.

If I find the time soon I will try to finish it and send a pull request.

In the meantime you can check it out here : https://github.com/leeroybrun/react-native-camera

This adds a new cropScanArea={[WIDTH_PERCENTAGE, HEIGHT_PERCENTAGE]} param to <RNCamera />.

For example <RNCamera [...] cropScanArea={[0.9, 0.25]}></RNCamera> will crop the scanning area to 90% of the camera width and 25% of its height (at the center).

The UI part is left to the developer, nothing is displayed on the screen when using this param.

Here is an example of what ~ a crop of "90% of the camera width and 25% of its height" represents.

Sans titre-1

Limiting the area where we need to search for a barcode results in a much faster scan for the user, especially on older phones.

Bro, is it able to support RN .60.x? I would like to use your fork with that feature.

@sibelius
Copy link
Collaborator

Can we have something like this #1852

Just define a rect and limit the region to it?

@fabOnReact
Copy link
Contributor

Android #2766

@sibelius
Copy link
Collaborator

sibelius commented Apr 1, 2020

can we close this?

Copy link
Contributor

@fabOnReact fabOnReact left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry about this one

anybody want to bring only the native parts of this PR?

I think the js part can be done in userland

this would solve this one #1435

I agree, as explained in #2766 the javascript logic should handle the logic for camera orientation and calculation of the parameters, the native code should expose the PlanarYUVLuminanceSource or RGBLuminanceSource parameters so that the user can set the yuv source dataWidth, dataHeight and cropping parameters. Any additional information could be exposed to the react-native developers via the React Native Bridge..

PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top, int width, int height, boolean reverseHorizontal) 

import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my pull request #2766 for android I expose the PlanarYUVLuminanceSource to the reactnative developer with a method named rectOfInterest.

rectOfInterest allows the user to set the instance variables later then passed to PlanarYUVLuminanceSource constructor.

PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top, int width, int height, boolean reverseHorizontal) 

read more here (the linked comment is hidden, be sure to open it).

rotationIndex = 3;
break;
}
// rotate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe as discussed in #2766 it is easier to expose the method to the react-native developers to create the PlanarYUVLuminanceSource instead of handling all the different scenarios and orientations... Many users will scan barcodes only in Landscape/FrontCamera or Portrait/FrontCamera... and maybe using com.google.zxing libraries is not the best choice for offering all this functionalities.. so I would be happy to discuss about this, but I will focus on the android side.
Sooner or later this functionality will break and we may not have the manpower to handle the mantainance.

            switch(deviceRotation){
                case 0: // portrait
                    rotationIndex = 6;
                    break;
                case 1: // landscape left
                    rotationIndex = 1;
                    break;
                case 2: // portrait upside down

                    break;
                case 3: // landscape right
                    rotationIndex = 3;
                    break;
            }
            // rotate
            try{
                mutableImage.rotate(rotationIndex);
            } catch (MutableImage.ImageMutationFailedException e) {
                android.util.Log.e("RCTCamera","Rotate temp image",e);
                promise.reject("failed to rotate file", e);
                return;
            }

You can still consider working on your own library and include this functionality, as the issue here is that the owner of the code then mantains it... as other developers may not be as productive handling issues on code they did not write, having a simple api may really help a lot.

throw new Exception();
}
LuminanceSource source = new RGBLuminanceSource(width, height, intArray);
BinaryBitmap bbitmap = new BinaryBitmap(new HybridBinarizer(source));
Copy link
Contributor

@fabOnReact fabOnReact Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not continue using YUV format and PlanarYUVLuminanceSource and switching to RGBLuminanceSource? I was courious understanding this reason. Thanks a lot 😃

@renatobenks
Copy link
Collaborator

@fabriziobertoglio1987 are you working to move this forward? I didn't get you on why did you close the other issue related to this one #2766 as you mentioned above? I mean, did you stop the work over there to get this one done? let me know to think how could I help to close this

@fabOnReact
Copy link
Contributor

fabOnReact commented May 14, 2020

Thanks @renatobenks currently I am busy trying to solve an issue in another repository, finishing #2766 is in my todo list. I estimate that I will start working on it in June.

If you want to continue my work on my branch (this is the example used to test the functionality).

The remaining TODO explained from @cristianocca in this comment are:

What's the final goal of this change?

Me, as a developer updating RNCamera, what should I change if I'm already using the current barcode scanner behaviour? What should I do if I want to use this improvement?

In my effort to re-write the rectOfInterest functionality, I had to re-write it from scratch and introduced breaking changes. The new api is built on top of PlanarYUVLuminanceSource see this post for detailed explanation.

The previous Javascript API was build based on iOS and ported to Android.

rectOfInterest={{ x: scanAreaX, y: scanAreaY, width: scanAreaWidth, height: scanAreaHeight }}

x and y where the coordinates of the top left corner, width and height a float number ranging from 0 to 1 representing the percentage ranging from 0% to 100% of the width/height of the screen.

I can build the same approach on my branch/functionality:

  1. I need to build a logic on the rotation parameter
  2. Rotate correctly the image based on camera rotation (currently this is calculated not with the rotation but on other parameters)
    https://github.com/react-native-community/react-native-camera/blob/5abbacaac4448311775c5544ea5feb3c3b5b94f9/android/src/main/java/org/reactnative/camera/tasks/BarCodeScannerAsyncTask.java#L45
  3. Adapt the current parameters based on PlanarYUVLuminanceSource parameters to percentages

The changes will basically reflect the fact that we pass parameters like this

rectOfInterest={{ x: scanAreaX, y: scanAreaY, width: scanAreaWidth, height: scanAreaHeight }}

instead of

landscape = {
  dataWidth: 1440,
  dataHeight: 1080,
  left: 250,
  top: 300,
  width: 950,
  height: 600,
}

Thanks a lot

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.