121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import React, { useRef, useEffect } from "react";
|
|
import "./Search.css"; // Import CSS for styling
|
|
import { Button } from "../ui/button";
|
|
import { toast } from "@/hooks/use-toast";
|
|
|
|
const Search: React.FC = () => {
|
|
const videoRef = useRef<HTMLVideoElement>(null);
|
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
useEffect(() => {
|
|
const openCamera = async () => {
|
|
try {
|
|
const stream = await navigator.mediaDevices.getUserMedia({
|
|
video: true,
|
|
});
|
|
if (videoRef.current) {
|
|
videoRef.current.srcObject = stream;
|
|
}
|
|
} catch (err) {
|
|
console.error("Error accessing the camera", err);
|
|
}
|
|
};
|
|
|
|
openCamera();
|
|
}, []);
|
|
|
|
// Capturing image from video stream
|
|
const captureImage = () => {
|
|
const video = videoRef.current;
|
|
const canvas = canvasRef.current;
|
|
|
|
if (video && canvas) {
|
|
const context = canvas.getContext("2d");
|
|
if (context) {
|
|
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
canvas.toBlob((blob) => {
|
|
if (blob) {
|
|
const file = new File([blob], "captured-image.png", {
|
|
type: "image/png",
|
|
});
|
|
callApi(file);
|
|
}
|
|
}, "image/png");
|
|
}
|
|
}
|
|
};
|
|
// Handling image upload
|
|
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
const file = event.target.files?.[0];
|
|
if (file) {
|
|
callApi(file); // Calling the API with the uploaded file
|
|
}
|
|
};
|
|
|
|
// Calling API with the provided image file
|
|
const callApi = async (file: File) => {
|
|
const formData = new FormData();
|
|
formData.append("image", file); // Appending the file to the form data
|
|
|
|
try {
|
|
const startTime = performance.now();
|
|
const response = await fetch(
|
|
`${process.env.NEXT_PUBLIC_BASE_URL}/search`,
|
|
{
|
|
method: "POST",
|
|
body: formData, // Sending the form data
|
|
}
|
|
);
|
|
// Ending measuring time
|
|
const endTime = performance.now();
|
|
const totalTime = (endTime - startTime) / 1000;
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
console.log("API call successful", data);
|
|
toast({
|
|
title: data.message,
|
|
description: `Name: ${data?.name}\n\nTime taken: ${totalTime.toFixed(
|
|
2
|
|
)} seconds`,
|
|
});
|
|
} else {
|
|
console.error("API call failed");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error calling API", error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="search-container">
|
|
<h2>Search</h2>
|
|
<div className="video-container">
|
|
<video ref={videoRef} autoPlay playsInline className="video" />
|
|
</div>
|
|
<Button type="button" onClick={captureImage} className="capture-button">
|
|
Capture Image
|
|
</Button>
|
|
<div>Or</div>
|
|
<div className="upload-container">
|
|
<label htmlFor="upload" className="upload-label">
|
|
Upload Image
|
|
</label>
|
|
<input
|
|
type="file"
|
|
id="upload"
|
|
accept="image/*"
|
|
onChange={handleFileChange}
|
|
className="upload-input"
|
|
/>
|
|
</div>
|
|
<canvas
|
|
ref={canvasRef}
|
|
style={{ display: "none" }}
|
|
width="640"
|
|
height="480"
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Search;
|