一、用到技术版本
1、react-native(0.59.8)
2、Android:buildToolsVersion = "28.0.3",minSdkVersion = 16,compileSdkVersion = 28,targetSdkVersion = 28,supportLibVersion = "28.0.0"
二、具体实现
react使用
import React, { Component } from 'react';
import {
AppRegistry,
Navigator,
TouchableOpacity,
StyleSheet,
Text,
View,
Image,
Platform,
Animated,
Easing,
} from 'react-native';
import { RNCamera } from 'react-native-camera'
import LocalBarcodeRecognizer from 'react-native-local-barcode-recognizer';
//图片选择器
var ImagePicker = require('react-native-image-picker');
//图片选择器参数设置
var options = {
title: '请选择图片来源',
cancelButtonTitle:'取消',
takePhotoButtonTitle:'拍照',
chooseFromLibraryButtonTitle:'相册图片',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
const imageBase64 = "data:image/jpeg;base64,";
export default class electronicsOrder extends Component{
constructor(props){
super(props);
// 初始化数据源
this.state={
tabTitle : this.props.tabLabel,
avatarSource: null,
textval:null,
sourceData:null,
viewAppear:false,
moveAnim: new Animated.Value(0)
}
}
componentDidMount() {
//进入后直接开始扫描
//this.startAnimation();
}
startAnimation = () => {
this.state.moveAnim.setValue(0);
Animated.timing(
this.state.moveAnim,
{
toValue: -200,
duration: 1500,
easing: Easing.linear
}
).start(() => this.startAnimation());
};
// 识别二维码
onBarCodeRead = (result) => {
const { navigate } = this.props.navigation;
const {data} = result;
if(data!=null && data!=''){
this.setState({textval:data,viewAppear:false},function(){
});
}
//如果要跳转地址使用下面的
// navigate('createOrder', {
// url: data
// })
};
//选择照片按钮点击
choosePic() {
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('用户取消了选择!');
}
else if (response.error) {
alert("ImagePicker发生错误:" + response.error);
}
else if (response.customButton) {
alert("自定义按钮点击:" + response.customButton);
}
else {
let source = { uri: response.uri };
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
sourceData:'data:image/jpeg;base64,' + response.data
});
}
});
}
beginSaoMiao(){
if(null!=this.state.avatarSource){
this.recoginze();
}
}
recoginze = async ()=>{
// Here is the demoe
let result = await LocalBarcodeRecognizer.decode(this.state.sourceData.replace("data:image/jpeg;base64,",""),{codeTypes:['ean13','qr']});
alert(result);
}
clickSaoMiao(){
this.setState({viewAppear: true},function(){
this.startAnimation();
});
}
render(){
return(
{this.state.textval==null?this.state.tabTitle:this.state.textval}
选择照片
this.beginSaoMiao()}>
获取图片中二维码或者条形码信息
this.clickSaoMiao()}>
开始扫描
{this.state.viewAppear ?
{
this.camera = ref;
}}
style={styles.preview}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
onBarCodeRead={this.onBarCodeRead}
>
将二维码放入框内,即可自动扫描
: null
}
);
}
}
const styles = StyleSheet.create({
center:{
flex:1,
justifyContent:'center',
alignItems:'center',
},
red:{
color:'#f00',
},
container:{
flex: 1,
// marginTop:25,
backgroundColor: '#F5FCFF',
// justifyContent: 'center',
// alignItems: 'center',
// flexDirection: 'row'
},
item:{
margin:15,
height:30,
borderWidth:1,
padding:6,
borderColor:'#ddd',
textAlign:'center'
},
image:{
height:198,
width:300,
alignSelf:'center',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center'
},
rectangleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent'
},
rectangle: {
height: 200,
width: 200,
borderWidth: 1,
borderColor: '#00FF00',
backgroundColor: 'transparent'
},
rectangleText: {
flex: 0,
color: '#fff',
marginTop: 10
},
border: {
flex: 0,
width: 200,
height: 2,
backgroundColor: '#00FF00',
}
});
Android
1) react-native-camera 需要修改 android目录下build.gradle文件中allprojects的repositories信息 加入如下代码
maven {
url 'https://maven.google.com'
}
maven {
url "https://jitpack.io"
}
allprojects {
repositories {
mavenLocal()
google()
jcenter()
maven {
url 'https://maven.google.com'
}
maven {
url "https://jitpack.io"
}
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
继续修改android/app/build.gradle文件
在defaultConfig中加入missingDimensionStrategy 'react-native-camera', 'general' 。因为加入三个第三方包导致android执行数量超过65536,所以在defaultConfig中继续加入如下代码:multiDexEnabled true
例如
defaultConfig {
applicationId "com.demo"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
missingDimensionStrategy 'react-native-camera', 'general'
multiDexEnabled true
}
2)react-native-local-barcode-recognizer
因为默认版本与我使用的不一致 我修改了其源码版本配置如下,
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1' //修改为一直3.3.1
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
sourceSets {
main {
aidl.srcDirs = ['src/main/java']
}
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.facebook.react:react-native:+'
implementation "com.google.zxing:core:3.3.0"
}
因为扫描识别率较低,有些还不能识别所以我参照原作者cicistream 的代码进行了如下修改 ,可以直接覆盖整个文件
文件路径android/src/main/java/cn.jystudio.local.barcode.recognizer.LocalBarcodeRecognizerModule.java
完整代码:
package cn.jystudio.local.barcode.recognizer;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.util.Base64;
import com.facebook.react.bridge.*;
import com.google.zxing.*;
import com.google.zxing.common.HybridBinarizer;
import java.util.*;
public class LocalBarcodeRecognizerModule extends ReactContextBaseJavaModule {
public static final String BARCODE_CODE_TYPE_KEY="codeTypes";
public static final Map VALID_BARCODE_TYPES =
Collections.unmodifiableMap(new HashMap() {
{
put("aztec", BarcodeFormat.AZTEC.toString());
put("ean13", BarcodeFormat.EAN_13.toString());
put("ean8", BarcodeFormat.EAN_8.toString());
put("qr", BarcodeFormat.QR_CODE.toString());
put("pdf417", BarcodeFormat.PDF_417.toString());
put("upc_e", BarcodeFormat.UPC_E.toString());
put("datamatrix", BarcodeFormat.DATA_MATRIX.toString());
put("code39", BarcodeFormat.CODE_39.toString());
put("code93", BarcodeFormat.CODE_93.toString());
put("interleaved2of5", BarcodeFormat.ITF.toString());
put("codabar", BarcodeFormat.CODABAR.toString());
put("code128", BarcodeFormat.CODE_128.toString());
put("maxicode", BarcodeFormat.MAXICODE.toString());
put("rss14", BarcodeFormat.RSS_14.toString());
put("rssexpanded", BarcodeFormat.RSS_EXPANDED.toString());
put("upc_a", BarcodeFormat.UPC_A.toString());
put("upc_ean", BarcodeFormat.UPC_EAN_EXTENSION.toString());
}
});
public LocalBarcodeRecognizerModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* @return the name of this module. This will be the name used to {@code require()} this module
* from javascript.
*/
@Override
public String getName() {
return "LocalBarcodeRecognizer";
}
@ReactMethod
public void decode(String base64Data, ReadableMap options, final Promise p){
try {
byte[] decodedString = Base64.decode(base64Data,Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
Result result = null;
MultiFormatReader reader = new MultiFormatReader();
if(options.hasKey(BARCODE_CODE_TYPE_KEY)){
ReadableArray codeTypes = options.getArray(BARCODE_CODE_TYPE_KEY);
if(codeTypes.size()>0) {
EnumMap hints = new EnumMap<>(DecodeHintType.class);
EnumSet decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
for(int i=0;i> 24;
R = (argb[argbIndex] & 0xff0000) >> 16;
G = (argb[argbIndex] & 0xff00) >> 8;
B = (argb[argbIndex] & 0xff);
argbIndex++;
// well known RGB to YUV algorithm
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
Y = Math.max(0, Math.min(Y, 255));
U = Math.max(0, Math.min(U, 255));
V = Math.max(0, Math.min(V, 255));
yuv420sp[yIndex++] = (byte) Y;
// ---UV---
if ((j % 2 == 0) && (i % 2 == 0)) {
yuv420sp[uvIndex++] = (byte) V;
yuv420sp[uvIndex++] = (byte) U;
}
}
}
}
private Bitmap rotateImage(Bitmap src, float degree)
{
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
Bitmap bmp = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return bmp;
}
private Bitmap getSmallerBitmap(Bitmap bitmap){
int size = bitmap.getWidth() * bitmap.getHeight() / 160000;
if (size <= 1){
return bitmap; // 如果小于
}else {
Matrix matrix = new Matrix();
matrix.postScale((float) (1 / Math.sqrt(size)), (float) (1 / Math.sqrt(size)));
Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,true);
return resizeBitmap;
}
}
}
上传几张示例图