Merge pull request #125 from wix/android_barcode

Android barcode
This commit is contained in:
Lev Vidrak 2018-02-06 16:45:54 +02:00 committed by GitHub
commit b1041eb81f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 7667 additions and 79 deletions

View File

@ -21,5 +21,7 @@ android {
dependencies {
compile 'com.facebook.react:react-native:+'
compile 'com.android.support:recyclerview-v7:25.0.1'
compile 'com.google.zxing:core:3.3.0'
compile 'me.dm7.barcodescanner:core:1.9.8'
compile group: 'com.drewnoakes', name: 'metadata-extractor', version: '2.9.1'
}

View File

@ -1,7 +1,10 @@
package com.wix.RNCameraKit.camera;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.hardware.Camera;
import android.support.annotation.ColorInt;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@ -10,12 +13,20 @@ import android.widget.FrameLayout;
import com.facebook.react.uimanager.ThemedReactContext;
import com.wix.RNCameraKit.Utils;
import me.dm7.barcodescanner.core.IViewFinder;
import me.dm7.barcodescanner.core.ViewFinderView;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public class CameraView extends FrameLayout implements SurfaceHolder.Callback {
private ThemedReactContext context;
private SurfaceView surface;
private Rect viewFrameRect;
private IViewFinder viewFinder;
@ColorInt private int frameColor = Color.GREEN;
@ColorInt private int laserColor = Color.RED;
public CameraView(ThemedReactContext context) {
super(context);
this.context = context;
@ -49,6 +60,9 @@ public class CameraView extends FrameLayout implements SurfaceHolder.Callback {
int actualPreviewHeight = getResources().getDisplayMetrics().heightPixels;
int height = Utils.convertDeviceHeightToSupportedAspectRatio(actualPreviewWidth, actualPreviewHeight);
surface.layout(0, 0, actualPreviewWidth, height);
if (viewFinder != null) {
((View) viewFinder).layout(0, 0, actualPreviewWidth, height);
}
}
@Override
@ -70,4 +84,84 @@ public class CameraView extends FrameLayout implements SurfaceHolder.Callback {
public SurfaceHolder getHolder() {
return surface.getHolder();
}
private final Runnable measureAndLayout = new Runnable() {
@Override
public void run() {
measure(
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
}
};
@Override
public void requestLayout() {
super.requestLayout();
post(measureAndLayout);
}
public void showFrame() {
viewFinder = createViewFinderView(getContext());
addView((View) viewFinder);
requestLayout();
}
private IViewFinder createViewFinderView(Context context) {
ViewFinderView viewFinderView = new ViewFinderView(context);
viewFinderView.setBorderColor(frameColor);
viewFinderView.setLaserColor(laserColor);
viewFinderView.setLaserEnabled(true);
viewFinderView.setBorderStrokeWidth(5);
viewFinderView.setBorderLineLength(60);
viewFinderView.setMaskColor(Color.argb(60, 0, 0, 0));
viewFinderView.setSquareViewFinder(true);
viewFinderView.setViewFinderOffset(11);
return viewFinderView;
}
public Rect getFramingRectInPreview(int previewWidth, int previewHeight) {
if (viewFrameRect == null) {
if (viewFinder != null) {
Rect framingRect = viewFinder.getFramingRect();
int viewFinderViewWidth = viewFinder.getWidth();
int viewFinderViewHeight = viewFinder.getHeight();
if (framingRect == null || viewFinderViewWidth == 0 || viewFinderViewHeight == 0) {
return null;
}
Rect rect = new Rect(framingRect);
if (previewWidth < viewFinderViewWidth) {
rect.left = rect.left * previewWidth / viewFinderViewWidth;
rect.right = rect.right * previewWidth / viewFinderViewWidth;
}
if (previewHeight < viewFinderViewHeight) {
rect.top = rect.top * previewHeight / viewFinderViewHeight;
rect.bottom = rect.bottom * previewHeight / viewFinderViewHeight;
}
viewFrameRect = rect;
} else {
viewFrameRect = new Rect(0, 0, previewWidth, previewHeight);
}
}
return viewFrameRect;
}
public void setFrameColor(@ColorInt int color) {
this.frameColor = color;
if (viewFinder != null) {
viewFinder.setBorderColor(frameColor);
}
}
public void setLaserColor(@ColorInt int color) {
this.laserColor = color;
if (viewFinder != null) {
viewFinder.setLaserColor(laserColor);
}
}
}

View File

@ -1,27 +1,41 @@
package com.wix.RNCameraKit.camera;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.SensorManager;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.WindowManager;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.google.zxing.Result;
import com.wix.RNCameraKit.Utils;
import com.wix.RNCameraKit.camera.barcode.BarcodeScanner;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;
import static com.wix.RNCameraKit.camera.Orientation.getSupportedRotation;
@SuppressWarnings("MagicNumber deprecation") // We're still using Camera API 1, everything is deprecated
@SuppressWarnings("MagicNumber deprecation")
// We're still using Camera API 1, everything is deprecated
public class CameraViewManager extends SimpleViewManager<CameraView> {
private static Camera camera = null;
@ -33,6 +47,17 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
private static int currentRotation = 0;
private static AtomicBoolean cameraReleased = new AtomicBoolean(false);
private static boolean shouldScan = false;
private static BarcodeScanner scanner;
private static Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (scanner != null) {
scanner.onPreviewFrame(data, camera);
}
}
};
public static Camera getCamera() {
return camera;
}
@ -49,7 +74,7 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
}
static void setCameraView(CameraView cameraView) {
if(!cameraViews.isEmpty() && cameraViews.peek() == cameraView) return;
if (!cameraViews.isEmpty() && cameraViews.peek() == cameraView) return;
CameraViewManager.cameraViews.push(cameraView);
connectHolder();
createOrientationListener();
@ -58,13 +83,13 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
private static void createOrientationListener() {
if (orientationListener != null) return;
orientationListener = new OrientationEventListener(reactContext, SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(@IntRange(from = -1, to = 359) int angle) {
if (angle == OrientationEventListener.ORIENTATION_UNKNOWN) return;
setCameraRotation(359 - angle, false);
}
};
orientationListener.enable();
@Override
public void onOrientationChanged(@IntRange(from = -1, to = 359) int angle) {
if (angle == OrientationEventListener.ORIENTATION_UNKNOWN) return;
setCameraRotation(359 - angle, false);
}
};
orientationListener.enable();
}
static boolean setFlashMode(String mode) {
@ -108,6 +133,7 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
} catch (RuntimeException e) {
e.printStackTrace();
}
setBarcodeScanner();
}
private static void releaseCamera() {
@ -116,16 +142,16 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
}
private static void connectHolder() {
if (cameraViews.isEmpty() || cameraViews.peek().getHolder() == null) return;
if (cameraViews.isEmpty() || cameraViews.peek().getHolder() == null) return;
new Thread(new Runnable() {
@Override
public void run() {
if(camera == null) {
if (camera == null) {
initCamera();
}
if(cameraViews.isEmpty()) {
if (cameraViews.isEmpty()) {
return;
}
@ -135,6 +161,9 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
try {
camera.stopPreview();
camera.setPreviewDisplay(cameraViews.peek().getHolder());
if (shouldScan) {
camera.setOneShotPreviewCallback(previewCallback);
}
camera.startPreview();
} catch (IOException | RuntimeException e) {
e.printStackTrace();
@ -146,12 +175,12 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
}
static void removeCameraView() {
if(!cameraViews.isEmpty()) {
if (!cameraViews.isEmpty()) {
cameraViews.pop();
}
if(!cameraViews.isEmpty()) {
if (!cameraViews.isEmpty()) {
connectHolder();
} else if(camera != null){
} else if (camera != null) {
releaseCamera();
camera = null;
}
@ -188,8 +217,8 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
}
private static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
final double ASPECT_TOLERANCE = 0.15;
double targetRatio = (double) h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
@ -232,10 +261,65 @@ public class CameraViewManager extends SimpleViewManager<CameraView> {
parameters.setPictureSize(optimalPictureSize.width, optimalPictureSize.height);
parameters.setFlashMode(flashMode);
camera.setParameters(parameters);
} catch (RuntimeException ignored) {}
} catch (RuntimeException ignored) {
}
}
public static void reconnect() {
connectHolder();
}
public static int getRotationCount() {
return currentRotation / 90;
}
public static void setBarcodeScanner() {
scanner = new BarcodeScanner(reactContext, previewCallback);
scanner.setResultHandler(new BarcodeScanner.ResultHandler() {
@Override
public void handleResult(Result rawResult) {
WritableMap event = Arguments.createMap();
event.putString("qrcodeStringValue", rawResult.getText());
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(cameraViews.peek().getId(), "onReadCode", event);
}
});
}
@Nullable
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return MapBuilder.<String, Object>builder()
.put("onReadCode",
MapBuilder.of("registrationName", "onReadCode"))
.build();
}
@ReactProp(name = "scanBarcode")
public void setShouldScan(CameraView view, boolean scanBarcode) {
shouldScan = scanBarcode;
if (shouldScan && camera != null) {
camera.setOneShotPreviewCallback(previewCallback);
}
}
@ReactProp(name = "showFrame")
public void setFrame(CameraView view, boolean show) {
if (show) {
view.showFrame();
}
}
@ReactProp(name = "frameColor", defaultInt = Color.GREEN)
public void setFrameColor(CameraView view, @ColorInt int color) {
view.setFrameColor(color);
}
@ReactProp(name = "laserColor", defaultInt = Color.RED)
public void setLaserColor(CameraView view, @ColorInt int color) {
view.setLaserColor(color);
}
public static synchronized Rect getFramingRectInPreview(int previewWidth, int previewHeight) {
return cameraViews.peek().getFramingRectInPreview(previewWidth, previewHeight);
}
}

View File

@ -0,0 +1,217 @@
package com.wix.RNCameraKit.camera.barcode;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.wix.RNCameraKit.camera.CameraViewManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import me.dm7.barcodescanner.core.DisplayUtils;
public class BarcodeScanner {
public interface ResultHandler {
void handleResult(Result rawResult);
}
private MultiFormatReader mMultiFormatReader;
public static final List<BarcodeFormat> ALL_FORMATS = new ArrayList<>();
private List<BarcodeFormat> mFormats;
private ResultHandler mResultHandler;
private Context context;
private Camera.PreviewCallback previewCallback;
static {
ALL_FORMATS.add(BarcodeFormat.AZTEC);
ALL_FORMATS.add(BarcodeFormat.CODABAR);
ALL_FORMATS.add(BarcodeFormat.CODE_39);
ALL_FORMATS.add(BarcodeFormat.CODE_93);
ALL_FORMATS.add(BarcodeFormat.CODE_128);
ALL_FORMATS.add(BarcodeFormat.DATA_MATRIX);
ALL_FORMATS.add(BarcodeFormat.EAN_8);
ALL_FORMATS.add(BarcodeFormat.EAN_13);
ALL_FORMATS.add(BarcodeFormat.ITF);
ALL_FORMATS.add(BarcodeFormat.MAXICODE);
ALL_FORMATS.add(BarcodeFormat.PDF_417);
ALL_FORMATS.add(BarcodeFormat.QR_CODE);
ALL_FORMATS.add(BarcodeFormat.RSS_14);
ALL_FORMATS.add(BarcodeFormat.RSS_EXPANDED);
ALL_FORMATS.add(BarcodeFormat.UPC_A);
ALL_FORMATS.add(BarcodeFormat.UPC_E);
ALL_FORMATS.add(BarcodeFormat.UPC_EAN_EXTENSION);
}
public BarcodeScanner(Context context, Camera.PreviewCallback previewCallback) {
this.context = context;
this.previewCallback = previewCallback;
initMultiFormatReader();
}
public void setFormats(List<BarcodeFormat> formats) {
mFormats = formats;
initMultiFormatReader();
}
public void setResultHandler(ResultHandler resultHandler) {
mResultHandler = resultHandler;
}
public Collection<BarcodeFormat> getFormats() {
if(mFormats == null) {
return ALL_FORMATS;
}
return mFormats;
}
private void initMultiFormatReader() {
Map<DecodeHintType,Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, getFormats());
mMultiFormatReader = new MultiFormatReader();
mMultiFormatReader.setHints(hints);
}
public void onPreviewFrame(byte[] data, Camera camera) {
if(mResultHandler == null) {
return;
}
try {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
int width = size.width;
int height = size.height;
if (DisplayUtils.getScreenOrientation(context) == Configuration.ORIENTATION_PORTRAIT) {
int rotationCount = CameraViewManager.getRotationCount();
if (rotationCount == 1 || rotationCount == 3) {
int tmp = width;
width = height;
height = tmp;
}
data = getRotatedData(data, camera);
}
Result rawResult = null;
PlanarYUVLuminanceSource source = buildLuminanceSource(data, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = mMultiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} catch (NullPointerException npe) {
// This is terrible
} catch (ArrayIndexOutOfBoundsException ignored) {
} finally {
mMultiFormatReader.reset();
}
if (rawResult == null) {
LuminanceSource invertedSource = source.invert();
bitmap = new BinaryBitmap(new HybridBinarizer(invertedSource));
try {
rawResult = mMultiFormatReader.decodeWithState(bitmap);
} catch (NotFoundException e) {
// continue
} finally {
mMultiFormatReader.reset();
}
}
}
final Result finalRawResult = rawResult;
if (finalRawResult != null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
// Stopping the preview can take a little long.
// So we want to set result handler to null to discard subsequent calls to
// onPreviewFrame.
ResultHandler tmpResultHandler = mResultHandler;
mResultHandler = null;
//TODO:decide if I need to do this
//stopCameraPreview();
if (tmpResultHandler != null) {
tmpResultHandler.handleResult(finalRawResult);
}
}
});
} else {
camera.setOneShotPreviewCallback(previewCallback);
}
} catch(RuntimeException e) {
// TODO: Terrible hack. It is possible that this method is invoked after camera is released.
Log.w("CameraKit", e.toString());
}
}
private PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = CameraViewManager.getFramingRectInPreview(width, height);
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
PlanarYUVLuminanceSource source = null;
try {
source = new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
} catch(Exception e) {
e.printStackTrace();
}
return source;
}
private static byte[] getRotatedData(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
int width = size.width;
int height = size.height;
int rotationCount = CameraViewManager.getRotationCount();
if (rotationCount == 1 || rotationCount == 3) {
for (int i = 0; i < rotationCount; i++) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
data = rotatedData;
int tmp = width;
width = height;
height = tmp;
}
}
return data;
}
}

View File

@ -1,4 +1,4 @@
import React, {Component} from 'react';
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
@ -14,8 +14,9 @@ import {
} from 'react-native-camera-kit';
import CameraScreen from './src/CameraScreen';
import AlbumsScreen from './src/AlbumsScreen';
import GalleryScreen from './src/GalleryScreen';
import AlbumsScreen from './src/AlbumsScreen';
import GalleryScreen from './src/GalleryScreen';
import BarcodeScreen from './src/BarcodeScreen';
class example extends Component {
@ -32,29 +33,35 @@ class example extends Component {
return <Example />;
}
return (
<View style={{flex: 1}}>
<View style={{ flex: 1 }}>
<View style={styles.headerContainer}>
<Text style={styles.headerText}>
Welcome to Camera Kit
</Text>
<Text style={{fontSize: 40}}>📷</Text>
<Text style={{ fontSize: 40 }}>📷</Text>
</View>
<View style={styles.container}>
<TouchableOpacity onPress={() => this.setState({example: CameraScreen})}>
<TouchableOpacity onPress={() => this.setState({ example: BarcodeScreen })}>
<Text style={styles.buttonText}>
Barcode scanner Screen
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({ example: CameraScreen })}>
<Text style={styles.buttonText}>
Camera Screen
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({example: AlbumsScreen})}>
<TouchableOpacity onPress={() => this.setState({ example: AlbumsScreen })}>
<Text style={styles.buttonText}>
Albums Screen
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({example: GalleryScreen})}>
<TouchableOpacity onPress={() => this.setState({ example: GalleryScreen })}>
<Text style={styles.buttonText}>
Gallery Screen
</Text>

View File

@ -0,0 +1,44 @@
import React, { Component } from 'react';
import {
Alert
} from 'react-native';
import { CameraKitCameraScreen } from 'react-native-camera-kit';
export default class CameraScreen extends Component {
onBottomButtonPressed(event) {
const captureImages = JSON.stringify(event.captureImages);
Alert.alert(
`${event.type} button pressed`,
`${captureImages}`,
[
{ text: 'OK', onPress: () => console.log('OK Pressed') },
],
{ cancelable: false }
)
}
render() {
return (
<CameraKitCameraScreen
actions={{ rightButtonText: 'Done', leftButtonText: 'Cancel' }}
onBottomButtonPressed={(event) => this.onBottomButtonPressed(event)}
flashImages={{
on: require('./../images/flashOn.png'),
off: require('./../images/flashOff.png'),
auto: require('./../images/flashAuto.png')
}}
showFrame={true}
scanBarcode={true}
laserColor={"blue"}
frameColor={"yellow"}
onReadCode={((event) => console.log('QRCODE', event.nativeEvent.qrcodeStringValue))}
/>
);
}
}

View File

@ -7,7 +7,7 @@ export {
CameraKitGallery,
CameraKitCamera,
CameraKitGalleryView,
CameraKitCameraScreen
CameraKitCameraScreen,
};

7129
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
import React, {Component} from 'react';
import * as _ from 'lodash';
import React, { Component } from 'react';
import {
requireNativeComponent,
NativeModules
NativeModules,
processColor
} from 'react-native';
const NativeCamera = requireNativeComponent('CameraView', null);
@ -9,39 +11,44 @@ const NativeCameraModule = NativeModules.CameraModule;
export default class CameraKitCamera extends React.Component {
render() {
return <NativeCamera {...this.props}/>
}
render() {
const transformedProps = _.cloneDeep(this.props);
_.update(transformedProps, 'cameraOptions.ratioOverlayColor', (c) => processColor(c));
_.update(transformedProps, 'frameColor', (c) => processColor(c));
_.update(transformedProps, 'laserColor', (c) => processColor(c));
async logData() {
console.log('front Camera?', await NativeCameraModule.hasFrontCamera());
console.log('hasFlash?', await NativeCameraModule.hasFlashForCurrentCamera());
console.log('flashMode?', await NativeCameraModule.getFlashMode());
}
return <NativeCamera {...transformedProps}/>
}
static async requestDeviceCameraAuthorization() {
async logData() {
console.log('front Camera?', await NativeCameraModule.hasFrontCamera());
console.log('hasFlash?', await NativeCameraModule.hasFlashForCurrentCamera());
console.log('flashMode?', await NativeCameraModule.getFlashMode());
}
static async requestDeviceCameraAuthorization() {
const usersAuthorizationAnswer = await NativeCameraModule.requestDeviceCameraAuthorization();
return usersAuthorizationAnswer;
}
}
async capture(saveToCameraRoll = true) {
const imageTmpPath = await NativeCameraModule.capture(saveToCameraRoll);
return imageTmpPath;
}
async capture(saveToCameraRoll = true) {
const imageTmpPath = await NativeCameraModule.capture(saveToCameraRoll);
return imageTmpPath;
}
async changeCamera() {
const success = await NativeCameraModule.changeCamera();
return success;
}
async changeCamera() {
const success = await NativeCameraModule.changeCamera();
return success;
}
async setFlashMode(flashMode = 'auto') {
const success = await NativeCameraModule.setFlashMode(flashMode);
return success;
}
async setFlashMode(flashMode = 'auto') {
const success = await NativeCameraModule.setFlashMode(flashMode);
return success;
}
static async checkDeviceCameraAuthorizationStatus() {
return await NativeCameraModule.checkDeviceCameraAuthorizationStatus();
}
static async checkDeviceCameraAuthorizationStatus() {
return await NativeCameraModule.checkDeviceCameraAuthorizationStatus();
}
static async hasCameraPermission() {
const success = await NativeCameraModule.hasCameraPermission();

View File

@ -26,7 +26,6 @@ export default class CameraKitCamera extends React.Component {
static async requestDeviceCameraAuthorization() {
const usersAuthorizationAnswer = await NativeCameraAction.requestDeviceCameraAuthorization();
return usersAuthorizationAnswer;
}
async capture(saveToCameraRoll = true) {

View File

@ -37,14 +37,14 @@ export default class CameraScreenBase extends Component {
mode: FLASH_MODE_AUTO,
image: _.get(this.props, 'flashImages.auto')
},
{
mode: FLASH_MODE_ON,
image: _.get(this.props, 'flashImages.on')
},
{
mode: FLASH_MODE_OFF,
image: _.get(this.props, 'flashImages.off')
}
{
mode: FLASH_MODE_ON,
image: _.get(this.props, 'flashImages.on')
},
{
mode: FLASH_MODE_OFF,
image: _.get(this.props, 'flashImages.off')
}
];
this.state = {
captureImages: [],
@ -130,15 +130,20 @@ export default class CameraScreenBase extends Component {
<View style={styles.cameraContainer}>
{
this.isCaptureRetakeMode() ?
<Image
style={{flex: 1, justifyContent: 'flex-end'}}
source={{uri: this.state.imageCaptured.uri}}
/> :
<CameraKitCamera
ref={(cam) => this.camera = cam}
style={{flex: 1, justifyContent: 'flex-end'}}
cameraOptions={this.state.cameraOptions}
/>
<Image
style={{ flex: 1, justifyContent: 'flex-end' }}
source={{ uri: this.state.imageCaptured.uri }}
/> :
<CameraKitCamera
ref={(cam) => this.camera = cam}
style={{ flex: 1, justifyContent: 'flex-end' }}
cameraOptions={this.state.cameraOptions}
showFrame={this.props.showFrame}
scanBarcode={this.props.scanBarcode}
laserColor={this.props.laserColor}
frameColor={this.props.frameColor}
onReadCode={this.props.onReadCode}
/>
}
</View>
);
@ -195,7 +200,7 @@ export default class CameraScreenBase extends Component {
}
sendBottomButtonPressedAction(type, captureRetakeMode, image) {
if(this.props.onBottomButtonPressed) {
if (this.props.onBottomButtonPressed) {
this.props.onBottomButtonPressed({ type, captureImages: this.state.captureImages, captureRetakeMode, image })
}
}
@ -203,14 +208,14 @@ export default class CameraScreenBase extends Component {
async onButtonPressed(type) {
const captureRetakeMode = this.isCaptureRetakeMode();
if (captureRetakeMode) {
if(type === 'left') {
if (type === 'left') {
GalleryManager.deleteTempImage(this.state.imageCaptured.uri);
this.setState({imageCaptured: undefined});
this.setState({ imageCaptured: undefined });
}
else if(type === 'right') {
else if (type === 'right') {
const result = await GalleryManager.saveImageURLToCameraRoll(this.state.imageCaptured.uri);
const savedImage = {...this.state.imageCaptured, ...result}; // Note: Can't just return 'result' as on iOS not all data is returned by the native call (just the ID).
this.setState({imageCaptured: undefined, captureImages: _.concat(this.state.captureImages, savedImage)}, () => {
const savedImage = { ...this.state.imageCaptured, ...result }; // Note: Can't just return 'result' as on iOS not all data is returned by the native call (just the ID).
this.setState({ imageCaptured: undefined, captureImages: _.concat(this.state.captureImages, savedImage) }, () => {
this.sendBottomButtonPressedAction(type, captureRetakeMode);
});
}
@ -244,7 +249,7 @@ export default class CameraScreenBase extends Component {
renderBottomButtons() {
return (
<View style={[styles.bottomButtons, {backgroundColor: '#ffffff00'}]}>
<View style={[styles.bottomButtons, { backgroundColor: '#ffffff00' }]}>
{this.renderBottomButton('left')}
{this.renderCaptureButton()}
{this.renderBottomButton('right')}