[enh] There should be a preview for images uploaded
This commit is contained in:
parent
30e9a5a5cd
commit
c1b9f42c4a
@ -13,6 +13,8 @@ services:
|
|||||||
- "6379:6379"
|
- "6379:6379"
|
||||||
volumes:
|
volumes:
|
||||||
- laserrdb:/var/lib/redis
|
- laserrdb:/var/lib/redis
|
||||||
|
command: ["redis-server", "--appendonly", "yes"]
|
||||||
|
|
||||||
|
|
||||||
app:
|
app:
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
21
index.html
21
index.html
@ -20,15 +20,18 @@
|
|||||||
<script src="js/canvas.js"></script>
|
<script src="js/canvas.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
|
||||||
window.ORIGINAL_JSON=window.JSON;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="container-fluid container-md">
|
<div class="container-fluid container-md">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<h1 class="text-primary">Send shots to the laser!</h1>
|
<div class="select">
|
||||||
|
<label for="videoSource">Video source: </label>
|
||||||
|
<select id="videoSource">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-primary">Send shots to the laser!</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -64,7 +67,15 @@ window.ORIGINAL_JSON=window.JSON;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row" id="result">
|
||||||
|
<div class="col-sm">
|
||||||
|
<canvas id="simuCanvas" width="640" height="480"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm" >
|
||||||
|
<h3>Your images</h3>
|
||||||
|
<div id="imageList"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
133
js/canvas.js
133
js/canvas.js
@ -2,7 +2,7 @@
|
|||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|
||||||
var binary_level = 100
|
var binary_level = 100
|
||||||
var url = document.URL
|
var url = document.location.origin
|
||||||
var cropper = null
|
var cropper = null
|
||||||
var snap = null
|
var snap = null
|
||||||
var width;
|
var width;
|
||||||
@ -25,11 +25,9 @@ $(document).ready(function(){
|
|||||||
context.drawImage(video, 0, 0, width, height);
|
context.drawImage(video, 0, 0, width, height);
|
||||||
snap = context.createImageData(width, height);
|
snap = context.createImageData(width, height);
|
||||||
snap.data.set( context.getImageData(0, 0, width, height).data )
|
snap.data.set( context.getImageData(0, 0, width, height).data )
|
||||||
console.log(snap)
|
|
||||||
console.log(context.getImageData(0, 0, width, height))
|
|
||||||
binary(context)
|
binary(context)
|
||||||
$("#result").show()
|
$("#result").show()
|
||||||
$('html, body').animate({scrollTop: $("#result").offset().top}, 2000);
|
//$('html, body').animate({scrollTop: $("#result").offset().top}, 2000);
|
||||||
|
|
||||||
cropper = new Cropper(canvas,{
|
cropper = new Cropper(canvas,{
|
||||||
viewMode: 3,
|
viewMode: 3,
|
||||||
@ -47,7 +45,54 @@ $(document).ready(function(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://raw.githubusercontent.com/samdutton/simpl/gh-pages/getusermedia/sources/js/main.js
|
||||||
|
|
||||||
|
var videoElement = document.querySelector('video');
|
||||||
|
var videoSelect = document.querySelector('select#videoSource');
|
||||||
|
videoSelect.onchange = getStream;
|
||||||
|
getStream().then(getDevices).then(gotDevices);
|
||||||
|
|
||||||
|
function getDevices() {
|
||||||
|
// AFAICT in Safari this only gets default devices until gUM is called :/
|
||||||
|
return navigator.mediaDevices.enumerateDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotDevices(deviceInfos) {
|
||||||
|
window.deviceInfos = deviceInfos; // make available to console
|
||||||
|
for (const deviceInfo of deviceInfos) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = deviceInfo.deviceId;
|
||||||
|
option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
|
||||||
|
videoSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getStream() {
|
||||||
|
if (window.stream) {
|
||||||
|
window.stream.getTracks().forEach(track => {
|
||||||
|
track.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const videoSource = videoSelect.value;
|
||||||
|
const constraints = {
|
||||||
|
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
|
||||||
|
};
|
||||||
|
return navigator.mediaDevices.getUserMedia(constraints).
|
||||||
|
then(gotStream).catch(handleError);
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotStream(stream) {
|
||||||
|
window.stream = stream; // make stream available to console
|
||||||
|
videoSelect.selectedIndex = [...videoSelect.options].
|
||||||
|
findIndex(option => option.text === stream.getVideoTracks()[0].label);
|
||||||
|
videoElement.srcObject = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleError(error) {
|
||||||
|
console.error('Error: ', error);
|
||||||
|
}
|
||||||
|
// https://raw.githubusercontent.com/samdutton/simpl/gh-pages/getusermedia/sources/js/main.js
|
||||||
function setCameraResolution( track ){
|
function setCameraResolution( track ){
|
||||||
width = track.getSettings().width
|
width = track.getSettings().width
|
||||||
height = track.getSettings().height
|
height = track.getSettings().height
|
||||||
@ -158,6 +203,7 @@ $(document).ready(function(){
|
|||||||
imageList = localStorage.getItem("imageList") ? JSON.parse(localStorage.getItem("imageList")) : []
|
imageList = localStorage.getItem("imageList") ? JSON.parse(localStorage.getItem("imageList")) : []
|
||||||
imageList.push(d.hash_name)
|
imageList.push(d.hash_name)
|
||||||
localStorage.setItem("imageList",JSON.stringify(imageList))
|
localStorage.setItem("imageList",JSON.stringify(imageList))
|
||||||
|
refreshImageList()
|
||||||
})
|
})
|
||||||
.fail(function(d,m,jq){
|
.fail(function(d,m,jq){
|
||||||
$("#messages").html(`<div class="alert alert-danger" role="alert">Ooops... Something went wrong: ${jq}</div>`)
|
$("#messages").html(`<div class="alert alert-danger" role="alert">Ooops... Something went wrong: ${jq}</div>`)
|
||||||
@ -165,4 +211,83 @@ $(document).ready(function(){
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
var simuCanvas = document.getElementById("simuCanvas");
|
||||||
|
var ctx = simuCanvas.getContext("2d");
|
||||||
|
var lastpoint = { x: 0, y: 0, color: 0};
|
||||||
|
ctx.clearRect(0,0,400,400);
|
||||||
|
var zoom = 0.5;
|
||||||
|
//ctx.save
|
||||||
|
|
||||||
|
Point = function( l ){
|
||||||
|
return {
|
||||||
|
"x" : l[0],
|
||||||
|
"y" : l[1],
|
||||||
|
"color" : l[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws every segment received, except black colored target ones
|
||||||
|
var drawSimu = function() {
|
||||||
|
pointsList = document.pointsList
|
||||||
|
if (pointsList.length > 0)
|
||||||
|
{
|
||||||
|
ctx.clearRect(0,0,400,400);
|
||||||
|
lastpoint = new Point(pointsList[0])
|
||||||
|
for (var i = 0; i < pointsList.length; i+=1)
|
||||||
|
{
|
||||||
|
point = new Point(pointsList[i])
|
||||||
|
// if the target is black, skip drawing
|
||||||
|
if( point.color != 0){
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.shadowBlur = 5;
|
||||||
|
ctx.shadowColor = 'rgba(255, 255, 255, 1)';
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = "#"+(point.color + Math.pow(16, 6)).toString(16).slice(-6);
|
||||||
|
ctx.moveTo(lastpoint.x * zoom, lastpoint.y * zoom);
|
||||||
|
ctx.lineTo(point.x * zoom, point.y * zoom);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.closePath()
|
||||||
|
}
|
||||||
|
lastpoint = point
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function refreshImageList(){
|
||||||
|
var imageList = localStorage.getItem("imageList") ? JSON.parse(localStorage.getItem("imageList")) : []
|
||||||
|
html = ''
|
||||||
|
for( id in imageList){
|
||||||
|
hash_name = imageList[id]
|
||||||
|
html += `<li><a href="#${hash_name}" class="hash_name" rel="${hash_name}">${hash_name}</a></li>`
|
||||||
|
}
|
||||||
|
$("#imageList").html(`<ul>${html}</ul>`)
|
||||||
|
|
||||||
|
}
|
||||||
|
refreshImageList()
|
||||||
|
|
||||||
|
$("#imageList").on("click",function(e){
|
||||||
|
var el = e.target
|
||||||
|
var hash_name = $(el).attr("rel")
|
||||||
|
var u = `${url}/hash_name/${hash_name}`
|
||||||
|
$.ajax({
|
||||||
|
url: `${url}/hash_name/${hash_name}`,
|
||||||
|
dataType: "json",
|
||||||
|
|
||||||
|
}).done(function(d,m,j){
|
||||||
|
if( d.errors ){
|
||||||
|
msg = d.errors.join(" / ")
|
||||||
|
$("#messages").html(`<div class="alert alert-danger" role="alert">Something went wrong: ${msg}</div>`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$("#messages").html("")
|
||||||
|
document.pointsList = d.points_list
|
||||||
|
drawSimu()
|
||||||
|
})
|
||||||
|
.fail(function(d,m,jq){
|
||||||
|
$("#messages").html(`<div class="alert alert-danger" role="alert">Ooops... Something went wrong: ${jq}</div>`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
16
server.py
16
server.py
@ -61,6 +61,22 @@ def image():
|
|||||||
print("woah",e)
|
print("woah",e)
|
||||||
return( json.dumps( {"errors":[ str(e)]}))
|
return( json.dumps( {"errors":[ str(e)]}))
|
||||||
|
|
||||||
|
@app.route('/hash_name/<hash_name>',methods = ['GET'])
|
||||||
|
def hash_name(hash_name):
|
||||||
|
try:
|
||||||
|
|
||||||
|
item = json.loads(r.hget("images",hash_name))
|
||||||
|
if not item:
|
||||||
|
raise Exception("This image is not available now. You might need to wait a bit more?")
|
||||||
|
return( json.dumps({
|
||||||
|
"message":"ok",
|
||||||
|
"points_list":item["points_list"]
|
||||||
|
}) )
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("woah",e)
|
||||||
|
return( json.dumps( {"errors":[ str(e)]}))
|
||||||
|
|
||||||
# Run Flask
|
# Run Flask
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host= '0.0.0.0',debug = True)
|
app.run(host= '0.0.0.0',debug = True)
|
||||||
|
Loading…
Reference in New Issue
Block a user