Last active
March 5, 2020 17:29
-
-
Save ganeshkumartk/dc1e7ff8b2c5e3ab61b2e045c5a858be to your computer and use it in GitHub Desktop.
Index page: Place it in templates folder ---- main.css & main.js: Place in static folder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | |
<title>Demo</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}" /> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="title"> | |
<h3>Image Classifier</h3> | |
</div> | |
<div class="panel"> | |
<input id="file-upload" class="hidden" type="file" accept="image/x-png,image/gif,image/jpeg" /> | |
<label for="file-upload" id="file-drag" class="upload-box"> | |
<div id="upload-caption">Drop image here or click to select</div> | |
<img id="image-preview" class="hidden" /> | |
</label> | |
</div> | |
<div style="margin-bottom: 2rem;"> | |
<input type="button" value="Submit" class="button" onclick="submitImage();" /> | |
<input type="button" value="Clear" class="button" onclick="clearImage();" /> | |
</div> | |
<div id="image-box"> | |
<img id="image-display" /> | |
<div id="pred-result" class="hidden"></div> | |
<svg id="loader" class="hidden" viewBox="0 0 32 32" width="32" height="32"> | |
<circle id="spinner" cx="16" cy="16" r="14" fill="none"></circle> | |
</svg> | |
</div> | |
</div> | |
</body> | |
<footer> | |
<script src="{{ url_for('static',filename='main.js') }}"></script> | |
</footer> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, | |
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; | |
-webkit-font-smoothing: antialiased; | |
background-color: #f8f8f8; | |
} | |
/* Global button style */ | |
.button { | |
font-family: inherit; | |
text-align: center; | |
cursor: pointer; | |
border: none; | |
text-decoration: none; | |
outline: none; | |
color: #ffffff; | |
background-color: rgb(0, 120, 212); | |
padding: 0.5rem 1.2rem; | |
border-radius: 2px; | |
font-size: 1rem; | |
min-width: 6rem; | |
} | |
.button:hover { | |
background-color: rgb(16, 110, 190); | |
} | |
.button.disabled { | |
pointer-events: none; | |
background-color: #cccccc; | |
color: #666666; | |
} | |
/* Main section */ | |
.main { | |
box-sizing: border-box; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
} | |
.main .title h3 { | |
font-size: 2.3rem; | |
font-weight: 300; | |
margin: 0.8rem 0; | |
} | |
.hidden { | |
display: none; | |
} | |
.reveal { | |
opacity: 0; | |
} | |
.reveal:hover { | |
opacity: 0.2; | |
} | |
/* Upload box */ | |
.upload-box { | |
font-size: 0.8rem; | |
color: #666666; | |
cursor: pointer; | |
width: 16rem; | |
height: 10rem; | |
background: #fff; | |
border: 0.1rem dashed #838388; | |
border-radius: 0.4rem; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
flex-direction: column; | |
margin: 1rem 0 2rem 0; | |
} | |
.upload-box.dragover { | |
/* background-color: grey; */ | |
color: #eeeeee; | |
border: 0.1rem solid rgb(0, 120, 212); | |
box-shadow: inset 0 0 0 0.1rem rgb(0, 120, 212); | |
} | |
.upload-box:hover { | |
border-color: rgb(0, 120, 212); | |
} | |
.upload-box #image-preview { | |
max-width: 14rem; | |
max-height: 8rem; | |
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.19); | |
} | |
#image-result { | |
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); | |
max-height: 20rem; | |
} | |
#image-box { | |
position: relative; | |
width: auto; | |
float: left; | |
margin-bottom: 2rem; | |
} | |
#image-display { | |
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); | |
max-height: 20rem; | |
} | |
#image-display.loading { | |
filter: brightness(30%); | |
} | |
#pred-result { | |
color: white; | |
font-size: 1.5rem; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
} | |
#loader { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
z-index: 10; | |
margin: 0 auto; | |
} | |
/* Animation */ | |
#spinner { | |
box-sizing: border-box; | |
stroke: #cccccc; | |
stroke-width: 3px; | |
transform-origin: 50%; | |
animation: line 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite, | |
rotate 1.6s linear infinite; | |
} | |
@keyframes rotate { | |
from { | |
transform: rotate(0); | |
} | |
to { | |
transform: rotate(450deg); | |
} | |
} | |
@keyframes line { | |
0% { | |
stroke-dasharray: 2, 85.964; | |
transform: rotate(0); | |
} | |
50% { | |
stroke-dasharray: 65.973, 21.9911; | |
stroke-dashoffset: 0; | |
} | |
100% { | |
stroke-dasharray: 2, 85.964; | |
stroke-dashoffset: -65.973; | |
transform: rotate(90deg); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fileDrag = document.getElementById("file-drag"); | |
var fileSelect = document.getElementById("file-upload"); | |
// Add event listeners | |
fileDrag.addEventListener("dragover", fileDragHover, false); | |
fileDrag.addEventListener("dragleave", fileDragHover, false); | |
fileDrag.addEventListener("drop", fileSelectHandler, false); | |
fileSelect.addEventListener("change", fileSelectHandler, false); | |
function fileDragHover(e) { | |
// prevent default behaviour | |
e.preventDefault(); | |
e.stopPropagation(); | |
fileDrag.className = e.type === "dragover" ? "upload-box dragover" : "upload-box"; | |
} | |
function fileSelectHandler(e) { | |
// handle file selecting | |
var files = e.target.files || e.dataTransfer.files; | |
fileDragHover(e); | |
for (var i = 0, f; (f = files[i]); i++) { | |
previewFile(f); | |
} | |
} | |
//======================================================================== | |
// Web page elements for functions to use | |
//======================================================================== | |
var imagePreview = document.getElementById("image-preview"); | |
var imageDisplay = document.getElementById("image-display"); | |
var uploadCaption = document.getElementById("upload-caption"); | |
var predResult = document.getElementById("pred-result"); | |
var loader = document.getElementById("loader"); | |
//======================================================================== | |
// Main button events | |
//======================================================================== | |
function submitImage() { | |
// action for the submit button | |
console.log("submit"); | |
if (!imageDisplay.src || !imageDisplay.src.startsWith("data")) { | |
window.alert("Please select an image before submit."); | |
return; | |
} | |
loader.classList.remove("hidden"); | |
imageDisplay.classList.add("loading"); | |
// call the predict function of the backend | |
predictImage(imageDisplay.src); | |
} | |
function clearImage() { | |
// reset selected files | |
fileSelect.value = ""; | |
// remove image sources and hide them | |
imagePreview.src = ""; | |
imageDisplay.src = ""; | |
predResult.innerHTML = ""; | |
hide(imagePreview); | |
hide(imageDisplay); | |
hide(loader); | |
hide(predResult); | |
show(uploadCaption); | |
imageDisplay.classList.remove("loading"); | |
} | |
function previewFile(file) { | |
// show the preview of the image | |
console.log(file.name); | |
var fileName = encodeURI(file.name); | |
var reader = new FileReader(); | |
reader.readAsDataURL(file); | |
reader.onloadend = () => { | |
imagePreview.src = URL.createObjectURL(file); | |
show(imagePreview); | |
hide(uploadCaption); | |
// reset | |
predResult.innerHTML = ""; | |
imageDisplay.classList.remove("loading"); | |
displayImage(reader.result, "image-display"); | |
}; | |
} | |
//======================================================================== | |
// Helper functions | |
//======================================================================== | |
function predictImage(image) { | |
fetch("/predict", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
body: JSON.stringify(image) | |
}) | |
.then(resp => { | |
if (resp.ok) | |
resp.json().then(data => { | |
displayResult(data); | |
}); | |
}) | |
.catch(err => { | |
console.log("An error occured", err.message); | |
window.alert("Oops! Something went wrong."); | |
}); | |
} | |
function displayImage(image, id) { | |
// display image on given id <img> element | |
let display = document.getElementById(id); | |
display.src = image; | |
show(display); | |
} | |
function displayResult(data) { | |
// display the result | |
// imageDisplay.classList.remove("loading"); | |
hide(loader); | |
predResult.innerHTML = data.result; | |
show(predResult); | |
} | |
function hide(el) { | |
// hide an element | |
el.classList.add("hidden"); | |
} | |
function show(el) { | |
// show an element | |
el.classList.remove("hidden"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment