From 110d0d3b1b8b7f1b14409062f1be38165361b7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B5=ED=9D=AC=20=EA=B9=80?= Date: Thu, 23 Jan 2025 03:42:08 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=80=EC=83=89=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dialog/search/search.jsx | 190 ++++++++++++++++-------- 1 file changed, 127 insertions(+), 63 deletions(-) diff --git a/src/components/dialog/search/search.jsx b/src/components/dialog/search/search.jsx index ee4bf48..e27a6d6 100644 --- a/src/components/dialog/search/search.jsx +++ b/src/components/dialog/search/search.jsx @@ -10,7 +10,7 @@ import Typography from '@mui/material/Typography'; import SearchIcon from '@mui/icons-material/Search'; import TextField from '@mui/material/TextField'; import Skeleton from '@mui/material/Skeleton'; -import { InputAdornment, Stack, Button } from '@mui/material'; +import { InputAdornment, Stack, Button, Modal } from '@mui/material'; import MenuList from '@mui/material/MenuList'; import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; @@ -25,8 +25,8 @@ import FormControl from '@mui/material/FormControl'; import Select from '@mui/material/Select'; import { useCurrencyConvert } from 'src/hooks/convertCurrency'; import { useCurrencyFormatter } from 'src/hooks/formatCurrency'; -const axios = require("axios"); -const fs = require("fs"); +const axios = require('axios'); +const fs = require('fs'); const FormData = require('form-data'); // api import * as api from 'src/services'; @@ -59,6 +59,10 @@ export default function Search({ ...props }) { const router = useRouter(); const [search, setSearch] = React.useState(''); + const [image, setImage] = React.useState(null); + const [predictions, setPredictions] = React.useState([]); + const [showModal, setShowModal] = React.useState(false); + const canvasRef = React.useRef(null); const { data: filters, isLoading: filtersLoading } = useQuery(['get-search-filters'], () => api.getSearchFilters()); const { mutate, isLoading } = useMutation('search', api.search, { @@ -69,6 +73,18 @@ export default function Search({ ...props }) { const [focus, setFocus] = React.useState(true); + // 파일 선택 핸들러 + const handleFileChange = (event) => { + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = () => { + setImage(reader.result); // 이미지 상태 업데이트 + }; + reader.readAsDataURL(file); + } + }; + const handleListItemClick = (prop) => { if (multiSelect) { const matched = state.selected.filter((v) => prop._id === v._id); @@ -104,66 +120,82 @@ export default function Search({ ...props }) { const fileInputRef = React.useRef(null); - // 이미지를 찾는 함수 - const handleImageSearch = () => { - if (fileInputRef.current) { - fileInputRef.current.click(); // 숨겨진 파일 입력을 트리거 - } + const detectWithRoboflow = async () => { + if (!image) return; + + const canvas = canvasRef.current; + const ctx = canvas?.getContext('2d'); + + const img = new Image(); + img.src = image; + + img.onload = async () => { + // 캔버스 크기 설정 + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage(img, 0, 0); + + // 이미지를 Blob으로 변환 + const response = await fetch(image); + const blob = await response.blob(); + + // API 호출 + + const formData = new FormData(); + formData.append('file', blob); + + const apiEndpoint = `https://detect.roboflow.com/picup/1?api_key=s9OJq0UPljSqkPsJY6xP`; + + try { + const apiResponse = await fetch(apiEndpoint, { + method: 'POST', + body: formData + }); + + const result = await apiResponse.json(); + console.log('Predictions:', result); + + if (result.predictions) { + setShowModal(true); + setPredictions(result.predictions); + + // 바운딩 박스와 라벨 표시 + result.predictions.forEach((prediction) => { + const { x, y, width, height, class: label, confidence } = prediction; + + // 바운딩 박스 + ctx.strokeStyle = 'red'; + ctx.lineWidth = 1; + ctx.strokeRect(x - 50, y - 80, width, height); + + // 라벨 + ctx.fillStyle = 'red'; + ctx.font = '16px Arial'; + ctx.fillText(`${label} (${(confidence * 100).toFixed(2)}%)`, x - 50, y - 80 > 10 ? y - 5 : 10); + }); + setTimeout(() => { + setShowModal(false); + }, 1000); + setTimeout(() => { + setSearch(result.predictions[0].class); + }, 500); + setTimeout(() => { + onKeyDown + }, 500); + } + } catch (error) { + console.error('Error detecting objects:', error); + } + }; }; - // 파일 선택 시 호출되는 함수 - // const handleFileChange = (event) => { - // const file = event.target.files?.[0]; - // if (file) { - // console.log('Selected File:', file); - - // // 예: 파일을 서버에 업로드하거나 처리 - // const reader = new FileReader(); - // reader.onload = () => { - // console.log('Image Preview URL:', reader.result); - // }; - // reader.readAsDataURL(file); + // const handleSubmit = (event) => { + // event.preventDefault(); + // if (fileInputRef.current && fileInputRef.current.files.length > 0) { + // handleFileChange({ target: { files: fileInputRef.current.files } }); // } // }; - const handleFileChange = async (event) => { - const file = event.target.files[0]; - if (file) { - const formData = new FormData(); - formData.append('name', file.name); - formData.append('file', file); - formData.append('split', 'train'); - - console.log(formData) - - axios({ - method: 'POST', - url: 'https://api.roboflow.com/dataset/picup/upload', - params: { - api_key: 's9OJq0UPljSqkPsJY6xP' - }, - data: formData, - headers: { - "Content-Type": "multipart/form-data" - } - }) - .then(function (response) { - console.log(response.data); - }) - .catch(function (error) { - console.log(error.message); - }); - } - }; - - const handleSubmit = (event) => { - event.preventDefault(); - if (fileInputRef.current && fileInputRef.current.files.length > 0) { - handleFileChange({ target: { files: fileInputRef.current.files } }); - } - }; - - return ( <> -
-