import React, { Component } from 'react' import { Card, Button, Form, Container, Spinner, Row, Toast } from 'react-bootstrap' import axios from 'axios'; import { faCloudDownloadAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export default class UploadForm extends Component { state = { image: null, returnedImage: null, loading: false, inferenceTime: null, instances: null, errorMessage: null } onImageChange = (event) => { this.setState({ image: event.target.files[0] }) if (!event.target.files[0].name.match(/.(jpg|jpeg|png)$/i)){ this.setState({ image: null}) alert('Not an image. jpg, jpeg, png are allowed'); } // console.log(this.state) } onImageUpload = () => { const formData = new FormData(); // Update the formData object formData.append( "file", this.state.image, this.state.image.name ); this.setState({ loading: true }) this.setState({ returnedImage: null }) // console.log(this.state.image); axios({ method: 'post', url: 'http://localhost:5000/api/analyse-image-json', data: formData, headers: { 'Content-Type': 'multipart/form-data' }, responseType: 'json' }) .then((response) => { const data = response.data // console.log(response); this.setState({ loading: false }) this.setState({ inferenceTime: data['inference_time'] }) this.setState({ instances: data['instances'] }) // base64 json image to blob for display const byteCharacters = atob(data['img']); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); let image = new Blob([byteArray], { type: 'image/jpeg' }); this.setState({ returnedImage: URL.createObjectURL(image) }) }) .catch((err) => { //handle error this.setState({ loading: false }) console.log(err); this.setState({ errorMessage: err.message }) // this.displayErrorMessage(err.message) }); } displayErrorMessage = () => { return ( <div className='pt-4' aria-live="polite" aria-atomic="true" style={{ position: 'relative', minHeight: '100px', }}> <Toast style={{ position: 'absolute', top: 0, right: 0, }} delay={3000} autohide> <Toast.Header className="text-white bg-danger"> {/* <img src="holder.js/20x20?text=%20" className="rounded mr-2" alt="" /> */} {/* <strong className="mr-auto text-left"><FontAwesomeIcon icon={faTimesCircle} size="lg" /> </strong> */} <small>{this.state.errorMessage}</small> </Toast.Header> <Toast.Body>{this.state.errorMessage}</Toast.Body> </Toast> </div> ) } imgDetails = () => { if (this.state.image) { return ( <Card.Subtitle className="mb-2 text-muted"> <ul> {/* <li>File Name: {this.state.image.name}</li> */} <li>File Type: {this.state.image.type}</li> <li>File size: {(this.state.image.size / 1000000).toFixed(1)} MB</li> <li>Inference time: {this.state.inferenceTime}</li> <li>Instances: {this.state.instances}</li> </ul> </Card.Subtitle> ) } } downloadImage = () => { // create temporary link to download image const url = this.state.returnedImage const link = document.createElement('a'); link.href = url; link.setAttribute('download', this.state.image.name); document.body.appendChild(link); link.click(); } loading = () => { if (this.state.loading) { return ( <Container className='pt-4'> <Row className="justify-content-md-center"> <Spinner animation="grow" variant="primary" /> <Spinner animation="grow" variant="secondary" /> <Spinner animation="grow" variant="success" /> <Spinner animation="grow" variant="danger" /> <Spinner animation="grow" variant="warning" /> <Spinner animation="grow" variant="info" /> <Spinner animation="grow" variant="dark" /> </Row> </Container> ) } if (this.state.errorMessage) { return ( this.displayErrorMessage(this.state.errorMessage) ) } } render() { const imgDisplay = ( <div className='pt-4 shadow-lg'> <Card border="warning" bg="light"> <Card.Header className="logo text-center bg-light"> <h5>Analysed image</h5> <Button variant="Warning" size="lg" type="button" onClick={this.downloadImage}> <FontAwesomeIcon icon={faCloudDownloadAlt} size="lg" /> </Button> </Card.Header> <Card.Body> <img alt="asdfasdfs" src={this.state.returnedImage} style={{ maxWidth: '98%' }} /> </Card.Body> </Card> </div> ) return ( <div> <div> <Card border="info" bg="light" className='shadow-lg'> <Card.Header className="logo text-center text-white bg-info"><h5>Upload image</h5></Card.Header> <Card.Body> <Form onSubmit={this.onSubmit}> <Form.Group controlId="name"> <Form.Label className="logo">Image</Form.Label> <Form.Control name="image" type="file" onChange={this.onImageChange} /> </Form.Group> <Button variant="info" type="button" onClick={this.onImageUpload} >Upload</Button> </Form> </Card.Body> {this.state.image ? this.imgDetails() : null} </Card> </div> <div> {this.state.returnedImage ? imgDisplay : this.loading()} </div> </div> ) } }