Face_Classify_frontend/app/src/components/SearchImg/SearchImage.js
2022-01-14 22:02:12 +07:00

537 lines
23 KiB
JavaScript

import { Card, Image as ImageAntd } from 'antd';
import Parser from 'html-react-parser';
import $ from 'jquery';
import React, { Component } from 'react';
import "react-datepicker/dist/react-datepicker.css";
import ReactFileReader from 'react-file-reader';
import Pagination from "react-js-pagination";
import { PulseLoader } from 'react-spinners';
import swal from 'sweetalert';
import { HOST } from '../../config/index';
import Store from '../../store';
class SearchImage extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
listHistory: [],
crrHistory: [],
dataVerification: null,
filesImagePerson: "",
page_num: 1,
page_size: 10,
total_count: 0,
valueRes: 100,
threshold: 50,
similarity: 70,
value: 0,
selectedEncoding: [],
boxs: [],
slides: [],
encodings: [],
plugins: [],
nimages: [],
showModal: false,
crrdatainfo: null,
offset: 0,
showFirst: 0,
showLast: 0,
totalLength: 0,
dataRole: Store.getState().role.role,
isLogin: Store.getState().isLogin.isLogin,
};
Store.subscribe(() => {
this.setState({
isLogin: Store.getState().isLogin.isLogin,
dataRole: Store.getState().role.role,
}, () => {
});
});
this.onchange = this.onchange.bind(this);
this.closeModal = this.closeModal.bind(this);
var itemsPerPage = 6;
if ($(window).width() >= 1400 && $(window).width() < 1750) {
itemsPerPage = 6
} else if ($(window).width() <= 1280 ) {
itemsPerPage = 6
} else {
itemsPerPage = 8
}
this.itemsPerPage = itemsPerPage;
}
componentDidMount() {
window.$('.carousel').carousel({
interval: false,
wrap: false
}).on('slid.bs.carousel', function () {
var curSlide = window.$('.active');
if (curSlide.is(':first-child')) {
window.$('.carousel-control-prev').hide();
window.$('.carousel-control-next').show();
} else if (curSlide.is(':last-child')) {
window.$('.carousel-control-prev').show();
window.$('.carousel-control-next').hide();
} else {
window.$('.carousel-control-prev').show();
window.$('.carousel-control-next').show();
}
});
}
onchange(value) {
this.setState({ value });
}
closeModal() {
this.setState({
showModal: false,
})
}
handlePrevChange() {
var index = this.state.value;
index = index - 1
if (index >= 0)
this.setState({
value: index,
selectedEncoding: this.state.encodings[index],
})
}
handleNextChange() {
var index = this.state.value;
if (index < (this.state.encodings.length - 1))
index = index + 1
this.setState({
value: index,
selectedEncoding: this.state.encodings[index],
})
}
changeFace(index) {
this.setState({
value: index,
selectedEncoding: this.state.encodings[index],
}, () => {
this.getPerson()
})
}
getPerson() {
if (!this.state.valueRes || !this.state.threshold) {
return swal('Cảnh báo!', 'Vui lòng điền đầy đủ các trường', 'warning');
}
this.setState({
loading: true,
});
fetch(`${HOST}/api/search_people`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJjbGFzc2lmeS9sb2dpbiJdLCJleHAiOjE2NDE5NzQ5NjV9.2F2PAUKjpfjPJKzgvzgCDtyBuTXDRl86EnJJGdYgWTM'
},
body: JSON.stringify({
encodings: this.state.selectedEncoding,
image: "",
threshold: parseInt(this.state.threshold) / 100,
result_number: this.state.valueRes,
})
}).then((response) => {
return response.json()
}).then((rs) => {
if (rs.status === 10000) {
var data = rs.data;
this.setState({
listHistory: data,
loading: false,
// total_count: rs.count,
});
this.FilterSearch(this.state.page_num)
} else if (rs.status === 10003) {
if (rs.message === 'No face in image') {
swal("Lỗi", "Ảnh không có khuôn mặt!", "error");
} else if (rs.message === 'Too many face') {
swal("Lỗi", "Ảnh có quá nhiều khuôn mặt!", "error");
} else {
swal("Lỗi", "Ảnh không đạt yêu cầu!", "error");
}
this.setState({
listHistory: [],
loading: false,
});
} else if (rs.status === 10002) {
swal("Lỗi", "Lỗi hệ thống!", "error");
this.setState({
listHistory: [],
loading: false,
});
} else {
swal("Lỗi!", "Ảnh không hợp lệ!", "error");
this.setState({
listHistory: [],
loading: false,
});
}
}).catch((error) => {
if (error) {
console.log(error)
swal("Lỗi!", "Ảnh không hợp lệ!", "error");
this.setState({
listHistory: [],
loading: false,
total_count: 0,
});
}
})
}
getFaces() {
var image_base64;
image_base64 = this.state.filesImagePerson.replace('data:image/png;base64,', '');
image_base64 = image_base64.replace('data:image/jpg;base64,', '');
image_base64 = image_base64.replace('data:image/jpeg;base64,', '');
fetch(`${HOST}/api/face_images/faces`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
image: image_base64
})
}).then((response) => {
return response.json()
}).then((rs) => {
if (rs.status === 10000) {
var boxs = []
var item = ""
var encodings = []
rs.imgs.map((value, index) => {
var item_active = "<div class='carousel-item active pt-3'>"
+ "<img style='margin-left: 5px;width: 75px; opacity: 1;cursor: pointer;' src=" + `data:image/png;base64,` + " dangerouslySetInnerHTML={{__html:this.state.userText}} onClick={this.toggleTranspose()} />"
+ "</div>"
// var item_inactive = "<div class='carousel-item'>"
// + "<img src="+`data:image/png;base64,${value} `+ "style={{ marginLeft: '5px', width: '75px', opacity: 1, cursor: 'pointer' }} alt='...' />"
// + "</div>"
if (index === 0) {
item += "<div class='carousel-item active pt-3'>"
item += "<img style='margin-left: 5px;width: 75px; opacity: 1;cursor: pointer;' alt='...' src=" + `data:image/png;base64,${value} ` + " />"
}
else if (index % 2 === 0) {
item += "<div class='carousel-item pt-3'>"
}
if (index !== 0 && (index % 2 === 0)) {
item += "<img style='margin-left: 5px;width: 75px; opacity: 1;cursor: pointer;' src=" + `data:image/png;base64,${value} ` + " />"
}
else if (index !== 0) {
item += "<img style='margin-left: 5px;width: 75px; opacity: 1;cursor: pointer;' src=" + `data:image/png;base64,${value} ` + " />"
item += "</div>"
}
item = item_active
boxs.push(rs.boxes[index])
encodings.push(rs.encodings[index])
});
this.setState({
encodings: encodings,
slides: Parser(item),
boxs: boxs,
value: 0,
selectedEncoding: encodings[0],
listHistory: [],
nimages: rs.imgs,
total_count: 0,
page_num: 1,
numbershow: (rs.imgs.length > 3 ? 3 : rs.imgs.length),
}, () => {
if (this.state.encodings.length === 1) {
window.$('.carousel-control-prev').hide();
window.$('.carousel-control-next').hide();
}
else {
window.$('.carousel-control-prev').show();
window.$('.carousel-control-next').show();
}
if (this.state.encodings.length >= 1)
this.changeFace(0)
})
}
else {
swal("Lỗi!", "Ảnh không hợp lệ!", "error");
this.setState({
listHistory: [],
loading: false,
total_count: 0,
});
}
}).catch((error) => {
if (error) {
console.log(error)
swal("Lỗi!", "Ảnh không hợp lệ!", "error");
this.setState({
listHistory: [],
loading: false,
total_count: 0,
});
}
})
}
onFilesChangeImagePerson = async (files) => {
document.getElementById('previewImagePerson').src = files.base64;
this.setState({
filesImagePerson: files.base64,
crrHistory: [],
nimages: [],
loading: false,
totalLength: 0,
plugins: []
});
this.getFaces();
}
isChangeRes = (event) => {
this.setState({
valueRes: event.target.value,
})
}
isChangeThreshold = (event) => {
let val = event.target.value
let maxLength = 3
let newValue = val < maxLength ? val : parseInt(val.toString().substring(0, maxLength));
this.setState({
threshold: newValue,
})
}
FilterSearch = (activePage) => {
const offset = (activePage - 1) * this.itemsPerPage;
const crrHistory = this.state.listHistory.slice(offset, offset + this.itemsPerPage);
this.setState({
crrHistory,
offset,
showFirst: offset + 1,
showLast: crrHistory.length + offset,
totalLength: this.state.listHistory.length
});
}
handlePageChange = (pageNumber) => {
this.setState({
...this.state,
page_num: pageNumber,
}, () => {
this.FilterSearch(pageNumber);
})
}
render() {
let rsImages = this.state.nimages.map((value, index) => {
var item_active = ""
if (index === 0) {
item_active =
(
<div key={value} class={"carousel-item active pt-3"}>
<img alt="" src={`data:image/png;base64,${value} `} style={{ marginLeft: '5px', width: '75px', opacity: 1, cursor: 'pointer' }} onClick={() => this.changeFace(index)} class={"img-responsive"} />
</div>
)
}
else if (index > 0) {
item_active =
(
<div key={value} class={"carousel-item pt-3"}>
<img alt="" src={`data:image/png;base64,${value} `} style={{ marginLeft: '5px', width: '75px', opacity: 1, cursor: 'pointer' }} onClick={() => this.changeFace(index)} class={"img-responsive"} />
</div>
)
}
return item_active
});
let bulletedImg = this.state.crrHistory.map((value, index) => {
let layoutImg = "col-md-4"
if ($(window).width() >= 1400 && $(window).width() < 1750) {
layoutImg = "col-md-4"
} else if ($(window).width() <= 1280 ) {
layoutImg = "col-md-4"
} else {
layoutImg = "col-md-3"
}
return (
<div className={`${layoutImg} mb-4`}>
<Card
style={{ width: 300 }}
cover={<ImageAntd
style={{ objectFit: 'contain', height: '180px'}}
// width={200}
src={value.image_url}
/>}
>
<p style={{wordWrap: "break-word", marginBottom: "0px"}}><strong>facebookID: </strong>{value.person_id}</p>
<p style={{wordWrap: "break-word"}}><strong>ImageID: </strong>{value.image_id}</p>
</Card>
</div>
)
});
return (
<div className="m-portlet m-portlet--mobile pb-3">
<div className="m-portlet__head">
<div className="m-portlet__head-caption">
<div className="m-portlet__head-title">
<h3 className="m-portlet__head-text">
Tìm kiếm ảnh
</h3>
</div>
</div>
</div>
<div className="m-portlet__body pt-2">
<div className="m-grid__item m-grid__item--fluid m-wrapper" style={{ backgroundColor: 'white' }}>
<div className="m-content mt-3-phone pd_phone_0 p-3">
<div className="m-form m-form--fit m-form--label-align-right">
<div className="row m-0">
<div className="col-md-2 px-0">
<img src="./img/photo-placeholder.png" id="previewImagePerson" className="text-center" style={{width: '100%', height: 'auto'}} alt="" />
<div className="text-center p-8">
<ReactFileReader fileTypes={['image/png', 'image/jpg', 'image/jpeg']} base64={true} multipleFiles={false} handleFiles={this.onFilesChangeImagePerson} >
<button style={{ marginTop: '10px' }} className={'btn m-btn--icon m-btn btn-default m-loader--success m-loader--right'}>
<span >
<i className="la la-cloud-upload"></i>
<span>Chọn ảnh</span>
</span>
</button>
</ReactFileReader>
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner" data-interval="false">
{rsImages}
</div>
<a className={`carousel-control-prev ${rsImages.length <= 1 ? "d-none" : ""}`} href="#carouselExampleControls" role="button" data-slide="prev" onClick={() => this.handlePrevChange()}>
<span class="carousel-control-prev-icon fa fa-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a className={`carousel-control-next ${rsImages.length <= 1 ? "d-none" : ""}`} href="#carouselExampleControls" role="button" data-slide="next" onClick={() => this.handleNextChange()}>
<span class="carousel-control-next-icon fa fa-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<div style={{ marginTop: '10px', textAlign: 'left' }}>
<table>
<tbody>
<tr>
<td>
<span>Số kết quả: </span>
</td>
<td>
<input className="form-control form-control-sm" type="number" step="1" min="1" name="m_table_1_length" value={this.state.valueRes} onChange={(event) => this.isChangeRes(event)} aria-controls="m_table_1" />
</td>
</tr>
<tr>
<td>
<span>Tỷ lệ giống:</span>
</td>
<td>
<label className="percent-simular" data-input="%">
<input className="input-percent form-control form-control-sm" type="number" min="1" max="100" step="1" name="m_table_1_length" value={this.state.threshold} onChange={(event) => this.isChangeThreshold(event)} aria-controls="m_table_1" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
<div style={{ marginTop: '10px' }} className="ml-2 mb-mobile-10">
<button
onClick={() => {
this.setState({
page_num: 1,
listHistory: []
}, () => {
this.getPerson();
})
}}
className="btn btn-accent m-btn m-btn--icon">
<span>
<i className="la la-search" />
<span>Tìm kiếm</span>
</span>
</button>
</div>
</div>
</div>
<div className="col-md-10">
<div className="pl-2 row d-flex justify-content-between">
<div>
<Pagination
prevPageText='Trang trước'
nextPageText='Trang sau'
firstPageText='Trang đầu'
lastPageText='Trang cuối'
activePage={this.state.page_num}
itemsCountPerPage={this.itemsPerPage}
totalItemsCount={this.state.totalLength}
pageRangeDisplayed={5}
onChange={this.handlePageChange}
/>
</div>
<div className="pull-right">
<div>Tổng kết quả <b>{this.state.totalLength}</b></div>
</div>
</div>
<div className='row-sm row pl-3 pr-3 pb-3'>
{bulletedImg}
<PulseLoader
// css={override}
sizeUnit={"px"}
size={12}
margin={'2px'}
color={'#36D7B7'}
loading={this.state.loading}
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default SearchImage;