업로드!
This commit is contained in:
parent
4d92cc2b61
commit
2bf1c54e7a
@ -10,12 +10,13 @@ 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, IconButton } from '@mui/material';
|
||||
import MenuList from '@mui/material/MenuList';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
|
||||
|
||||
// components
|
||||
import NoDataFound from 'src/illustrations/dataNotFound';
|
||||
@ -28,6 +29,65 @@ import { useCurrencyFormatter } from 'src/hooks/formatCurrency';
|
||||
// api
|
||||
import * as api from 'src/services';
|
||||
|
||||
const axios = require('axios');
|
||||
|
||||
const getImageUrl = async (ids) => {
|
||||
const requestOptions = {
|
||||
method: 'GET',
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
try {
|
||||
const responses = await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
const response = await fetch(
|
||||
`https://api.roboflow.com/picup/picup/images/${id}?api_key=s9OJq0UPljSqkPsJY6xP`,
|
||||
requestOptions
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error fetching image for ID: ${id}, Status: ${response.status}`);
|
||||
}
|
||||
return response.json(); // JSON 응답 반환
|
||||
})
|
||||
);
|
||||
|
||||
return responses; // 모든 이미지 정보를 배열로 반환
|
||||
} catch (error) {
|
||||
console.error('Error fetching image URLs:', error);
|
||||
return null; // 오류 발생 시 null 반환
|
||||
}
|
||||
};
|
||||
|
||||
const searchImages = async (imageBase64) => {
|
||||
const myHeaders = new Headers();
|
||||
myHeaders.append('Content-Type', 'application/json');
|
||||
|
||||
const raw = JSON.stringify({
|
||||
like_image: 'MV09CPgMSn9uhQ5D2nl5',
|
||||
limit: 3,
|
||||
in_dataset: true
|
||||
});
|
||||
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: myHeaders,
|
||||
body: raw,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://api.roboflow.com/picup/picup/search?api_key=s9OJq0UPljSqkPsJY6xP',
|
||||
requestOptions
|
||||
);
|
||||
const result = await response.json();
|
||||
return result; // 반환 추가
|
||||
} catch (error) {
|
||||
console.error('Error fetching images:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
Search.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
mobile: PropTypes.bool.isRequired
|
||||
@ -56,6 +116,9 @@ export default function Search({ ...props }) {
|
||||
|
||||
const router = useRouter();
|
||||
const [search, setSearch] = React.useState('');
|
||||
const [image, setImage] = React.useState(null);
|
||||
const [imagesResultID, setImagesResultID] = React.useState(null);
|
||||
const [roboFlowUrlLists, setRoboFlowUrlLists] = React.useState([]);
|
||||
|
||||
const { data: filters, isLoading: filtersLoading } = useQuery(['get-search-filters'], () => api.getSearchFilters());
|
||||
const { mutate, isLoading } = useMutation('search', api.search, {
|
||||
@ -108,21 +171,48 @@ export default function Search({ ...props }) {
|
||||
}
|
||||
};
|
||||
|
||||
// 파일 선택 시 호출되는 함수
|
||||
const handleFileChange = (event) => {
|
||||
const handleFileChange = async (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.onloadend = async () => {
|
||||
const base64Image = reader.result.split(',')[1]; // base64 변환 후 접두사 제거
|
||||
setImage(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const objectDetect = async (image) => {
|
||||
try {
|
||||
const result = await searchImages(image);
|
||||
|
||||
// id 배열 추출
|
||||
const imageIds = result.results.map((r) => r.id);
|
||||
|
||||
// 배열을 한 번에 저장
|
||||
setImagesResultID(imageIds);
|
||||
|
||||
console.log('Image IDs:', imageIds); // 디버깅 출력
|
||||
} catch (error) {
|
||||
console.error('Error in image search:', error);
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (imagesResultID && imagesResultID.length > 0) {
|
||||
getImageUrl(imagesResultID).then((url) => {
|
||||
setRoboFlowUrlLists(url);
|
||||
});
|
||||
}
|
||||
}, [imagesResultID]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (roboFlowUrlLists) {
|
||||
console.log(roboFlowUrlLists);
|
||||
}
|
||||
}, [roboFlowUrlLists]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
@ -167,7 +257,9 @@ export default function Search({ ...props }) {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button variant='contained' sx={{ width: '100%', borderRadius: 0 }} onClick={handleImageSearch}>이미지 검색</Button>
|
||||
<Button variant="contained" sx={{ width: '100%', borderRadius: 0 }} onClick={handleImageSearch}>
|
||||
이미지 검색
|
||||
</Button>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
@ -332,13 +424,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>
|
||||
@ -347,6 +439,63 @@ export default function Search({ ...props }) {
|
||||
</>
|
||||
)}
|
||||
</Box>{' '}
|
||||
{roboFlowUrlLists &&
|
||||
roboFlowUrlLists.map((i, index) => (
|
||||
<MenuList
|
||||
key={`search-by-images-${i.image.annotation.key}-${index.toString()}`}
|
||||
sx={{
|
||||
pt: 0,
|
||||
mt: 1,
|
||||
overflow: 'auto',
|
||||
px: 1,
|
||||
li: {
|
||||
borderRadius: '8px',
|
||||
border: `1px solid transparent`,
|
||||
'&:hover, &.Mui-focusVisible, &.Mui-selected ': {
|
||||
border: (theme) => `1px solid ${theme.palette.primary.main}`,
|
||||
bgcolor: (theme) => alpha(theme.palette.primary.main, 0.16),
|
||||
h6: {
|
||||
color: 'primary.main'
|
||||
}
|
||||
},
|
||||
'&.active': {
|
||||
border: (theme) => `1px solid ${theme.palette.primary.main}`,
|
||||
bgcolor: (theme) => alpha(theme.palette.primary.main, 0.16),
|
||||
h6: {
|
||||
color: 'primary.main'
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
autoFocusItem={!focus}
|
||||
>
|
||||
<MenuItem>
|
||||
<ListItemIcon>
|
||||
<img
|
||||
alt="이미지"
|
||||
src={i.image.urls.original}
|
||||
style={{ width: '40px', height: '40px', borderRadius: '100%' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
<Stack direction="row" gap={1} alignItems={'center'} justifyContent={'space-between'}>
|
||||
<div>
|
||||
<Typography variant="subtitle1" color="text.primary" noWrap>
|
||||
Object Data Set {index}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" noWrap>
|
||||
{i.image.tags.map((i) => {
|
||||
return i;
|
||||
})}
|
||||
{` `}
|
||||
<span>{i.image.r * 100}%</span>
|
||||
</Typography>
|
||||
</div>
|
||||
</Stack>
|
||||
</ListItemText>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
))}
|
||||
{multiSelect && (
|
||||
<Stack gap={1} direction={'row'} p={1} justifyContent={'end'}>
|
||||
<Button variant="outlined" color="primary" onClick={() => handleSave(selectedProducts)}>
|
||||
@ -358,6 +507,42 @@ export default function Search({ ...props }) {
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
{/* 이미지 미리보기 렌더링 */}
|
||||
{image && (
|
||||
<Modal
|
||||
open={image}
|
||||
sx={{ height: '100vh', width: '100vw', display: 'flex', justifyContent: 'center', alignItems: 'center' }}
|
||||
>
|
||||
<Box sx={{ position: 'relative' }}>
|
||||
<Box mt={2} display="flex" justifyContent="center">
|
||||
<IconButton
|
||||
sx={{ position: 'absolute;', right: 0, top: 10, mixBlendMode: 'difference' }}
|
||||
onClick={() => {
|
||||
setImage(null);
|
||||
}}
|
||||
>
|
||||
<CloseRoundedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
<img
|
||||
src={image}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
maxHeight: '300px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #ddd'
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
sx={{ position: 'absolute', bottom: 0, left: '50%', transform: 'translate(-50%, 0px)' }}
|
||||
onClick={() => objectDetect(image)}
|
||||
>
|
||||
이미지 상품 검색
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import { varFadeInRight } from '../animate';
|
||||
// react dropzone
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
|
||||
|
||||
|
||||
const DropZoneStyle = styled('div')(({ theme }) => ({
|
||||
outline: 'none',
|
||||
display: 'flex',
|
||||
|
Loading…
Reference in New Issue
Block a user