I'm building a React Native Expo app that scans expense receipts (bills) and extracts the total amount using OCR (Tesseract.js). However, I'm facing multiple issues:
My Setup: React Native: "expo": "~50.0.0" Camera: expo-camera OCR: tesseract.js Issues I'm Facing: TypeScript Error with expo-camera
const cameraRef = useRef<Camera>(null); // Error: 'Camera' refers to a value but is used as a type I tried useRef<CameraType | null>(null), but it still gives an error. OCR Doesn't Work Properly
Tesseract.recognize(uri, "eng") sometimes returns empty text or incorrect values. I need to extract only the total amount from the receipt, but I can't reliably filter the text.
What I Need Help With: Fixing the Camera type issue in TypeScript. Making OCR more accurate, especially for extracting only the total amount from the receipt. Are there better alternatives to tesseract.js for mobile OCR in React Native Expo?
Fixing the Camera type issue in TypeScript. Making OCR more accurate, especially for extracting only the total amount from the receipt.
My Code :
import React, { useState, useEffect, useRef } from "react";
import { View, Text, TouchableOpacity, Image, StyleSheet } from "react-native";
import { Camera } from "expo-camera";
import Tesseract from "tesseract.js";
export default function ReceiptScanner() {
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
const [imageUri, setImageUri] = useState(null);
const [extractedText, setExtractedText] = useState("");
const cameraRef = useRef<Camera>(null);
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === "granted");
})();
}, []);
const takePicture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current?.takePictureAsync();
setImageUri(photo.uri);
extractText(photo.uri);
}
};
const extractText = async (uri: Tesseract.ImageLike) => {
try {
const result = await Tesseract.recognize(uri, "eng", {
logger: (m) => console.log(m), // Logs OCR progress
});
setExtractedText(result.data.text);
} catch (error) {
console.error("OCR Error:", error);
}
};
if (hasPermission === null) return <View />;
if (hasPermission === false) return <Text>No access to camera</Text>;
return (
<View style={styles.container}>
{!imageUri ? (
<Camera style={styles.camera} ref={cameraRef} />
) : (
<Image source={{ uri: imageUri }} style={styles.imagePreview} />
)}
<TouchableOpacity onPress={takePicture} style={styles.button}>
<Text style={styles.text}>Scan Receipt</Text>
</TouchableOpacity>
{extractedText ? (
<View style={styles.textContainer}>
<Text style={styles.resultTitle}>Extracted Text:</Text>
<Text style={styles.resultText}>{extractedText}</Text>
</View>
) : null}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: "center", justifyContent: "center" },
camera: { width: "100%", height: "70%" },
imagePreview: { width: "100%", height: "70%", resizeMode: "contain" },
button: {
backgroundColor: "blue",
padding: 10,
borderRadius: 5,
marginTop: 10,
},
text: { color: "white", fontSize: 18 },
textContainer: { marginTop: 20, paddingHorizontal: 10 },
resultTitle: { fontWeight: "bold", fontSize: 18 },
resultText: { fontSize: 16, marginTop: 5 },
});
I'm building a React Native Expo app that scans expense receipts (bills) and extracts the total amount using OCR (Tesseract.js). However, I'm facing multiple issues:
My Setup: React Native: "expo": "~50.0.0" Camera: expo-camera OCR: tesseract.js Issues I'm Facing: TypeScript Error with expo-camera
const cameraRef = useRef<Camera>(null); // Error: 'Camera' refers to a value but is used as a type I tried useRef<CameraType | null>(null), but it still gives an error. OCR Doesn't Work Properly
Tesseract.recognize(uri, "eng") sometimes returns empty text or incorrect values. I need to extract only the total amount from the receipt, but I can't reliably filter the text.
What I Need Help With: Fixing the Camera type issue in TypeScript. Making OCR more accurate, especially for extracting only the total amount from the receipt. Are there better alternatives to tesseract.js for mobile OCR in React Native Expo?
Fixing the Camera type issue in TypeScript. Making OCR more accurate, especially for extracting only the total amount from the receipt.
My Code :
import React, { useState, useEffect, useRef } from "react";
import { View, Text, TouchableOpacity, Image, StyleSheet } from "react-native";
import { Camera } from "expo-camera";
import Tesseract from "tesseract.js";
export default function ReceiptScanner() {
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
const [imageUri, setImageUri] = useState(null);
const [extractedText, setExtractedText] = useState("");
const cameraRef = useRef<Camera>(null);
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === "granted");
})();
}, []);
const takePicture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current?.takePictureAsync();
setImageUri(photo.uri);
extractText(photo.uri);
}
};
const extractText = async (uri: Tesseract.ImageLike) => {
try {
const result = await Tesseract.recognize(uri, "eng", {
logger: (m) => console.log(m), // Logs OCR progress
});
setExtractedText(result.data.text);
} catch (error) {
console.error("OCR Error:", error);
}
};
if (hasPermission === null) return <View />;
if (hasPermission === false) return <Text>No access to camera</Text>;
return (
<View style={styles.container}>
{!imageUri ? (
<Camera style={styles.camera} ref={cameraRef} />
) : (
<Image source={{ uri: imageUri }} style={styles.imagePreview} />
)}
<TouchableOpacity onPress={takePicture} style={styles.button}>
<Text style={styles.text}>Scan Receipt</Text>
</TouchableOpacity>
{extractedText ? (
<View style={styles.textContainer}>
<Text style={styles.resultTitle}>Extracted Text:</Text>
<Text style={styles.resultText}>{extractedText}</Text>
</View>
) : null}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: "center", justifyContent: "center" },
camera: { width: "100%", height: "70%" },
imagePreview: { width: "100%", height: "70%", resizeMode: "contain" },
button: {
backgroundColor: "blue",
padding: 10,
borderRadius: 5,
marginTop: 10,
},
text: { color: "white", fontSize: 18 },
textContainer: { marginTop: 20, paddingHorizontal: 10 },
resultTitle: { fontWeight: "bold", fontSize: 18 },
resultText: { fontSize: 16, marginTop: 5 },
});
Share
Improve this question
edited Mar 18 at 7:18
DarkBee
15.5k8 gold badges72 silver badges117 bronze badges
asked Mar 18 at 7:04
Ayana SagaraAyana Sagara
1
1 Answer
Reset to default 0I used another method as a work around. I used Flask API to do the OCR