Files
photoassistant/templates/viewer.html

266 lines
12 KiB
HTML

{% extends "base.html" %} {% block main_content %}
{# make the form-switch / toggle info color set, give or take #}
<style>
.norm-txt { font-size: 1.0rem }
.form-check-input:checked {
background-color: #39C0ED;
border-color: #CFF4FC;
}
.form-switch .form-check-input {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2339C0ED'/%3e%3c/svg%3e");
}
.form-switch .form-check-input:focus {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23CFF4FC'/%3e%3c/svg%3e");
}
</style>
<script>
var gap=0.8
function NewWidth()
{
w_r=im.width/(window.innerWidth*gap)
h_r=im.height/(window.innerHeight*gap)
if( w_r > h_r )
return window.innerWidth*gap
else
return im.width*gap / (im.height/window.innerHeight)
}
function NewHeight()
{
w_r=im.width/(window.innerWidth*gap)
h_r=im.height/(window.innerHeight*gap)
if( h_r > w_r )
return window.innerHeight*gap
else
return im.height*gap / (im.width/window.innerWidth)
}
// Define this once and before it will be called, hence at the top of this file
function DrawImg()
{
// another call to this func will occur on load, so skip this one
if( im.width == 0 )
return
canvas.width=NewWidth(im)
canvas.height=NewHeight(im)
// actually draw the pixel images to the canvas at the right size
context.drawImage(im, 0, 0, canvas.width, canvas.height )
if( $('#faces').prop('checked') )
{
// draw rect on each face
for( i=0; i<faces.length; i++ )
{
x = faces[i].x / ( im.width/canvas.width )
y = faces[i].y / ( im.height/canvas.height )
w = faces[i].w / ( im.width/canvas.width )
h = faces[i].h / ( im.height/canvas.height )
context.beginPath()
context.rect( x, y, w, h )
context.lineWidth = 2
context.strokeStyle = 'green'
if( faces[i].who )
{
// finish face box, need to clear out new settings for
// transparent backed-name tag
context.stroke();
context.beginPath()
context.lineWidth = 0.1
context.font = "30px Arial"
context.globalAlpha = 0.6
str=faces[i].who
if( $('#distance').prop('checked') )
str += "("+faces[i].distance+")"
bbox = context.measureText(str);
f_h=bbox.fontBoundingBoxAscent
if( bbox.fontBoundingBoxDescent )
f_h += bbox.fontBoundingBoxDescent
f_h -= 8
context.rect( x+w/2-bbox.width/2, y-f_h, bbox.width, f_h )
context.fillStyle="white"
context.fill()
context.stroke();
context.beginPath()
context.globalAlpha = 1.0
context.font = "30px Arial"
context.textAlign = "center"
context.fillStyle = "green"
context.fillText(str, x+w/2, y-2)
}
/* can use to show lower left coords of a face for debugging
else
{
context.font = "14px Arial"
context.textAlign = "center"
context.fillStyle = "black"
context.fillText( 'x=' + faces[i].x + ', y=' + faces[i].y, x+w/2, y-2)
context.fillText( 'x=' + faces[i].x + ', y=' + faces[i].y, x+w/2, y-2)
}
*/
context.stroke();
}
}
}
function ResizeVideo()
{
$('#_v').height(window.innerHeight*gap)
}
function FaceToggle()
{
$('#distance').prop('disabled', function(i, v) { return !v; });
DrawImg()
}
</script>
<div id="viewer" class="container-fluid">
{% set max=eids.split(',')|length %}
<input type="hidden" name="eids" value={{eids}}>
<div class="row">
{% if eids.find(obj.id|string) > 0 %}
<form id="prev" class="col col-auto" action="/viewprev" method="POST">
<input type="hidden" name="current" value="{{obj.id}}">
<input type="hidden" name="eids" value="{{eids}}">
<input id="prev_fname" type="hidden" name="fname" value="">
<input id="prev_faces" type="hidden" name="faces" value="">
<input id="prev_distance" type="hidden" name="distance" value="">
<button class="btn btn-outline-info h-75" id="la"
onClick="
$('#prev_fname').val($('#fname').prop('checked'))
$('#prev_faces').val($('#faces').prop('checked'))
$('#prev_distance').val($('#distance').prop('checked'))
">
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('static', filename='upstream/icons.svg')}}#prev"/></svg>
</button>
</form id="prev">
{% endif %}
{% if obj.type.name == "Image" %}
<figure class="col col-auto border border-info rounded m-0 p-1" id="figure">
<canvas id="canvas"></canvas>
<script>
var im=new Image();
im.onload=DrawImg
im.src="/{{obj.in_dir.in_path.path_prefix}}/{{obj.in_dir.rel_path}}/{{obj.name}}"
var faces=[]
{% for face in obj.file_details.faces %}
data = {
'x': '{{face.locn[3]}}', 'y': '{{face.locn[0]}}',
'w': '{{face.locn[1]-face.locn[3]}}', 'h':'{{face.locn[2]-face.locn[0]}}'
}
{% if face.refimg %}
data['who']='{{face.refimg.person.tag}}'
data['distance']="{{face.refimg_lnk.face_distance|round(2)}}"
data['model']="{{face.facefile_lnk.model_used}}"
{% endif %}
faces.push( data )
{% endfor %}
var context = canvas.getContext('2d')
window.addEventListener('resize', DrawImg, false);
</script>
<figcaption class="figure-caption text-center text-wrap text-break"
{% if sels['fname']=='false' %}
style="display:none"
{% endif %}
>{{obj.name}}
</figcaption>
</figure>
{% elif obj.type.name == "Video" %}
<video id="_v" controls>
<source src="/{{obj.in_dir.in_path.path_prefix}}/{{obj.in_dir.rel_path}}/{{obj.name}}" type="video/mp4">
Your browser does not support the video tag.
</video>
<script>
window.addEventListener('resize', ResizeVideo, false);
ResizeVideo()
</script>
{% endif %}
{% for eid in eids.split(',') %}
{% if loop.index == max-1 %}
{% if eid|int != obj.id %}
<form id="next" class="col col-auto" action="/viewnext" method="POST">
<input type="hidden" name="current" value="{{obj.id}}">
<input type="hidden" name="eids" value="{{eids}}">
<input id="next_fname" type="hidden" name="fname" value="">
<input id="next_faces" type="hidden" name="faces" value="">
<input id="next_distance" type="hidden" name="distance" value="">
<button class="col col-auto btn btn-outline-info h-75" id="ra"
onClick="
$('#next_fname').val($('#fname').prop('checked'))
$('#next_faces').val($('#faces').prop('checked'))
$('#next_distance').val($('#distance').prop('checked'))
">
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('static', filename='upstream/icons.svg')}}#next"/></svg>
</button>
</form id="next">
{% endif %}
{% endif %}
{% endfor %}
</div id="/form-row">
{# use this for color of toggles: https://www.codeply.com/p/4sL9uhevwJ #}
<div class="row">
<span class="d-flex col-1 justify-content-end my-auto">Show:</span>
<div class="d-flex form-check form-switch border border-info rounded col-1 my-auto py-1 justify-content-center">
<input class="form-check-input" type="checkbox" id="fname" onChange="$('.figure-caption').toggle()"
{% if sels['fname']=='true' %} checked {% endif %} >
<label class="form-check-label" for="fname">Filename</label>
</div>
<div class="d-flex form-check form-switch border border-info rounded col-1 my-auto py-1 justify-content-center">
<input class="form-check-input" type="checkbox" onChange="FaceToggle()" id="faces"
{% if not obj.file_details.faces %} disabled {% endif %}
{% if sels['faces']=='true' %} checked {% endif %}
>
<label class="form-check-label" for="faces">Faces</label>
</div>
<div class="d-flex form-check form-switch border border-info rounded col-1 my-auto py-1 justify-content-center">
<input class="form-check-input" type="checkbox" onChange="DrawImg()" id="distance"
{% if not obj.file_details.faces or sels['faces']=='false' %} disabled {% endif %}
{% if sels['distance']=='true' %} checked {% endif %}
>
<label class="form-check-label" for="distance">Distance</label>
</div>
<span class="col col-auto my-auto py-1">AI Model:</span>
<div class="col col-auto">
{% if not obj.file_details.faces %}
{{CreateSelect( "model", 0, ["N/A", "normal", "slow/accurate"], "", "rounded-end h-100 norm-txt", [0,1,2])|safe }}
{% else %}
{{CreateSelect( "model", obj.file_details.faces[0].facefile_lnk.model_used, ["normal", "slow/accurate"], "", "rounded-end h-100 norm-txt", [1,2])|safe }}
{% endif %}
</div>
</div class="row">
{% endblock main_content %}
{% block script_content %}
<script>
$( document ).keydown(function(event) {
switch (event.key)
{
case "Left": // IE/Edge specific value
case "ArrowLeft":
$('#la').click()
break;
case "Right": // IE/Edge specific value
case "ArrowRight":
$('#ra').click()
break;
case "d":
$('#distance').click()
break;
case "f":
$('#faces').click()
break;
case "n":
$('#fname').click()
break;
default:
return; // Quit when this doesn't handle the key event.
}
});
</script>
{% endblock script_content %}