我正在尝试在我的应用中实现一项功能,用户可以从相机胶卷中选择一张照片,然后该应用就会检测到图像中的二维码。
我目前正在使用react-native-camera-roll-picker:https://github.com/jeanpan/react-native-camera-roll-picker 和react-native-qrcode-local-image:https://github.com/remobile/react-native-qrcode-local-image
问题是本地QR码图像库要求我传递本地路径,并且与react-native-camera-roll-picker提供的本机uri不兼容。我会使用另一个库来解码图像二维码,但这个图像似乎是唯一可以在iOS和Android上运行并从现有图像而不是实际相机进行扫描的库。
我也尝试过实现react-native-fetch-blob以暂时在本地保存相机胶卷图像,但这也给我带来了麻烦:https://github.com/wkh237/react-native-fetch-blob
这是我目前尝试的函数,我在react-native-camera-roll-picker的“回调”道具中调用(以前的尝试被注释掉了):
_pickedImage(array,currentImg) {
console.log(currentImg)
var path = RNFS.DocumentDirectoryPath + '/pickedqr';
let rnfbURI = RNFetchBlob.wrap(RNFetchBlob.fs.asset(currentImg.uri))
const Blob = RNFetchBlob.polyfill.Blob
Blob.build(rnfbURI, {type:'image/jpg'}).then((b) => {
tmpBlob = b;
RNFetchBlob.fs.readFile(tmpBlob, 'base64').then((data) => {
console.log("Base64", data)
QRDecoder.decode(`data:image/gif;base64,${data}`, (error, result)=>{
console.log("Code", result)
console.log("Error", error)
});
});
})
/*fullPath = currentImg.uri.replace("assets-library://", "cdvfile://localhost/assets-library/")
QRDecoder.decode(fullPath, (error, result)=>{
console.log("Code", result)
console.log("Error", error)
});*/
/*let blb = Blob.build( rnfbURI, { type: 'image/jpg'})
console.log(blb)*/
/*RNFetchBlob.fs.readFile(rnfbURI, 'base64').then((data) => {
console.log("Base64", data)
QRDecoder.decode(`data:image/gif;base64,${data}`, (error, result)=>{
console.log("Code", result)
console.log("Error", error)
});
})*/
}
我现在完全失去了所以任何方法或见解都会受到高度赞赏。
答案 0 :(得分:1)
您可以使用react-native-camera
轻松解决此问题。
这是简单的代码段。
handleCodeDetected = (data) => {
// do whatever you want to do with data
}
...
...
<RNCamera
type={RNCamera.Constants.Type.back}
barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
onBarCodeRead={this.handleCodeDetected}
style={styles.preview}
/>
答案 1 :(得分:1)
This answer为我解决了该问题。 创建了本机方法来隐藏路径中的uri,这是我的代码:
@ReactMethod
public void getRealPathFromURI(String contentUriString, Promise promise) {
Uri contentUri = Uri.parse(contentUriString);
Cursor cursor = null;
try {
String wholeID = DocumentsContract.getDocumentId(contentUri);
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
cursor = reactContext.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
String filePath = "";
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
promise.resolve(filePath);
} catch (Throwable e) {
promise.reject(e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
和js:
DocumentPicker.pick({ type }).then((document: DocumentPickerResponse) => {
MyNativeModule.getRealPathFromURI(document.uri).then((path) => {
QRCodeLocalImage.decode(path, (err, res) => {
callback(err, { qrData: res });
});
});
});
答案 2 :(得分:1)
您可以只使用react-native-rn-zxing:
npm i react-native-rn-zxing
然后将其链接:
react-native link react-native-rn-zxing
用法:
import RnZxing from 'react-native-rn-zxing';
...
// Pass the callback as a parameter
RnZxing.showQrReader(this.onBarcodeScanned);
...
// Define the callback function to handle data after scan
onBarcodeScanned = (data) => {
this.setState({data: data});
};
答案 3 :(得分:0)
您可以使用react-native-qrcode-scanner
从图像或直接通过相机扫描QR。
安装:
使用以下命令安装依赖项:
yarn add react-native-camera react-native-qr-scanner
使用以下方式链接这些库:
react-native link react-native-camera && react-native-qr-scanner
您需要将权限添加到项目的AndroidManifest.xml。应该在您的android/app/src/main/AndroidManifest.xml
中添加以下内容:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE"/>
在iOS 10或更高版本中,您需要在项目的info.plist中添加“隐私-相机使用说明”键。这应该在your_project/ios/your_project/Info.plist
中找到。添加以下代码:
<key>NSCameraUsageDescription</key>
<string/>
<key>NSPhotoLibraryUsageDescription</key>
<string/>
<key>NSMicrophoneUsageDescription</key>
<string/>
<key>NSPhotoLibraryAddUsageDescription</key>
<string/>
用法:
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {QRreader} from 'react-native-qr-scanner';
import ImagePicker from 'react-native-image-picker';
export default class Scanner extends Component {
constructor(props) {
super(props);
this.state = {
reader: {
message: null,
data: null
}
};
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>{
this.openPhoto();
}}>
<Text style={{marginTop: 20}}>打开相册识别二维码</Text>
</TouchableOpacity>
<View>
{!this.state.reader? <Text>{!this.state.reader.message?'':`${this.state.reader.message}`}</Text>: <Text>{!this.state.reader.message?'':`${this.state.reader.message}:${this.state.reader.data}`}</Text>}
</View>
</View>
);
}
openPhoto(){
console.log('ImagePicker');
ImagePicker.launchImageLibrary({}, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
if(response.uri){
var path = response.path;
if(!path){
path = response.uri;
}
QRreader(path).then((data)=>{
this.setState({reader: {
message: '识别成功',
data: data
}});
// 十秒后自动清空
setTimeout(() => {
this.setState({reader: {
message: null,
data: null
}})
}, 10000);
}).catch((err)=>{
this.setState({reader: {
message: '识别失败',
data: null
}});
});
}
}
});
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff'
}
});
您可以在此处了解有关此库的更多信息:https://www.npmjs.com/package/react-native-qr-scanner
答案 4 :(得分:0)
您可以使用rn-qr-generator
它可以检测图像中的QR码
RNQRGenerator.detect({
uri: PATH_TO_IMAGE, // local path of the image. Can be skipped if base64 is passed.
base64: imageBase64String, // If uri is passed this option will be skipped.
})
.then(response => {
const { values } = response; // Array of detected QR code values. Empty if nothing found.
})