*Rectangle bounding boxes are not showing at correct positions for picket values.
2nd thing: only one out of three is showing.
To draw rectangles i am using frame/rect ={top,left, width,height} info received from googlemlkit in picked text element or line.
image info contain image width, height and aspect ratio How can i adjust thee position of these 3 rectangles at exact positions If need any data sample i can add it too *
import React, {useState}from "react";
import {
View,
useWindowDimensions,
ImageBackground,
} from "react-native";
import PropTypes from "prop-types";
import {BaseColor, useTheme } from "@config";
import { SafeAreaView, } from "@components";
import styles from "./styles";
import moment from "moment";
import Modal from "react-native-modal";
import { useTranslation } from "react-i18next";
import {recognizeImage} from '../../mlkit';
import { Svg, Rect } from 'react-native-svg';
export default function OcrView(props) {
const { modalVisible, expLine, image, base64} = props;
const { colors } = useTheme();
const { t, i18n } = useTranslation();
const { height, width } = useWindowDimensions();
var dateFormat = i18n.language == "en" ? "MM/DD/YYYY" : "DD-MM-YYYY";
const [amountValu, setAmountValu] = useState(null);
const [dateVal, setDateVal] = useState(null);
const [currVal, setCurreVal] = useState(expLine?.currency);
const [currBlock, setCurrBlock] = useState(null);
const [ammBlock, setAmmBlock] = useState(null);
const [dateBlock, setDateBlock] = useState(null);
const currencies = ['AED', 'ALL','DKK', 'USD']
const [isImageLoaded, setIsImageLoaded] = useState(false);
const getText = async (path, base64) => {
if(path!=null || base64!=null)
{
try{
const response = await recognizeImage(path, base64);
var amountSet = false;
var dateisSet= false;
var previous=0.0;
var amount="";
var dateFound=null;
var currencyFound=null;
var dateBlock=null;
var amountBlock=null;
var currBlock=null;
for (let block of response.blocks) {
//console.log('block:', block.text);
for (let line of block.lines) {
//console.log('line:', line.text);
if(!amountSet)
{
let isAmount = isAmountCheck(line.text);
if(isAmount!=""){
let amountval =line.text.replace(/ /g, "");
let current = 0.0;
try{
if(isAmount== "en")
{
current= parseFloat(amountval.replace(/,/g, ""));
}
else{
let value = amountval.replace(/\./g, "");
value = value.replace(/,/g,".");
current= parseFloat(value);
}
}
catch (e)
{
console.log('parseFloat:', amountval, e);
}
if(current>previous)
{
previous= current;
if(i18n.language == "en")
{
if(isAmount== "en")
{
amount= amountval;
}else{
amount= new Intl.NumberFormat("en-US", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(current);
}
}
else
{
if(isAmount== "dk")
{
amount= amountval;
}else {
amount= new Intl.NumberFormat("da-DK", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(current);
}
}
amountBlock = line;
}
}
}
if(!dateisSet)
{
let format= checkDateFormats(line.text);
if(format!="")
{
dateFound = dateFormatChange(line.text,format);
dateisSet = true;
dateBlock = line;
//console.log('dateisSet 1 : ', dateFound);
}
}
for (let element of line.elements) {
//console.log('element:', element.text);
if(!amountSet)
{
let isAmount = isAmountCheck(element.text);
if(isAmount!=""){
let amountval = element.text.replace(/ /g, "");
let current = 0.0;
try{
if(isAmount== "en")
{
current= parseFloat(amountval.replace(/,/g, ""));
}
else{
let value = amountval.replace(/\./g, "");
value = value.replace(/,/g,".");
current= parseFloat(value);
}
}
catch (e)
{
console.log('parseFloat:', amountval, e);
}
if(current>previous)
{
previous= current;
if(i18n.language == "en")
{
if(isAmount== "en")
{
amount= amountval;
}else{
amount= new Intl.NumberFormat("en-US", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(current);
}
}
else
{
if(isAmount== "dk")
{
amount= amountval;
}else {
amount= new Intl.NumberFormat("da-DK", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(current);
}
}
amountBlock = element;
}
}
}
if(!dateisSet)
{
let format= checkDateFormats(element.text);
//console.log('dateCheck:', element.text, format);
if(format!="")
{
dateFound = dateFormatChange(element.text,format);
dateisSet = true;
dateBlock = element;
//console.log('dateisSet:', dateFound);
}
}
if(currencyFound==null)
{
if(currencies.includes(element.text))
{
currencyFound= element.text;
currBlock= element;
}
}
}
}
}
//console.log('ocrview ','amount:', amount, " dateFound: ", dateFound, " currencyFound ", currencyFound);
if(amount!="")
{
setAmountValu(amount);
setAmmBlock(amountBlock);
if(dateFound!=null)
{
setDateVal(dateFound);
setDateBlock(dateBlock);
}
if(currencyFound!=null)
{
setCurreVal(currencyFound);
setCurrBlock(currBlock);
}
console.log(image);
setIsImageLoaded(true);
}
}
catch(err)
{
console.log("ocrview getText err ", err);
}
}
};
function isAmountCheck(toMatch) {
let found ="";
if( toMatch?.match(/^\d{1,3}((\.|\s)?\d{1,3})*\s*,\s*\d{1,2}?$/))
{
found= "dk";
}
else if(toMatch?.match(/^\d{1,3}((,|\s)?\d{1,3})*\s*\.\s*\d{1,2}?$/))
{
found= "en";
}
//console.log("ocrview ToMatch =>",found,toMatch);
return found ;
}
function checkDateFormats(toMatch) {
try{
if(toMatch.match(/^(0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[0-2])-(\d{4}$)/))
{
return "DD-MM-YYYY";
}
if(toMatch.match(/^(0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[0-2])\.(\d{4}$)/))
{
return "DD.MM.YYYY";
}
else return "";
}
catch(e)
{
console.log("ocrview checkDateFormats", toMatch, e);
return "";
}
};
function dateFormatChange(toChange, currentFormat) {
var date_ =null;
try{
let momentObj = moment(toChange, currentFormat);
date_ = moment(momentObj).format(dateFormat);
}
catch(e)
{
console.log("ocrview dateFormatChange", e,"currentFormat =",currentFormat);
}
return date_;
};
const BoundingTextView = ({ left, top, widt, heig, block}) => (
console.log(block?.rect, block.text),
<Rect
x={left}
y={top}
width={widt}
height={heig}
stroke={'red'}
strokeWidth={2}
fill="transparent"
/>
);
return (
<Modal
isVisible={modalVisible}
onBackButtonPress={() => props.toggle()}
onBackdropPress={() => props.toggle()}
swipeDirection={["down"]}
animationInTiming={500}
animationOutTiming={500}
animationOut={"slideOutDown"}
backdropOpacity={0.6}
onShow ={() =>{getText(image?.uri, base64)}}
>
<SafeAreaView
style={{
backgroundColor: colors.card,
maxHeight: height,
flex:1,
}}
edges={["right", "left", "bottom"]}
>
<View style={{backgroundColor: "white",marginBottom:5 ,justifyContent:'center', alignItems:'center'}}>
{isImageLoaded && <ImageBackground
source={{
uri: image?.uri,
}}
style={{
width: width * 0.9,
height: height * 0.74,
}}
onLayout={event => {
console.log("onLayout",event.nativeEvent.layout);
}}
>
<Svg width={width * 0.9} height={height * 0.74}>
{ dateBlock !=null &&<BoundingTextView
key={0}
left={dateBlock.rect.left}
top={dateBlock.rect.top}
widt={dateBlock.rect.width}
heig={dateBlock.rect.height}
block={dateBlock}
/>}
{ ammBlock !=null &&<BoundingTextView
key={1}
left={ammBlock.rect.left}
top={ammBlock.rect.top}
widt={ammBlock.rect.width}
heig={ammBlock.rect.height}
block={ammBlock}
/>}
{ currBlock !=null &&<BoundingTextView
key={2}
left={currBlock.rect.left}
top={currBlock.rect.top}
widt={currBlock.rect.width}
heig={currBlock.rect.height}
block={currBlock}
/>}
</Svg>
</ImageBackground>}
</View>
</SafeAreaView>
</Modal>
);
}
OcrView.propTypes = {
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
image: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
blocks: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
expLine: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
base64: PropTypes.string,
modalVisible: PropTypes.bool,
};
OcrView.defaultProps = {
style: {},
image: {},
expLine: {},
base64:null,
modalVisible: false,
};