검색 업로드

This commit is contained in:
익희 김 2025-01-23 03:42:08 +09:00
parent 6c9d0690aa
commit 110d0d3b1b

View File

@ -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>
</>
);
}