검색 업로드
This commit is contained in:
parent
6c9d0690aa
commit
110d0d3b1b
@ -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 (
|
||||
<>
|
||||
<TextField
|
||||
@ -208,17 +240,28 @@ export default function Search({ ...props }) {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<form style={{ display: 'flex' }} onSubmit={handleSubmit}>
|
||||
<Button variant="contained" sx={{ width: '80%', borderRadius: 0 }} onClick={handleImageSearch}>
|
||||
<form
|
||||
style={{ display: 'flex' }}
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault();
|
||||
detectWithRoboflow();
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ width: '80%', borderRadius: 0 }}
|
||||
onClick={() => document.getElementById('fileInput').click()}
|
||||
>
|
||||
이미지 찾기
|
||||
</Button>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
capture="camera"
|
||||
id="fileInput"
|
||||
ref={fileInputRef}
|
||||
onChange={handleFileChange}
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
<button type="submit" style={{ width: '20%', height: '40px', border: '0' }}>
|
||||
검색
|
||||
@ -380,13 +423,13 @@ export default function Search({ ...props }) {
|
||||
{isLoading ? <Skeleton variant="text" width="200px" /> : product.category}
|
||||
</Typography>
|
||||
</div>
|
||||
<Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
{/* <Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
{isLoading ? (
|
||||
<Skeleton variant="text" width="100px" />
|
||||
) : (
|
||||
fCurrency(cCurrency(product.priceSale))
|
||||
)}
|
||||
</Typography>
|
||||
</Typography> */}
|
||||
</Stack>
|
||||
</ListItemText>
|
||||
</MenuItem>
|
||||
@ -406,6 +449,27 @@ export default function Search({ ...props }) {
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
className={showModal === true ? 'active' : ''}
|
||||
sx={{
|
||||
height: '100vh',
|
||||
width: '100vw',
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
top: '-100vh',
|
||||
backgroundColor: '#00000055',
|
||||
zIndex: 1300,
|
||||
transition: 'ease all 0.3s',
|
||||
'&.active': {
|
||||
top: 0,
|
||||
transition: 'ease all 0.3s'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Stack sx={{ height: '100vh', width: '100vw', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<canvas ref={canvasRef} style={{ width: '90vw' }}></canvas>
|
||||
</Stack>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user