React Native: a Simple OCR scanner

Bráulio Carvalho
Inflight IT
Published in
3 min readJun 29, 2021

At InflightIT, we studied about OCR (Optical Character Recognition) to implement in upcoming projects and additional features to our ongoing projects. For example, reading invoices from restaurants/shops.

In this OCR sample we can select or take a photo from our device. For that we’ll use:

  • react-native-image-picker (picking images)
  • rn-text-detector (text recognization from photo)

1. React-Native

First we need to create a react-native project and choose between a javascript or typescript based-project. Personally i’m opting for typescript every time I can, regardless if the project is a large or a small one. Typescript does give more comfort when debugging and helps to have a good structure.

npx react-native init ocrSampleApp --template react-native-template-typescript

2. Install dependencies

npm i react-native-image-picker --save && npm i rn-text-detector --save
npx pod-install

3. Additional configurations

iOS

For iOS we need to add this code to Info.plist. It is required by Apple and we need to say why we need camera access.

<key>NSCameraUsageDescription</key>
<string>App needs permission to access your phone camera.</string><key>NSPhotoLibraryAddUsageDescription</key>
<string>App store photos in your phone library.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App store photos in your phone library.</string>

Android

For Android we also need to add permissions in AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

4. Basic usage

Import main packages to work with.

import { launchCamera, launchImageLibrary } from "react-native-image-picker";
import RNTextDetector from "rn-text-detector";

Create a state to our app.

const [state, setState] = useState<{
loading: boolean;
image: string | null;
toast: {
message: string;
isVisible: boolean;
};
textRecognition: [] | null;
}>({
loading: false,
image: null,
textRecognition: null,
toast: {
message: "",
isVisible: false,
},
});

Add the following functions in order to perform a simple string.

function onPress(type: "capture" | "library") {
setState({ ...state, loading: true });
type === "capture"
? launchCamera({ mediaType: "image" }, onImageSelect)
: launchImageLibrary({ mediaType: "image" }, onImageSelect);
}
async function onImageSelect(media: { assets: [{ uri: string }] }) {
if (!media) {
setState({ ...state, loading: false });
return;
}
if (!!media && media.assets) {
const file = media.assets[0].uri;
const textRecognition = await RNTextDetector.detectFromUri(file);
const INFLIGHT_IT = "Inflight IT";
//if match toast will appear
const matchText = textRecognition.findIndex((item: { text: string
}) => item.text.match(INFLIGHT_IT));
setState({
...state,
textRecognition,
image: file,
toast: {
message: matchText > -1 ? "Ohhh i love this company!!" : "",
isVisible: matchText > -1,
},
loading: false,
});
}}

Make your view to display text and image.

return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>RN OCR SAMPLE</Text>
<View style={getSpace(20)}>
<TouchableOpacity style={[styles.button, styles.shadow]}
onPress={() => onPress("capture")}>
<Text>Take Photo</Text>
</TouchableOpacity>
<View style={getSpace(20)}>
<TouchableOpacity
style={[styles.button, styles.shadow]}
onPress={() => onPress("library")}
>
<Text>Pick a Photo</Text>
</TouchableOpacity>
</View>
<View style={getSpace(50)}>
<WrapLoading loading={state.loading}>
<View style={{ alignItems: "center" }}>
<Image style={[styles.image, styles.shadow]}
source={{ uri: state.image }} />
</View>
{!!state.textRecognition &&
state.textRecognition.map(
(item: { text: string }, i: number) => (
<Text key={i} style={getSpace(10)}>
{item.text}
</Text>
))}
</WrapLoading>
</View>
</View>
{state.toast.isVisible &&
ToastAndroid.showWithGravityAndOffset(
state.toast.message,
ToastAndroid.LONG,
ToastAndroid.BOTTOM,
25,
50
)}
</View>
</SafeAreaView>
);

Then just try it! 🚀

Android example

5. Conclusion

With a few steps you can achieve text-recognition with only 2 libraries without using Firebase at all. Hope you enjoy it!

Inflight IT is a team of experts and enthusiasts on software development and user experience design. We are a team ready to create and transform digital systems to an user experience centric approach. We design and develop for people. Check our website and contact us for any inquiries: https://inflightit.com/.

--

--