How to integrate OCR with Expo - react-native

I tried using various libraries such as react-native-tesseract react-native-text-detector in Expo in order to integrate OCR but they did not work. This is my code and I am wondering how to integrate OCR within it. Thank you in advance for solutions!
takePicture = async () => {
if (this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
this.runOcr(data.uri);
}
};
runOcr = async (imageUri) => {
//code here
};
return (
<>
<Camera
ref={(ref) => {
this.camera = ref;
}}
style={{
flex: 1,
position: "absolute",
width: "100%",
height: "100%",
}}
type={Camera.Constants.Type.back}
autoFocus={Camera.Constants.AutoFocus.on}
flashMode={
!this.state.isFlash
? Camera.Constants.FlashMode.off
: Camera.Constants.FlashMode.on
}
/>
<View
style={{
position: "absolute",
bottom: "5%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
flexDirection: "row",
}}
>
<TouchableOpacity onPress={this.takePicture}>
<Image
style={{ width: 90, height: 90 }}
source={require("./assets/rec.png")}
/>
</TouchableOpacity>
</View>
</>
);
runOcr is the function where OCR happens however I removed the OCR code.

Related

How to implement swipeable in react native gesture handler

I want to implement a swipe to delete feature on flatlist data. I can get the swipe to work, but it only registers after the touch input is lifted. When I start dragging, the card does not initially drag, but it swipes after I lift the input. How can I make it so it starts dragging when I start moving the card?
Current Code:
export default class AppleStyleSwipeableRow extends Component {
private renderRightAction = (x: number, dragX) => {
const trans = dragX.interpolate({
inputRange: [0, 1],
outputRange: [x, 0],
extrapolate: "clamp",
});
const pressHandler = () => {
this.close();
Alert.alert("hi");
};
return (
<Animated.View
style={{
flex: 1,
borderRadius: 15,
height: 120,
transform: [{ translateX: trans }],
}}
>
<RectButton
style={[
styles.rightAction,
{ backgroundColor: "transparent", height: 50 },
]}
onPress={pressHandler}
>
<SquircleView
style={StyleSheet.absoluteFill}
squircleParams={{
cornerSmoothing: 0.6,
cornerRadius: 15,
fillColor: "#FF3B30",
}}
>
<Image
style={{
width: 17.37 * 1.5,
height: 19.66 * 1.5,
justifyContent: "center",
alignSelf: "center",
top: 40,
right: 3.5,
}}
source={require("../../assets/trash.fill.png")}
></Image>
</SquircleView>
</RectButton>
</Animated.View>
);
};
private renderRightActions = (
progress: Animated.AnimatedInterpolation,
_dragAnimatedValue: Animated.AnimatedInterpolation
) => (
<View
style={{
width: 90,
flexDirection: I18nManager.isRTL ? "row-reverse" : "row",
}}
>
{this.renderRightAction(90, progress)}
</View>
);
private swipeableRow?: Swipeable;
private updateRef = (ref: Swipeable) => {
this.swipeableRow = ref;
};
private close = () => {
this.swipeableRow?.close();
};
render() {
const { children } = this.props;
return (
<Swipeable
containerStyle={{ borderRadius: 15 }}
childrenContainerStyle={{ backgroundColor: "white", borderRadius: 15 }}
ref={this.updateRef}
friction={3}
enableTrackpadTwoFingerGesture
rightThreshold={40}
renderRightActions={this.renderRightActions}
>
{children}
</Swipeable>
);
}
}
const styles = StyleSheet.create({
actionText: {
color: "white",
fontSize: 16,
backgroundColor: "transparent",
padding: 10,
},
rightAction: {
alignItems: "center",
flex: 1,
justifyContent: "center",
left: 10,
},
});
ScreenA.tsx
const RenderItem = ({ item }) => {
return (
<View style={{ height: 120, width: W_WIDTH * 0.9, zIndex: -100 }}>
<Image
source={require("../../assets/pin.png")}
style={{
position: "absolute",
width: 40,
height: 40,
}}
/>
<Text
style={{
fontSize: 22,
paddingRight: 16,
color: "black",
fontFamily: "Medium",
left: 45,
top: 6,
}}
>
Foo
</Text>
</View>
);
};
const ScreenA = () => {
const SwipeableRow = ({ item }) => {
return (
<RectButton
style={{
width: W_WIDTH * 0.9,
height: 120,
alignItems: "center",
backgroundColor: "#f3f2f8",
borderRadius: 10,
marginHorizontal: 20,
marginTop: 20,
}}
onPress={() =>
navigation.navigate("ScreenB")
}
>
<AppleStyleSwipeableRow>
<RenderItem item={item} />
</AppleStyleSwipeableRow>
</RectButton>
);
};
return (
<StatusBar style={colorScheme == "dark" ? "light" : "dark"} />
<ScrollView
style={[
styles.container,
{
backgroundColor: colorScheme == "dark" ? "black" : "white",
},
]}
contentInsetAdjustmentBehavior="automatic"
keyboardDismissMode="on-drag"
>
<FlatList
data={bookmarks}
keyExtractor={(item) => item.country}
renderItem={({ item }) => <SwipeableRow item={item} />}
// renderItem={renderItem}
showsVerticalScrollIndicator={false}
/>
</ScrollView>
);
};
}
Does your RectButton have an onPressIn prop? That's what you'll need to use - if it doesn't have it, switch it out for a Pressable or other component with this prop.

image onLoad width is undefined

When running the following code without the ImageZoom component,the useEffect hook console logs this : Object { "height": 412, "width": 231.66666666666666, } which is the right height and width of the image on load (the size of the image as displayed).
but when im adding the ImageZoom component I get a Component Exception Cannot read property 'width' of undefined.
const ImageModal = ({ image, isOpenImage, onStateChange }) => {
const [imageLoad, setImageLoad] = useState({ width: null, height: null });
const handleLoad = (event) => {
setImageLoad({
width: event.nativeEvent.source.width,
height: event.nativeEvent.source.height,
});
};
useEffect(() => {
console.log(imageLoad);
}, [imageLoad]);
const NewImage = useCallback(
() => (
<Image
onLoad={(event) => handleLoad(event)}
source={image}
style={{ flex: 1 }}
resizeMode="contain"
/>
),
[]
);
return (
<Modal
style={{ flex: 1 }}
animationType="slide"
transparent={true}
visible={isOpenImage}>
<Fragment>
<View
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: '#000000',
opacity: 0.5,
}}
/>
<View
style={{
position: 'absolute',
bottom: 22.5,
zIndex: 2,
alignSelf: 'center',
}}>
<TouchableOpacity
onPress={() => {
onStateChange(false);
}}
style={{
width: 130,
height: 47,
borderRadius: 50,
borderWidth: 2,
borderColor: '#fff',
backgroundColor: '#2e423d',
transform: [{ scaleX: 1 }],
justifyContent: 'center',
}}>
<Text
style={{
fontSize: 18.8,
fontFamily: 'OpenSansHebrew-Regular',
color: '#ffffff',
alignSelf: 'center',
}}>
סגירה
</Text>
</TouchableOpacity>
</View>
<View
style={{
flex: 1,
backgroundColor: 'white',
marginBottom: 0,
marginHorizontal: 15,
borderRadius: 20,
}}>
<View
style={{
flex: 1,
backgroundColor: 'white',
marginBottom: 0,
marginBottom: 250,
marginTop: 150,
justifyContent: 'center',
}}>
<ImageZoom
cropWidth={screenWidth}
cropHeight={screenHeight}
imageWidth={imageLoad.width}
imageHeight={imageLoad.height}>
<NewImage />
</ImageZoom>
</View>
</View>
</Fragment>
</Modal>
);
};
try initializing imageLoad state with some data.
const [imageLoad, setImageLoad] = useState({width: 0, height: 0});
You are initializing the state imageLoad with an empty value. First of all you have to define the width and height of the value in your useState hook like this -
const [imageLoad, setImageLoad] = useState({width:null, height: null});
It's showing error because you have not defined your width and height objects in the state imageLoad.
according to your comment, it seems that your state is not updating before rendering of the ImageZoom component.
First try to update the state before the ImageZoom renders for that you can create a new state called imageLoaded and than update this state in your useEffect like this ->
const [imageLoaded , setImageLoaded ] = useState(false);
useEffect(() => {
getDimensions ()
}, []);
const getDimensions = (url) => {
var img = new Image();
img.src = url;
img.onload = ()=> { setImageLoad({
width: img.width,
height: img.height,
})
setImageLoaded(true) }
}
Now render component On State of ImageLoad
ImageLoaded ?
<ImageZoom
cropWidth={screenWidth}
cropHeight={screenHeight}
imageWidth={imageLoad.width}
imageHeight={imageLoad.height}>
<NewImage />
</ImageZoom>
: null;
Now you don't need the onLoad event in your image component

React-Native Flatlist ignoring styles

I'm stuck in why the Flatlist ignores almost every style, like space-around list items and space-around header components and everything.
Here is my code:
renderHeader = () => {
return (
<Text style={styles.scheduleHeaderContainer}>
<Text style={styles.headerNotReady}>NOT READY YET</Text>
<Text style={styles.headerCleared}>CLEARED</Text>
</Text>
)
}
renderItemSeparator = () => <View style={{height: 10, backgroundColor: '#828282', width: 1, zIndex: 1, position: 'absolute'}}/>
...
<View style={styles.listContainer}>
<FlatList
data={this.state.rooms}
style={styles.scheduleContainer}
horizontal={false}
numColumns={4}
ListHeaderComponent={this.renderHeader}
ItemSeparatorComponent={this.renderItemSeparator}
renderItem={({ item, index }) => {
console.log('item', item.room);
return (
<View style={styles.elementsContainer}>
<Text>
{item.room.data.name}
</Text>
</View>
);
}}
keyExtractor={(item, index) => String(index)}
/>
</View>
And here are some styles:
listContainer: {
position: 'absolute',
width: '100%',
left: 14,
right: 14,
top: 353,
height: 200,
},
scheduleContainer: {
backgroundColor: '#FFFFFF',
alignSelf: 'center',
width: '100%'
},
scheduleHeaderContainer:{
alignSelf: 'center',
},
headerNotReady: {
flex: 1,
},
headerCleared: {
flex: 1
},
Here is the result, some of the styles not working, like flex, space-around ...
Here is the result I'm looking for:
I don't know what caused the problem. However, you can get a result close to the look you want from this.
https://snack.expo.io/LZGnhJwoz

How do I move a buttom from behind an image using React Native

I have attached a screen shot of the problem. I can't seem to be able to move my button from behind an image object. I tried zIndex and moving my Views around but I am still getting the same issue. The code seems to only work on IOS but not on Android.
Your assistance will be greatly appreciated. my code is below.
Thank you.
Project Screenshot
import * as React from 'react';
import { StyleSheet, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';
import * as Permissions from 'expo-permissions';
import { EvilIcons } from '#expo/vector-icons'
export default class ImagePickerExample extends React.Component {
state = {
image: null,
};
render() {
let { image } = this.state;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View style={styles.emptyProfile}>
{image && <Image source={{ uri: image }} style={styles.profile} />}
</View>
<View style={{ marginLeft: 70, justifyContent: 'center', bottom: 25 }}>
<View style={styles.camera}>
<EvilIcons name='camera' size={35} color='#fff' onPress={this._pickImage} />
</View>
</View>
</View>
);
}
componentDidMount() {
this.getPermissionAsync();
}
getPermissionAsync = async () => {
if (Constants.platform.ios) {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
};
_pickImage = async () => {
try {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 4],
quality: 1,
});
if (!result.cancelled) {
this.setState({ image: result.uri });
}
console.log(result);
} catch (E) {
console.log(E);
}
};
}
const styles = StyleSheet.create({
camera: {
backgroundColor: '#fd4336',
height: 50,
width: 50,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
},
profile: {
width: 190,
height: 190,
borderRadius: 100,
justifyContent: 'center',
alignItems: 'center',
},
emptyProfile: {
width: 200,
height: 200,
borderRadius: 100,
backgroundColor: '#c1b78d',
borderWidth: 5,
borderColor: '#fff',
shadowColor: 'black',
shadowOffset: { width: 0, height: 3 },
shadowRadius: 3,
shadowOpacity: 0.3,
elevation: 5
}
})
SCREENSHOT
Okay I managed to figure it out! by wrapping another View
<View style={styles.emptyProfile}>
{image && <Image source={{ uri: image }} style={styles.profile} />}
<View style={{ left: 140, position: 'absolute', bottom: 50 }} >
<View style={styles.camera}>
<EvilIcons name='camera' size={35} color='#fff' onPress={this._pickImage} />
</View>
</View>
</View>
);

How to call an async function in TextInput's onChangeText

Here is my code
SearchFilterFunction(text) {
callApi = async () => {
try {
const response = await
fetch('http://192.168.100.229:9085/api/V1AndroidUnAuthorizedFastSearch?
title=${text}');
const responseJson = await response.json();
this.setState({
isLoading: false,
dataSource: responseJson.data,
}, function () {
});
}
catch (error) {
console.error(error);
}
}
}
render() {
return (
<View style={{ flexDirection: 'column' }}>
<View style={{
flexDirection: 'column',
alignItems: 'stretch',
}}>
<View style={{
height: 50,
backgroundColor: '#008cff',
flexDirection: 'row',
justifyContent: 'space-between'
}} >
<Image source={require('./asset/ic_buy_package.png')}
style={{ width: 30, height: 30, marginTop: 10, marginLeft: 10 }}
/>
<Image source={require('./asset/img_logo.png')}
style={{ width: 30, height: 30, marginTop: 10 }} />
<TouchableHighlight onPress={this.callApi}>
<Image source={require('./asset/ic_menu.png') }
style={{ width: 30, height: 30, marginTop: 10, marginRight:
10, }}
/>
</TouchableHighlight>
</View>
</View>
<View style={{
height: 50,
backgroundColor: "#008cff"
}}>
<TextInput
style={{ height: 40, backgroundColor: '#ffffff', marginRight: 10,
marginLeft: 10, marginTop: 5, textAlign: 'right', paddingRight: 10 }}
placeholder='جستجو...'
onChangeText={text => this.SearchFilterFunction(text).callApi}
onClear={text => this.SearchFilterFunction().callApi}
/>
</View>
<Text>{this.state.input}</Text>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text style={{fontSize:15,margin:10}}>
{item.title}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
};
but when type in TextInput i get this error
undefined is not an object
(evaluating'_this3.searchfilterfunction(text).callApi'
I want get text from TextInput and fetch my API with the entered text.
There are several problems here:
1) You are defining a function inside a function
SearchFilterFunction(text) {
callApi = async () => {
2) If you want to insert a variable value inside a string use ` instead of '.
3) This function call does not work this.SearchFilterFunction(text).callApi
Modifications:
Change your function to SearchFilterFunction to:
async SearchFilterFunction(text) {
try {
const response = await
fetch(`http://192.168.100.229:9085/api/V1AndroidUnAuthorizedFastSearch?
title=${text}`);
const responseJson = await response.json();
console.log('response', responseJson);
// set your state here
}
catch (error) {
console.error(error);
}
}
Change your TextInput to:
<TextInput
style={{ height: 40, backgroundColor: '#ffffff', marginRight: 10,
marginLeft: 10, marginTop: 5, textAlign: 'right', paddingRight: 10 }}
onChangeText={text => this.SearchFilterFunction(text)}
onClear={text => this.SearchFilterFunction()}
/>
Working example:
I created a simplified working example here:
https://snack.expo.io/S1LWHvH2V