Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,28 +223,61 @@ 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.

#### `barCodeTypes`

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:
Expand Down
27 changes: 27 additions & 0 deletions android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> _barCodeTypes = null;
private int _orientation = -1;
private int _actualDeviceOrientation = 0;
Expand Down Expand Up @@ -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<String> getBarCodeTypes() {
return _barCodeTypes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,23 @@ private Map<String, Object> getAspectConstants() {
private Map<String, Object> getBarCodeConstants() {
return Collections.unmodifiableMap(new HashMap<String, Object>() {
{
// @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");
}
});
}
Expand Down
12 changes: 12 additions & 0 deletions android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> types) {
RCTCamera.getInstance().setBarCodeTypes(types);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -306,26 +315,44 @@ 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;

// 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];
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];
}
}
int tmp = width;
width = height;
height = tmp;
imageData = rotated;
}
width = size.height;
height = size.width;
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);

Expand Down Expand Up @@ -359,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) {
Expand Down
Loading