0% found this document useful (0 votes)
10 views6 pages

Upload

This document is a React component that allows users to upload an image, which is then processed to detect a number plate and extract text using OCR. It utilizes Tesseract.js for text recognition and Axios for API calls to upload the image and detect the number plate. The component also handles loading states and error messages while providing a user-friendly interface for image uploads and displaying results.

Uploaded by

awaistest530
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views6 pages

Upload

This document is a React component that allows users to upload an image, which is then processed to detect a number plate and extract text using OCR. It utilizes Tesseract.js for text recognition and Axios for API calls to upload the image and detect the number plate. The component also handles loading states and error messages while providing a user-friendly interface for image uploads and displaying results.

Uploaded by

awaistest530
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

'use client';

import { useState, useEffect } from "react";


import axios from "axios";
import Tesseract from "tesseract.js"; // Import Tesseract.js
import { useSearchParams } from 'next/navigation'; // <-- To read the query from
Link

const base_url = process.env.NEXT_PUBLIC_URL;

const Page = () => {


const [imageUrl, setImageUrl] = useState("");
const [selectedFile, setSelectedFile] = useState(null);
const [detectionData, setDetectionData] = useState(null);
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [ocrText, setOcrText] = useState(""); // State for OCR result

// We retrieve the query parameter 'imageName' passed from CapturedImages via


Link
const searchParams = useSearchParams();
const imageNameFromLink = searchParams.get('imageName');

useEffect(() => {
// Just to show we received the image name from Link
if (imageNameFromLink) {
console.log("Received image name from link:", imageNameFromLink);
}
}, [imageNameFromLink]);

const handleFileChange = async (e) => {


const file = e.target.files[0];
if (!file) return;

setSelectedFile(file);
setError("");
setImageUrl("");
setDetectionData(null);
setOcrText(""); // Reset OCR text
setLoading(true);

const formData = new FormData();


formData.append("image", file);

try {
// Upload the image to the backend API
const response = await axios.post(`${base_url}/upload-image`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});

// Set uploaded image URL


const uploadedImageUrl = response.data.data.filepath;
setImageUrl(uploadedImageUrl);

// Automatically trigger the detection API


handleDetectImage(uploadedImageUrl);
} catch (err) {
console.error(err);
setError(
err.response?.data?.message || err.message || "An error occurred"
);
} finally {
setLoading(false);
}
};

const handleDetectImage = async (uploadedImageUrl) => {


setError("");
setDetectionData(null);
setLoading(true);

try {
const response = await axios.post(`${base_url}/detect-image`, {
imageUrl: uploadedImageUrl,
});
setDetectionData(response.data);

// Once we detect the number plate, trigger OCR


const numberPlate = response.data.predictions.find(
(pred) => pred.class === "number plate"
);
if (numberPlate) {
handleOCR(uploadedImageUrl, numberPlate);
}
} catch (err) {
console.error(err);
setError(
err.response?.data?.message || err.message || "An error occurred"
);
} finally {
setLoading(false);
}
};

const handleOCR = async (imageUrl, numberPlate) => {


setError("");
setLoading(true);

try {
// Use the canvas to crop the image
const img = new Image();
img.src = imageUrl;

img.onload = async () => {


// Create a canvas element to crop the number plate region
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");

// Set the canvas size to the dimensions of the bounding box


canvas.width = numberPlate.width;
canvas.height = numberPlate.height;

// Draw the image on the canvas, cropping it to the number plate region
ctx.drawImage(
img,
numberPlate.x - numberPlate.width / 2,
numberPlate.y - numberPlate.height / 2,
numberPlate.width,
numberPlate.height,
0,
0,
numberPlate.width,
numberPlate.height
);

// Convert the cropped canvas to a data URL


const croppedImageUrl = canvas.toDataURL();

// Use Tesseract to extract text from the cropped image


const {
data: { text },
} = await Tesseract.recognize(croppedImageUrl, "eng", {
logger: (m) => console.log(m), // Optional: logging progress
});

setOcrText(text); // Set the OCR text result


};
} catch (err) {
console.error("OCR error:", err);
setError("Failed to extract text");
} finally {
setLoading(false);
}
};

const renderBoundingBoxes = () => {


if (!detectionData || !detectionData.predictions) return null;

const { width, height } = detectionData.image;


const imgRef = document.getElementById("uploaded-image");

const imgWidth = imgRef?.clientWidth || width;


const imgHeight = imgRef?.clientHeight || height;

return detectionData.predictions.map((pred) => {


const scaleX = imgWidth / width;
const scaleY = imgHeight / height;

return (
<div
key={pred.detection_id}
style={{
position: "absolute",
left: (pred.x - pred.width / 2) * scaleX,
top: (pred.y - pred.height / 2) * scaleY,
width: pred.width * scaleX,
height: pred.height * scaleY,
border: "2px solid #FF0000",
boxSizing: "border-box",
borderRadius: "4px",
}}
>
<span
style={{
position: "absolute",
bottom: "0px",
left: "5px",
color: "white",
backgroundColor: "rgba(0, 0, 0, 0.7)",
padding: "2px 5px",
fontSize: "12px",
borderRadius: "3px",
}}
>
{pred.class} ({(pred.confidence * 100).toFixed(2)}%)
</span>
</div>
);
});
};

return (
<div style={styles.container}>
<h1 style={styles.title}>Upload Here</h1>

{/* Show the imageNameFromLink if present */}


{imageNameFromLink && (
<p style={{ color: "blue" }}>
Received image name from link: <strong>{imageNameFromLink}</strong>
</p>
)}

<div style={styles.inputGroup}>
<label htmlFor="file-upload" style={styles.uploadLabel}>
<span style={styles.uploadButton}>📤 Select Image</span>
<input
id="file-upload"
type="file"
accept="image/*"
onChange={handleFileChange}
style={styles.fileInput}
/>
</label>
</div>

{imageUrl && (
<div style={styles.imageContainer}>
<img
id="uploaded-image"
src={imageUrl}
alt="Uploaded"
style={styles.image}
/>
{renderBoundingBoxes()}
</div>
)}

{ocrText && (
<div style={styles.ocrContainer}>
<h3>Extracted Text:</h3>
<p>{ocrText}</p>
</div>
)}

{error && <p style={styles.errorText}>{error}</p>}


</div>
);
};

const styles = {
container: {
padding: "20px",
maxWidth: "800px",
margin: "0 auto",
textAlign: "center",
fontFamily: "Arial, sans-serif",
backgroundColor: "#f9f9f9",
borderRadius: "8px",
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
},
title: {
marginBottom: "20px",
color: "#333",
},
inputGroup: {
display: "flex",
justifyContent: "center",
marginBottom: "20px",
},
uploadLabel: {
position: "relative",
display: "inline-block",
cursor: "pointer",
},
uploadButton: {
padding: "10px 20px",
backgroundColor: "#00c46a",
color: "#fff",
borderRadius: "4px",
fontSize: "16px",
transition: "background-color 0.3s",
},
fileInput: {
position: "absolute",
top: 0,
left: 0,
opacity: 0,
width: "100%",
height: "100%",
cursor: "pointer",
},
imageContainer: {
position: "relative",
display: "inline-block",
maxWidth: "100%",
borderRadius: "8px",
overflow: "hidden",
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
},
image: {
maxWidth: "100%",
height: "auto",
display: "block",
},
ocrContainer: {
marginTop: "20px",
padding: "10px",
backgroundColor: "#f1f1f1",
borderRadius: "6px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
},
errorText: {
color: "#FF0000",
marginTop: "10px",
},
};

export default Page;

You might also like