dispatch des éléments
This commit is contained in:
parent
c59ec9bbf8
commit
5c0a357cc8
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/photo_mem.iml" filepath="$PROJECT_DIR$/.idea/photo_mem.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/photo_mem.iml
generated
Normal file
8
.idea/photo_mem.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -11,7 +11,7 @@ Inutile de garder des photos si vous ne savez pas qui est dessus.
|
|||||||
On m'a transmis beaucoup de photos anciennes (1919-1950), et je voulais mémoriser un maximum de noms de participants, pour transmettre tout cela aux descendants . Il y avait urgence car les personnes qui connaissaient ces photos et qui pouvaient me renseigner disparaissaient rapidement. Et donc, plutôt que de tout noter sur des bouts de papier difficiles à gérer, j'ai fait ce petit programme qui m'a été très utile, et en quelques séances passées chez des cousins ou voisins, j'ai pu renseigner une quarantaine de photos. (pas complètement).
|
On m'a transmis beaucoup de photos anciennes (1919-1950), et je voulais mémoriser un maximum de noms de participants, pour transmettre tout cela aux descendants . Il y avait urgence car les personnes qui connaissaient ces photos et qui pouvaient me renseigner disparaissaient rapidement. Et donc, plutôt que de tout noter sur des bouts de papier difficiles à gérer, j'ai fait ce petit programme qui m'a été très utile, et en quelques séances passées chez des cousins ou voisins, j'ai pu renseigner une quarantaine de photos. (pas complètement).
|
||||||
Ce programme peut être utilisé aussi pour vos photos de classe, équipe de foot, ou tout autres photos comportant des personnages ... ou animaux !
|
Ce programme peut être utilisé aussi pour vos photos de classe, équipe de foot, ou tout autres photos comportant des personnages ... ou animaux !
|
||||||
|
|
||||||
Utilisation :
|
## Utilisation :
|
||||||
Mettez vos photos à traiter dans un répertoire, avec le programme Photo_mem_cv et les fichiers opencv.js et haarcascade*.xml
|
Mettez vos photos à traiter dans un répertoire, avec le programme Photo_mem_cv et les fichiers opencv.js et haarcascade*.xml
|
||||||
Lancer la page photo_mem.html dans un navigateur, c'est avec firefox que ça marche le mieux. je crois que chromium passe mais IE pas du tout.
|
Lancer la page photo_mem.html dans un navigateur, c'est avec firefox que ça marche le mieux. je crois que chromium passe mais IE pas du tout.
|
||||||
Pour commencer, cliquez sur le bouton bleu "choix de la photo", trois cas possibles :
|
Pour commencer, cliquez sur le bouton bleu "choix de la photo", trois cas possibles :
|
||||||
@ -24,7 +24,7 @@ Pour commencer, cliquez sur le bouton bleu "choix de la photo", trois cas possib
|
|||||||
Quand vous avez terminé de remplir et de positionner vos étiquettes, n'oubliez pas d'enregistrer le xml. Choisissez le même répertoire que la photo, le nom donné au xml est le même que celui de la photo. Il écrase le fichier en cours.
|
Quand vous avez terminé de remplir et de positionner vos étiquettes, n'oubliez pas d'enregistrer le xml. Choisissez le même répertoire que la photo, le nom donné au xml est le même que celui de la photo. Il écrase le fichier en cours.
|
||||||
Attention, il n'y a pas de sauvegarde automatique, et si vous oubliez de sauvegarder, tout est perdu !
|
Attention, il n'y a pas de sauvegarde automatique, et si vous oubliez de sauvegarder, tout est perdu !
|
||||||
|
|
||||||
Reste à faire :
|
## Reste à faire :
|
||||||
modifier une personne - en cours ...
|
modifier une personne - en cours ...
|
||||||
saisir / modifier le titre - en cours ...
|
saisir / modifier le titre - en cours ...
|
||||||
adapter la taille des étiquettes et du cercle à la résolution de l'image
|
adapter la taille des étiquettes et du cercle à la résolution de l'image
|
||||||
|
436
main.js
Normal file
436
main.js
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
|
||||||
|
var personnes=[],nom=[],nomjf=[],prenom=[],annee=[],note=[],posx=[],posy=[],etx=[],ety=[], can_etiq=[];
|
||||||
|
var ibac=0, tit={}, titre="", fond=[];
|
||||||
|
var mode_saisie="true" // mode saisie true, mode modification false
|
||||||
|
var image = document.getElementById('ima_fond');
|
||||||
|
var cercle = document.getElementById("cirsvg");
|
||||||
|
var menu = document.getElementById("menu_modif");
|
||||||
|
var modif_titre = document.getElementById("nouveau_titre");
|
||||||
|
var cant = document.createElement("canvas");
|
||||||
|
document.body.appendChild(cant);
|
||||||
|
|
||||||
|
let inputElement = document.getElementById('fichiers');
|
||||||
|
inputElement.addEventListener('change', (e) => {
|
||||||
|
lecfic(e.target.files)
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function lecfic(fichier) {
|
||||||
|
nb_fichier=fichier.length
|
||||||
|
var i_xml=1, i_img=0;
|
||||||
|
if (fichier[0].name.split('.').pop()=="xml") {i_xml=0; i_img=1};
|
||||||
|
var src=fichier[i_img].name.substring(0,fichier[i_img].name.indexOf("."));
|
||||||
|
enreg_xml=src+".xml"
|
||||||
|
enreg_noms=src+"_noms.png"
|
||||||
|
fichier_xml=fichier[i_xml];
|
||||||
|
fond=fichier[i_img];
|
||||||
|
affiche_fond();
|
||||||
|
|
||||||
|
if (nb_fichier==1) {creation_data_xml(); lecture_xml(); return} // Un seul fichier sélectionné : l'image à traiter
|
||||||
|
|
||||||
|
if (fichier_xml.name.startsWith("haar")) {creation_data_xml(); detection_de_visages();return} // deux fichiers selectionnés : l'image et haarcascade.xml
|
||||||
|
|
||||||
|
// deux fichiers selectionnés : l'image et le xml du même nom
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(evt) {lecture(evt.target.result);};
|
||||||
|
reader.readAsText(fichier_xml);
|
||||||
|
|
||||||
|
function lecture(text) {
|
||||||
|
var parser = new DOMParser();
|
||||||
|
data_xml = parser.parseFromString(text,"text/xml");
|
||||||
|
lecture_xml();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chargement et affichage de l'image background
|
||||||
|
function affiche_fond() {
|
||||||
|
var read_fond = new FileReader();
|
||||||
|
read_fond.addEventListener("load", function (evt) {
|
||||||
|
image.src = evt.target.result;
|
||||||
|
}, false);
|
||||||
|
read_fond.readAsDataURL(fond);
|
||||||
|
}
|
||||||
|
|
||||||
|
function lecture_xml() {
|
||||||
|
tit = data_xml.documentElement.getElementsByTagName("titre")[0];
|
||||||
|
titre=tit.textContent
|
||||||
|
personnes = data_xml.documentElement.getElementsByTagName("personne");
|
||||||
|
nb_pers=personnes.length
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
nom[i] = personnes[i].getElementsByTagName( "nom")[0].textContent;
|
||||||
|
if (personnes[i].getElementsByTagName( "nom_jeune_fille")[0]) {
|
||||||
|
nomjf[i] = personnes[i].getElementsByTagName( "nom_jeune_fille")[0].textContent;
|
||||||
|
}
|
||||||
|
prenom[i] = personnes[i].getElementsByTagName( "prenom")[0].textContent;
|
||||||
|
annee[i] = personnes[i].getElementsByTagName( "annee_naiss")[0].textContent;
|
||||||
|
note[i] = personnes[i].getElementsByTagName( "note")[0].textContent;
|
||||||
|
posx[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['posx'].value);
|
||||||
|
posy[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['posy'].value);
|
||||||
|
etx[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['etx'].value);
|
||||||
|
ety[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['ety'].value);
|
||||||
|
}
|
||||||
|
if (titre!=='') {affiche_titre(titre)}
|
||||||
|
affiche_etiquette() ;
|
||||||
|
};
|
||||||
|
|
||||||
|
function affiche_titre(titre_photo) {
|
||||||
|
cant.className="tit";
|
||||||
|
cant.height=23;
|
||||||
|
var taille=titre_photo.length;
|
||||||
|
cant.width=taille*12;
|
||||||
|
tx = parseFloat(tit.attributes['titx'].value);
|
||||||
|
ty = parseFloat(tit.attributes['tity'].value);
|
||||||
|
cant.style.left = tx + "px";
|
||||||
|
cant.style.top = ty + "px";
|
||||||
|
titre_ctx = cant.getContext("2d");
|
||||||
|
titre_ctx.font = '21px Arial';
|
||||||
|
titre_ctx.fillStyle = 'Maroon';
|
||||||
|
titre_ctx.fillText(titre_photo, 20, 18);
|
||||||
|
affiche_etiquette() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
function affiche_etiquette() {
|
||||||
|
// affichage du texte nom/prénom dans des canvas etiquette
|
||||||
|
rayon=28
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
var id="can"+i;
|
||||||
|
if (document.getElementById(id)) continue ;
|
||||||
|
var canv = document.createElement("canvas");
|
||||||
|
canv.id=id;
|
||||||
|
document.body.appendChild(canv);
|
||||||
|
can_etiq[i] = document.getElementById(canv.id);
|
||||||
|
can_etiq[i].className="etiq";
|
||||||
|
can_etiq[i].height=30;
|
||||||
|
etiq_ctx = can_etiq[i].getContext("2d");
|
||||||
|
var taille=Math.max(nom[i].length,prenom[i].length,nomjf[i].length+5);
|
||||||
|
can_etiq[i].width=taille*7+10
|
||||||
|
if (nomjf[i].replace(/\t/g, '').length>1) {can_etiq[i].height=45};
|
||||||
|
etiq_ctx.font = '13px Arial';
|
||||||
|
etiq_ctx.fillStyle = 'chocolate';
|
||||||
|
can_etiq[i].style.left = etx[i] + "px";
|
||||||
|
can_etiq[i].style.top = ety[i] + "px";
|
||||||
|
etiq_ctx.fillText(nom[i], 7, 12);
|
||||||
|
etiq_ctx.fillText(prenom[i], 7, 25);
|
||||||
|
if (nomjf[i].length>1) {etiq_ctx.fillText("née : "+nomjf[i], 7, 38)};
|
||||||
|
};
|
||||||
|
gestion_souris();
|
||||||
|
};
|
||||||
|
|
||||||
|
function gestion_souris() {
|
||||||
|
if (titre!=='') { // pour déplacer le titre
|
||||||
|
cant.addEventListener("mousedown", function(e){this.addEventListener("mousemove", deplace_etiquette);});
|
||||||
|
cant.addEventListener("mouseup", function(e){this.removeEventListener("mousemove", deplace_etiquette);});
|
||||||
|
}
|
||||||
|
for (var i = 0; i < nb_pers; i++) { // pour déplacer les étiquettes nom,prénom ...
|
||||||
|
can_etiq[i].addEventListener("mousedown", function(e){this.addEventListener("mousemove", deplace_etiquette);});
|
||||||
|
can_etiq[i].addEventListener("mouseup", function(e){this.removeEventListener("mousemove", deplace_etiquette);});
|
||||||
|
};
|
||||||
|
ima_fond.addEventListener('mousedown', afficher_formulaire); // pour afficher le formulaire de saisie personne
|
||||||
|
ima_fond.addEventListener('mousemove', tracer_cercle); // pour afficher cercle personne
|
||||||
|
cercle.addEventListener('contextmenu', function (e) { menu_modif(e); e.preventDefault();}, false); // menu modif personne
|
||||||
|
};
|
||||||
|
|
||||||
|
function deplace_etiquette(e){
|
||||||
|
e.target.style.top = e.pageY-15+"px";
|
||||||
|
e.target.style.left = e.pageX-30+"px";
|
||||||
|
};
|
||||||
|
|
||||||
|
function menu_modif(){
|
||||||
|
menu.style.left = parseFloat(cercle.getAttribute("cx"))+10 +"px";
|
||||||
|
menu.style.top = parseFloat(cercle.getAttribute("cy"))+40 +"px";
|
||||||
|
menu.style.visibility="visible";
|
||||||
|
}
|
||||||
|
|
||||||
|
function supprimer_personne() {
|
||||||
|
misajour_xml();
|
||||||
|
x = data_xml.getElementsByTagName("personne")[ibac];
|
||||||
|
x.parentNode.removeChild(x);
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
x = can_etiq[i];
|
||||||
|
x.parentNode.removeChild(x);
|
||||||
|
};
|
||||||
|
cercle.style.visibility="hidden";
|
||||||
|
lecture_xml();
|
||||||
|
}
|
||||||
|
function creation_data_xml() {
|
||||||
|
var x, i;
|
||||||
|
var txt = "";
|
||||||
|
var text = "<photo>" +
|
||||||
|
"<titre titx='50px' tity='50px'>Titre "+ fond.name + "</titre>" +
|
||||||
|
"<date> </date>" +
|
||||||
|
"<lieu> </lieu>" +
|
||||||
|
"<commentaire> </commentaire>" +
|
||||||
|
"</photo>";
|
||||||
|
|
||||||
|
var parser_face = new DOMParser();
|
||||||
|
data_xml = parser_face.parseFromString(text,"text/xml");
|
||||||
|
// documentElement always represents the root node
|
||||||
|
x = data_xml.documentElement.childNodes;
|
||||||
|
for (i = 0; i < x.length ;i++) {
|
||||||
|
txt += x[i].nodeName + ": " + x[i].childNodes[0].nodeValue + "<br>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function detection_de_visages() {
|
||||||
|
// alert pour temporiser
|
||||||
|
alert("Ok pour continuer")
|
||||||
|
src = cv.imread(ima_fond);
|
||||||
|
gray = new cv.Mat();
|
||||||
|
cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
|
||||||
|
chargement_haarcascade();
|
||||||
|
}
|
||||||
|
function chargement_haarcascade() {
|
||||||
|
var reader_haar = new FileReader();
|
||||||
|
reader_haar.onload = function(ev) {
|
||||||
|
function str2ab(text) {
|
||||||
|
return new TextEncoder().encode(text);
|
||||||
|
}
|
||||||
|
faceCascadeFile = fichier_xml.name;
|
||||||
|
let data=str2ab(reader_haar.result)
|
||||||
|
cv.FS_createDataFile('/', faceCascadeFile, data, true, false, false);
|
||||||
|
detect_faces();
|
||||||
|
};
|
||||||
|
reader_haar.readAsText(fichier_xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
function detect_faces() {
|
||||||
|
|
||||||
|
let faces = new cv.RectVector();
|
||||||
|
let faceCascade = new cv.CascadeClassifier();
|
||||||
|
// load pre-trained classifiers
|
||||||
|
faceCascade.load(faceCascadeFile);
|
||||||
|
// detect faces
|
||||||
|
let msize = new cv.Size(0, 0);
|
||||||
|
faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, msize, msize);
|
||||||
|
console.log("Il y a "+ faces.size()+" visage(s)")
|
||||||
|
for (let i = 0; i < faces.size(); ++i) {
|
||||||
|
ajouter_personne_xml("nom_"+parseInt(i)+" ",faces.get(i).x,faces.get(i).y,faces.get(i).width,faces.get(i).height)
|
||||||
|
}
|
||||||
|
// cv.imshow('ima_fond', src);
|
||||||
|
src.delete(); gray.delete(); faceCascade.delete();
|
||||||
|
faces.delete();
|
||||||
|
lecture_xml();
|
||||||
|
|
||||||
|
;}
|
||||||
|
function ajouter_personne_xml(nom_face,fx,fy,fw,fh) {
|
||||||
|
var nomform=nom_face
|
||||||
|
var nomjfform=""
|
||||||
|
var prenomform=""
|
||||||
|
var anneeform=""
|
||||||
|
var noteform=""
|
||||||
|
var posxx=fx+fw/2
|
||||||
|
var posyy=fy+fh/2
|
||||||
|
var etxx=fx+10
|
||||||
|
var etyy=fy+fh*2
|
||||||
|
document.getElementById('ajout').className='invisible';
|
||||||
|
|
||||||
|
if (!nom_face) {
|
||||||
|
posxx=fx
|
||||||
|
posyy=fy
|
||||||
|
etxx=fx-30
|
||||||
|
etyy=fy+80
|
||||||
|
nomform=document.getElementById("nom").value
|
||||||
|
nomjfform=document.getElementById("nom_jeune_fille").value
|
||||||
|
prenomform=document.getElementById("prenom").value
|
||||||
|
anneeform=document.getElementById("annee").value
|
||||||
|
noteform=document.getElementById("note").value
|
||||||
|
}
|
||||||
|
// création d'un nouvel élément <personne> dans data_xml
|
||||||
|
var personne_ = data_xml.createElement("personne");
|
||||||
|
var nom_ = data_xml.createElement("nom");
|
||||||
|
nom_.appendChild(data_xml.createTextNode(nomform));
|
||||||
|
var nom_jf_ = data_xml.createElement("nom_jeune_fille");
|
||||||
|
nom_jf_.appendChild(data_xml.createTextNode(nomjfform));
|
||||||
|
var prenom_ = data_xml.createElement("prenom");
|
||||||
|
prenom_.appendChild(data_xml.createTextNode(prenomform));
|
||||||
|
var annee_ = data_xml.createElement("annee_naiss");
|
||||||
|
annee_.appendChild(data_xml.createTextNode(anneeform));
|
||||||
|
var note_ = data_xml.createElement("note");
|
||||||
|
note_.appendChild(data_xml.createTextNode(noteform));
|
||||||
|
var position_ = data_xml.createElement("position");
|
||||||
|
position_.setAttribute("posx", posxx);
|
||||||
|
position_.setAttribute("posy", posyy);
|
||||||
|
position_.setAttribute("etx", etxx);
|
||||||
|
position_.setAttribute("ety", etyy);
|
||||||
|
personne_.appendChild(nom_);
|
||||||
|
personne_.appendChild(nom_jf_);
|
||||||
|
personne_.appendChild(prenom_);
|
||||||
|
personne_.appendChild(annee_);
|
||||||
|
personne_.appendChild(note_);
|
||||||
|
personne_.appendChild(position_);
|
||||||
|
data_xml.getElementsByTagName("photo")[0].appendChild(personne_)
|
||||||
|
};
|
||||||
|
|
||||||
|
function modifier_personne() {
|
||||||
|
mode_saisie="false";
|
||||||
|
afficher_formulaire(this);
|
||||||
|
document.getElementById('nom').setAttribute('value', nom[ibac]);
|
||||||
|
document.getElementById('nom_jeune_fille').setAttribute('value', nomjf[ibac]);
|
||||||
|
document.getElementById('prenom').setAttribute('value', prenom[ibac]);
|
||||||
|
document.getElementById('annee').setAttribute('value', annee[ibac]);
|
||||||
|
document.getElementById('note').setAttribute('value', note[ibac]);
|
||||||
|
document.getElementById('titre').setAttribute('value', titre);
|
||||||
|
menu.style.visibility='hidden';
|
||||||
|
document.getElementById("enreg").style.visibility="hidden";
|
||||||
|
alert("Fonction en cours de développement")
|
||||||
|
};
|
||||||
|
|
||||||
|
function position_souris(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function tracer_cercle(e) {
|
||||||
|
document.getElementsByTagName("svg")[0].setAttribute('height', image.naturalHeight);
|
||||||
|
document.getElementsByTagName("svg")[0].setAttribute('width',image.naturalWidth);
|
||||||
|
var pos_x=position_souris(ima_fond, e).x;
|
||||||
|
var pos_y=position_souris(ima_fond, e).y;
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
var dx = posx[i] - pos_x;
|
||||||
|
var dy = posy[i] - pos_y;
|
||||||
|
var dist2 = dx * dx + dy * dy;
|
||||||
|
var rayon2 = rayon * rayon;
|
||||||
|
|
||||||
|
if (dist2 < rayon2) {
|
||||||
|
ibac=i
|
||||||
|
can_etiq[i].style.background = "palegreen"
|
||||||
|
cercle.setAttribute("cx",posx[i]);
|
||||||
|
cercle.setAttribute("cy",posy[i]);
|
||||||
|
cercle.setAttribute("r",rayon);
|
||||||
|
cercle.style.visibility="visible";
|
||||||
|
// grossir ou diminuer la taille du cercle
|
||||||
|
// cercle.addEventListener("wheel", function(e) {
|
||||||
|
// rayon=rayon + (e.deltaY>0 ? -1 : +1);
|
||||||
|
// cercle.setAttribute("r",rayon );
|
||||||
|
// } , false);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cercle.style.visibility="hidden";
|
||||||
|
if (nb_pers!=0) {can_etiq[ibac].style.backgroundColor = "oldlace";}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function afficher_formulaire(e) {
|
||||||
|
var formul=document.getElementById('ajout')
|
||||||
|
souris_x = position_souris(ima_fond, e).x ;
|
||||||
|
souris_y = position_souris(ima_fond, e).y;
|
||||||
|
if (souris_y-document.getElementById('ajout').height<0) {sourisy=50};
|
||||||
|
formul.style.top=souris_y+40+"px";
|
||||||
|
formul.style.left=souris_x-80+"px";
|
||||||
|
setTimeout(function () { document.getElementById("nom").focus(); },10);
|
||||||
|
formul.className='visible';
|
||||||
|
|
||||||
|
// document.getElementById('ajout_personne').reset(); // ne fonctioone pas !
|
||||||
|
if (mode_saisie) {
|
||||||
|
document.getElementById('nom').setAttribute('value', "");
|
||||||
|
document.getElementById('nom_jeune_fille').setAttribute('value', "");
|
||||||
|
document.getElementById('prenom').setAttribute('value', "");
|
||||||
|
document.getElementById('annee').setAttribute('value', "");
|
||||||
|
document.getElementById('note').setAttribute('value', "");
|
||||||
|
}
|
||||||
|
mode_saisie="true";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function misajour_xml(){
|
||||||
|
tit.setAttribute("titx",cant.style.left);
|
||||||
|
tit.setAttribute("tity",cant.style.top);
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
position=data_xml.getElementsByTagName( "position")[i];
|
||||||
|
position.setAttribute("etx",can_etiq[i].style.left);
|
||||||
|
position.setAttribute("ety",can_etiq[i].style.top);
|
||||||
|
};
|
||||||
|
lecture_xml();
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
function enregistrer_fichier(fichier) {
|
||||||
|
misajour_xml()
|
||||||
|
var texte_xml=(new XMLSerializer()).serializeToString(data_xml)
|
||||||
|
texte_xml=formatXml(texte_xml)
|
||||||
|
var blob = new Blob([texte_xml], {type: "text/plain;charset=utf-8"});
|
||||||
|
if (navigator.msSaveBlob) {
|
||||||
|
navigator.msSaveBlob(blob, fichier);
|
||||||
|
} else {
|
||||||
|
var a = document.createElement('a');
|
||||||
|
if (a.download === '');
|
||||||
|
a.setAttribute('download', fichier);
|
||||||
|
a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(texte_xml));
|
||||||
|
a.style.display = 'none';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatXml(xml, tab) { // tab = optional indent value, default is tab (\t)
|
||||||
|
var formatted = '', indent= '';
|
||||||
|
tab = tab || '\t';
|
||||||
|
xml.split(/>\s*</).forEach(function(node) {
|
||||||
|
if (node.match( /^\/\w/ )) indent = indent.substring(tab.length); // decrease indent by one 'tab'
|
||||||
|
formatted += indent + '<' + node + '>\r\n';
|
||||||
|
if (node.match( /^<?\w[^>]*[^\/]$/ )) indent += tab; // increase indent
|
||||||
|
});
|
||||||
|
return formatted.substring(1, formatted.length-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function image_finale() {
|
||||||
|
misajour_xml()
|
||||||
|
var decalx=5;
|
||||||
|
var decaly=29;
|
||||||
|
var can_imf = document.createElement("canvas");
|
||||||
|
document.body.appendChild(can_imf);
|
||||||
|
imf_ctx = can_imf.getContext("2d");
|
||||||
|
can_imf.width=ima_fond.width;
|
||||||
|
can_imf.height=ima_fond.height;
|
||||||
|
imf_ctx.drawImage(ima_fond,0,0)
|
||||||
|
if (titre!=='') {
|
||||||
|
var taille=titre.length;
|
||||||
|
hauteur=25
|
||||||
|
roundedRect(imf_ctx,tx-decalx,ty-decaly,taille*11,hauteur,5,'lightyellow','yellow');
|
||||||
|
imf_ctx.drawImage(cant, tx-decalx, ty-decaly)
|
||||||
|
};
|
||||||
|
for (var i = 0; i < nb_pers; i++) {
|
||||||
|
var taille=Math.max(nom[i].length,prenom[i].length,nomjf[i].length+5);
|
||||||
|
hauteur=30
|
||||||
|
if (nomjf[i].replace(/\t/g, '').length>1) {hauteur=45};
|
||||||
|
// if (!nomjf[i].charCodeAt(1)==9) {hauteur=45};
|
||||||
|
roundedRect(imf_ctx,etx[i]-decalx,ety[i]-decaly,taille*7+10,hauteur,15,'oldlace','blue');
|
||||||
|
imf_ctx.drawImage(can_etiq[i],etx[i]-decalx,ety[i]-decaly)
|
||||||
|
}
|
||||||
|
var a = document.createElement('a');
|
||||||
|
if (a.download === '');
|
||||||
|
a.setAttribute('download', enreg_noms);
|
||||||
|
a.setAttribute('href', can_imf.toDataURL("image/png").replace("image/png", "image/octet-stream"));
|
||||||
|
a.style.display = 'none';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
document.body.removeChild(can_imf);
|
||||||
|
|
||||||
|
function roundedRect(ctx, x, y, width, height, radius ,couleur_fond ,couleur_trait) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.strokeStyle = couleur_trait;
|
||||||
|
ctx.moveTo(x, y + radius);
|
||||||
|
ctx.lineTo(x, y + height - radius);
|
||||||
|
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
|
||||||
|
ctx.lineTo(x + width - radius, y + height);
|
||||||
|
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
|
||||||
|
ctx.lineTo(x + width, y + radius);
|
||||||
|
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
|
||||||
|
ctx.lineTo(x + radius, y);
|
||||||
|
ctx.quadraticCurveTo(x, y, x, y + radius);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = couleur_fond;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onOpenCvReady() {
|
||||||
|
document.getElementById('status').innerHTML = 'OpenCV.js est chargé !';
|
||||||
|
}
|
570
photo_mem.html
570
photo_mem.html
@ -9,537 +9,65 @@ Licence AGPL v3.0+
|
|||||||
ajout fonction modification des personnes
|
ajout fonction modification des personnes
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
<title>Photo mem</title>
|
||||||
|
|
||||||
<style>
|
</head>
|
||||||
circle {
|
|
||||||
fill: transparent;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 2;
|
|
||||||
}
|
|
||||||
#bouton_image {background-color:blue;color:white;height: 30px;}
|
|
||||||
#menu_modif {
|
|
||||||
display: block;
|
|
||||||
color: black;
|
|
||||||
background-color: gainsboro;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 2px solid;
|
|
||||||
border-radius: 6px;
|
|
||||||
text-align: center;
|
|
||||||
position: absolute;
|
|
||||||
width: 80px;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
#ajout {
|
|
||||||
border:2px solid red;
|
|
||||||
border-radius: 10px;
|
|
||||||
top: 100px;
|
|
||||||
left: 200px;
|
|
||||||
padding-top: 0.5em;
|
|
||||||
padding-bottom: 0.5em;
|
|
||||||
padding-left: 1em;
|
|
||||||
background-color: Azure;
|
|
||||||
width: 230px;
|
|
||||||
}
|
|
||||||
#ajout input:focus {border: solid 2px green;}
|
|
||||||
.cotecote {display: inline;}
|
|
||||||
.visible { visibility:visible; }
|
|
||||||
.invisible { visibility:hidden; }
|
|
||||||
.etiq {
|
|
||||||
background-color:oldlace;
|
|
||||||
border:1px solid blue;
|
|
||||||
border-radius: 10px;
|
|
||||||
position:absolute;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 13px;
|
|
||||||
left:-200px;
|
|
||||||
top: 100px;
|
|
||||||
}
|
|
||||||
.tit {
|
|
||||||
background-color:LightYellow;
|
|
||||||
border: 2px solid Yellow;
|
|
||||||
border-radius: 5px;
|
|
||||||
position:absolute;
|
|
||||||
left:-200px;
|
|
||||||
top: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<input id="fichiers" multiple type="file" class=cotecote style="display:none"/>
|
<link rel="stylesheet" type="text/css" href="/style_photomem.css"></link>
|
||||||
<button id="bouton_image" onclick="fichiers.click()" title="Charger une image et le XML associé" >Choix de la photo</button>
|
<header>
|
||||||
<input id="file" type="button" class=cotecote value="Enregistrer xml" onclick="enregistrer_fichier(enreg_xml)"/>
|
<h1>Photo Mem</h1>
|
||||||
<input id="file" type="button" class=cotecote value="Enregistrer image " onclick="image_finale()"/>
|
</header>
|
||||||
<p id="status" class=cotecote >OpenCV.js chargement en cours...</p>
|
<main>
|
||||||
|
<div id="actions">
|
||||||
|
|
||||||
<div style="position: relative; ">
|
<input id="fichiers" multiple type="file" class="cotecote" style="display:none"/>
|
||||||
<img src="" id="ima_fond" style="position: absolute; left: 0; top: 0; z-index: 0;">
|
<button id="bouton_image" onclick="fichiers.click()" title="Charger une image et le XML associé">Choix de la
|
||||||
</div>
|
photo
|
||||||
|
</button>
|
||||||
|
<input id="save_file" type="button" class=cotecote value="Enregistrer xml"
|
||||||
|
onclick="enregistrer_fichier(enreg_xml)"/>
|
||||||
|
<input id="file" type="button" class=cotecote value="Enregistrer image " onclick="image_finale()"/>
|
||||||
|
<p id="status" class=cotecote>OpenCV.js chargement en cours...</p>
|
||||||
|
</div>
|
||||||
|
<div style="position: relative; ">
|
||||||
|
<img src="" id="ima_fond" style="position: absolute; left: 0; top: 0; z-index: 0;">
|
||||||
|
</div>
|
||||||
|
|
||||||
<svg class="invisible" style="position: absolute" ;>
|
<svg class="invisible" style="position: absolute" ;>
|
||||||
<circle id="cirsvg" cx="30" cy="30" r="28" />
|
<circle id="cirsvg" cx="30" cy="30" r="28"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div id="ajout" class="invisible" style="position: relative; z-index: 1;">
|
<div id="ajout" class="invisible" style="position: relative; z-index: 1;">
|
||||||
<form name="ajout_personne" id="ajout_personne">
|
<form name="ajout_personne" id="ajout_personne">
|
||||||
<center><font color="green">NOUVELLE PERSONNE</font></center>
|
<h2 class="title is-2">
|
||||||
|
NOUVELLE PERSONNE
|
||||||
|
</h2>
|
||||||
|
Nom : <input type="text" name="nom" id="nom" autofocus><BR>
|
||||||
|
Née : <input type="text" name="nom_jf" id="nom_jeune_fille"><BR>
|
||||||
|
Prénom : <input type="text" name="prénom" id="prenom"><BR>
|
||||||
|
Année : <input type="text" name="année" id="annee"><BR>
|
||||||
|
Note : <input type="text" name="note" id="note"><BR>
|
||||||
|
Titre photo : <input type="text" name="titre" id="titre"><BR>
|
||||||
|
|
||||||
Nom : <INPUT type="text" name="nom" id="nom" autofocus><BR>
|
<input type="reset" id="enreg" value="Ajouter"
|
||||||
Née : <INPUT type="text" name="nom_jf" id="nom_jeune_fille"><BR>
|
onClick=ajouter_personne_xml("",souris_x,souris_y,"","");lecture_xml();>
|
||||||
Prénom : <INPUT type="text" name="prénom" id="prenom"><BR>
|
<input type="reset" value="Annuler" onClick=document.getElementById("ajout").className="invisible";>
|
||||||
Année : <INPUT type="text" name="année" id="annee"><BR>
|
</form>
|
||||||
Note : <INPUT type="text" name="note" id="note"><BR>
|
</div>
|
||||||
Titre photo : <INPUT type="text" name="titre" id="titre"><BR>
|
<div id="menu_modif" class="invisible">
|
||||||
|
<div id="modifier" onClick="modifier_personne();">modifier</div>
|
||||||
<INPUT type="reset" id="enreg" value="Ajouter" onClick=ajouter_personne_xml("",souris_x,souris_y,"","");lecture_xml();>
|
|
||||||
<INPUT type="reset" value="Annuler" onClick=document.getElementById("ajout").className="invisible";>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div id="menu_modif" class="invisible">
|
|
||||||
<div id="modifier" onClick="modifier_personne();">modifier </div>
|
|
||||||
<div id="supprimer" onClick="supprimer_personne();menu.style.visibility='hidden';">supprimer</div>
|
<div id="supprimer" onClick="supprimer_personne();menu.style.visibility='hidden';">supprimer</div>
|
||||||
<div id="annuler" onClick="menu.style.visibility='hidden';">annuler</div>
|
<div id="annuler" onClick="menu.style.visibility='hidden';">annuler</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var personnes=[],nom=[],nomjf=[],prenom=[],annee=[],note=[],posx=[],posy=[],etx=[],ety=[], can_etiq=[];
|
|
||||||
var ibac=0, tit={}, titre="", fond=[];
|
|
||||||
var mode_saisie="true" // mode saisie true, mode modification false
|
|
||||||
var image = document.getElementById('ima_fond');
|
|
||||||
var cercle = document.getElementById("cirsvg");
|
|
||||||
var menu = document.getElementById("menu_modif");
|
|
||||||
var modif_titre = document.getElementById("nouveau_titre");
|
|
||||||
var cant = document.createElement("canvas");
|
|
||||||
document.body.appendChild(cant);
|
|
||||||
|
|
||||||
let inputElement = document.getElementById('fichiers');
|
|
||||||
inputElement.addEventListener('change', (e) => {
|
|
||||||
lecfic(e.target.files)
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
function lecfic(fichier) {
|
|
||||||
nb_fichier=fichier.length
|
|
||||||
var i_xml=1, i_img=0;
|
|
||||||
if (fichier[0].name.split('.').pop()=="xml") {i_xml=0; i_img=1};
|
|
||||||
var src=fichier[i_img].name.substring(0,fichier[i_img].name.indexOf("."));
|
|
||||||
enreg_xml=src+".xml"
|
|
||||||
enreg_noms=src+"_noms.png"
|
|
||||||
fichier_xml=fichier[i_xml];
|
|
||||||
fond=fichier[i_img];
|
|
||||||
affiche_fond();
|
|
||||||
|
|
||||||
if (nb_fichier==1) {creation_data_xml(); lecture_xml(); return} // Un seul fichier sélectionné : l'image à traiter
|
|
||||||
|
|
||||||
if (fichier_xml.name.startsWith("haar")) {creation_data_xml(); detection_de_visages();return} // deux fichiers selectionnés : l'image et haarcascade.xml
|
|
||||||
|
|
||||||
// deux fichiers selectionnés : l'image et le xml du même nom
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onload = function(evt) {lecture(evt.target.result);};
|
|
||||||
reader.readAsText(fichier_xml);
|
|
||||||
|
|
||||||
function lecture(text) {
|
|
||||||
var parser = new DOMParser();
|
|
||||||
data_xml = parser.parseFromString(text,"text/xml");
|
|
||||||
lecture_xml();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chargement et affichage de l'image background
|
|
||||||
function affiche_fond() {
|
|
||||||
var read_fond = new FileReader();
|
|
||||||
read_fond.addEventListener("load", function (evt) {
|
|
||||||
image.src = evt.target.result;
|
|
||||||
}, false);
|
|
||||||
read_fond.readAsDataURL(fond);
|
|
||||||
}
|
|
||||||
|
|
||||||
function lecture_xml() {
|
|
||||||
tit = data_xml.documentElement.getElementsByTagName("titre")[0];
|
|
||||||
titre=tit.textContent
|
|
||||||
personnes = data_xml.documentElement.getElementsByTagName("personne");
|
|
||||||
nb_pers=personnes.length
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
nom[i] = personnes[i].getElementsByTagName( "nom")[0].textContent;
|
|
||||||
if (personnes[i].getElementsByTagName( "nom_jeune_fille")[0]) {
|
|
||||||
nomjf[i] = personnes[i].getElementsByTagName( "nom_jeune_fille")[0].textContent;
|
|
||||||
}
|
|
||||||
prenom[i] = personnes[i].getElementsByTagName( "prenom")[0].textContent;
|
|
||||||
annee[i] = personnes[i].getElementsByTagName( "annee_naiss")[0].textContent;
|
|
||||||
note[i] = personnes[i].getElementsByTagName( "note")[0].textContent;
|
|
||||||
posx[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['posx'].value);
|
|
||||||
posy[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['posy'].value);
|
|
||||||
etx[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['etx'].value);
|
|
||||||
ety[i] = parseFloat(personnes[i].getElementsByTagName( "position")[0].attributes['ety'].value);
|
|
||||||
}
|
|
||||||
if (titre!=='') {affiche_titre(titre)}
|
|
||||||
affiche_etiquette() ;
|
|
||||||
};
|
|
||||||
|
|
||||||
function affiche_titre(titre_photo) {
|
|
||||||
cant.className="tit";
|
|
||||||
cant.height=23;
|
|
||||||
var taille=titre_photo.length;
|
|
||||||
cant.width=taille*12;
|
|
||||||
tx = parseFloat(tit.attributes['titx'].value);
|
|
||||||
ty = parseFloat(tit.attributes['tity'].value);
|
|
||||||
cant.style.left = tx + "px";
|
|
||||||
cant.style.top = ty + "px";
|
|
||||||
titre_ctx = cant.getContext("2d");
|
|
||||||
titre_ctx.font = '21px Arial';
|
|
||||||
titre_ctx.fillStyle = 'Maroon';
|
|
||||||
titre_ctx.fillText(titre_photo, 20, 18);
|
|
||||||
affiche_etiquette() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
function affiche_etiquette() {
|
|
||||||
// affichage du texte nom/prénom dans des canvas etiquette
|
|
||||||
rayon=28
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
var id="can"+i;
|
|
||||||
if (document.getElementById(id)) continue ;
|
|
||||||
var canv = document.createElement("canvas");
|
|
||||||
canv.id=id;
|
|
||||||
document.body.appendChild(canv);
|
|
||||||
can_etiq[i] = document.getElementById(canv.id);
|
|
||||||
can_etiq[i].className="etiq";
|
|
||||||
can_etiq[i].height=30;
|
|
||||||
etiq_ctx = can_etiq[i].getContext("2d");
|
|
||||||
var taille=Math.max(nom[i].length,prenom[i].length,nomjf[i].length+5);
|
|
||||||
can_etiq[i].width=taille*7+10
|
|
||||||
if (nomjf[i].replace(/\t/g, '').length>1) {can_etiq[i].height=45};
|
|
||||||
etiq_ctx.font = '13px Arial';
|
|
||||||
etiq_ctx.fillStyle = 'chocolate';
|
|
||||||
can_etiq[i].style.left = etx[i] + "px";
|
|
||||||
can_etiq[i].style.top = ety[i] + "px";
|
|
||||||
etiq_ctx.fillText(nom[i], 7, 12);
|
|
||||||
etiq_ctx.fillText(prenom[i], 7, 25);
|
|
||||||
if (nomjf[i].length>1) {etiq_ctx.fillText("née : "+nomjf[i], 7, 38)};
|
|
||||||
};
|
|
||||||
gestion_souris();
|
|
||||||
};
|
|
||||||
|
|
||||||
function gestion_souris() {
|
|
||||||
if (titre!=='') { // pour déplacer le titre
|
|
||||||
cant.addEventListener("mousedown", function(e){this.addEventListener("mousemove", deplace_etiquette);});
|
|
||||||
cant.addEventListener("mouseup", function(e){this.removeEventListener("mousemove", deplace_etiquette);});
|
|
||||||
}
|
|
||||||
for (var i = 0; i < nb_pers; i++) { // pour déplacer les étiquettes nom,prénom ...
|
|
||||||
can_etiq[i].addEventListener("mousedown", function(e){this.addEventListener("mousemove", deplace_etiquette);});
|
|
||||||
can_etiq[i].addEventListener("mouseup", function(e){this.removeEventListener("mousemove", deplace_etiquette);});
|
|
||||||
};
|
|
||||||
ima_fond.addEventListener('mousedown', afficher_formulaire); // pour afficher le formulaire de saisie personne
|
|
||||||
ima_fond.addEventListener('mousemove', tracer_cercle); // pour afficher cercle personne
|
|
||||||
cercle.addEventListener('contextmenu', function (e) { menu_modif(e); e.preventDefault();}, false); // menu modif personne
|
|
||||||
};
|
|
||||||
|
|
||||||
function deplace_etiquette(e){
|
|
||||||
e.target.style.top = e.pageY-15+"px";
|
|
||||||
e.target.style.left = e.pageX-30+"px";
|
|
||||||
};
|
|
||||||
|
|
||||||
function menu_modif(){
|
|
||||||
menu.style.left = parseFloat(cercle.getAttribute("cx"))+10 +"px";
|
|
||||||
menu.style.top = parseFloat(cercle.getAttribute("cy"))+40 +"px";
|
|
||||||
menu.style.visibility="visible";
|
|
||||||
}
|
|
||||||
|
|
||||||
function supprimer_personne() {
|
|
||||||
misajour_xml();
|
|
||||||
x = data_xml.getElementsByTagName("personne")[ibac];
|
|
||||||
x.parentNode.removeChild(x);
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
x = can_etiq[i];
|
|
||||||
x.parentNode.removeChild(x);
|
|
||||||
};
|
|
||||||
cercle.style.visibility="hidden";
|
|
||||||
lecture_xml();
|
|
||||||
}
|
|
||||||
function creation_data_xml() {
|
|
||||||
var x, i;
|
|
||||||
var txt = "";
|
|
||||||
var text = "<photo>" +
|
|
||||||
"<titre titx='50px' tity='50px'>Titre "+ fond.name + "</titre>" +
|
|
||||||
"<date> </date>" +
|
|
||||||
"<lieu> </lieu>" +
|
|
||||||
"<commentaire> </commentaire>" +
|
|
||||||
"</photo>";
|
|
||||||
|
|
||||||
var parser_face = new DOMParser();
|
|
||||||
data_xml = parser_face.parseFromString(text,"text/xml");
|
|
||||||
// documentElement always represents the root node
|
|
||||||
x = data_xml.documentElement.childNodes;
|
|
||||||
for (i = 0; i < x.length ;i++) {
|
|
||||||
txt += x[i].nodeName + ": " + x[i].childNodes[0].nodeValue + "<br>";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function detection_de_visages() {
|
|
||||||
// alert pour temporiser
|
|
||||||
alert("Ok pour continuer")
|
|
||||||
src = cv.imread(ima_fond);
|
|
||||||
gray = new cv.Mat();
|
|
||||||
cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
|
|
||||||
chargement_haarcascade();
|
|
||||||
}
|
|
||||||
function chargement_haarcascade() {
|
|
||||||
var reader_haar = new FileReader();
|
|
||||||
reader_haar.onload = function(ev) {
|
|
||||||
function str2ab(text) {
|
|
||||||
return new TextEncoder().encode(text);
|
|
||||||
}
|
|
||||||
faceCascadeFile = fichier_xml.name;
|
|
||||||
let data=str2ab(reader_haar.result)
|
|
||||||
cv.FS_createDataFile('/', faceCascadeFile, data, true, false, false);
|
|
||||||
detect_faces();
|
|
||||||
};
|
|
||||||
reader_haar.readAsText(fichier_xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
function detect_faces() {
|
|
||||||
|
|
||||||
let faces = new cv.RectVector();
|
|
||||||
let faceCascade = new cv.CascadeClassifier();
|
|
||||||
// load pre-trained classifiers
|
|
||||||
faceCascade.load(faceCascadeFile);
|
|
||||||
// detect faces
|
|
||||||
let msize = new cv.Size(0, 0);
|
|
||||||
faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, msize, msize);
|
|
||||||
console.log("Il y a "+ faces.size()+" visage(s)")
|
|
||||||
for (let i = 0; i < faces.size(); ++i) {
|
|
||||||
ajouter_personne_xml("nom_"+parseInt(i)+" ",faces.get(i).x,faces.get(i).y,faces.get(i).width,faces.get(i).height)
|
|
||||||
}
|
|
||||||
// cv.imshow('ima_fond', src);
|
|
||||||
src.delete(); gray.delete(); faceCascade.delete();
|
|
||||||
faces.delete();
|
|
||||||
lecture_xml();
|
|
||||||
|
|
||||||
;}
|
|
||||||
function ajouter_personne_xml(nom_face,fx,fy,fw,fh) {
|
|
||||||
var nomform=nom_face
|
|
||||||
var nomjfform=""
|
|
||||||
var prenomform=""
|
|
||||||
var anneeform=""
|
|
||||||
var noteform=""
|
|
||||||
var posxx=fx+fw/2
|
|
||||||
var posyy=fy+fh/2
|
|
||||||
var etxx=fx+10
|
|
||||||
var etyy=fy+fh*2
|
|
||||||
document.getElementById('ajout').className='invisible';
|
|
||||||
|
|
||||||
if (!nom_face) {
|
|
||||||
posxx=fx
|
|
||||||
posyy=fy
|
|
||||||
etxx=fx-30
|
|
||||||
etyy=fy+80
|
|
||||||
nomform=document.getElementById("nom").value
|
|
||||||
nomjfform=document.getElementById("nom_jeune_fille").value
|
|
||||||
prenomform=document.getElementById("prenom").value
|
|
||||||
anneeform=document.getElementById("annee").value
|
|
||||||
noteform=document.getElementById("note").value
|
|
||||||
}
|
|
||||||
// création d'un nouvel élément <personne> dans data_xml
|
|
||||||
var personne_ = data_xml.createElement("personne");
|
|
||||||
var nom_ = data_xml.createElement("nom");
|
|
||||||
nom_.appendChild(data_xml.createTextNode(nomform));
|
|
||||||
var nom_jf_ = data_xml.createElement("nom_jeune_fille");
|
|
||||||
nom_jf_.appendChild(data_xml.createTextNode(nomjfform));
|
|
||||||
var prenom_ = data_xml.createElement("prenom");
|
|
||||||
prenom_.appendChild(data_xml.createTextNode(prenomform));
|
|
||||||
var annee_ = data_xml.createElement("annee_naiss");
|
|
||||||
annee_.appendChild(data_xml.createTextNode(anneeform));
|
|
||||||
var note_ = data_xml.createElement("note");
|
|
||||||
note_.appendChild(data_xml.createTextNode(noteform));
|
|
||||||
var position_ = data_xml.createElement("position");
|
|
||||||
position_.setAttribute("posx", posxx);
|
|
||||||
position_.setAttribute("posy", posyy);
|
|
||||||
position_.setAttribute("etx", etxx);
|
|
||||||
position_.setAttribute("ety", etyy);
|
|
||||||
personne_.appendChild(nom_);
|
|
||||||
personne_.appendChild(nom_jf_);
|
|
||||||
personne_.appendChild(prenom_);
|
|
||||||
personne_.appendChild(annee_);
|
|
||||||
personne_.appendChild(note_);
|
|
||||||
personne_.appendChild(position_);
|
|
||||||
data_xml.getElementsByTagName("photo")[0].appendChild(personne_)
|
|
||||||
};
|
|
||||||
|
|
||||||
function modifier_personne() {
|
|
||||||
mode_saisie="false";
|
|
||||||
afficher_formulaire(this);
|
|
||||||
document.getElementById('nom').setAttribute('value', nom[ibac]);
|
|
||||||
document.getElementById('nom_jeune_fille').setAttribute('value', nomjf[ibac]);
|
|
||||||
document.getElementById('prenom').setAttribute('value', prenom[ibac]);
|
|
||||||
document.getElementById('annee').setAttribute('value', annee[ibac]);
|
|
||||||
document.getElementById('note').setAttribute('value', note[ibac]);
|
|
||||||
document.getElementById('titre').setAttribute('value', titre);
|
|
||||||
menu.style.visibility='hidden';
|
|
||||||
document.getElementById("enreg").style.visibility="hidden";
|
|
||||||
alert("Fonction en cours de développement")
|
|
||||||
};
|
|
||||||
|
|
||||||
function position_souris(canvas, evt) {
|
|
||||||
var rect = canvas.getBoundingClientRect();
|
|
||||||
return {
|
|
||||||
x: evt.clientX - rect.left,
|
|
||||||
y: evt.clientY - rect.top
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function tracer_cercle(e) {
|
|
||||||
document.getElementsByTagName("svg")[0].setAttribute('height', image.naturalHeight);
|
|
||||||
document.getElementsByTagName("svg")[0].setAttribute('width',image.naturalWidth);
|
|
||||||
var pos_x=position_souris(ima_fond, e).x;
|
|
||||||
var pos_y=position_souris(ima_fond, e).y;
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
var dx = posx[i] - pos_x;
|
|
||||||
var dy = posy[i] - pos_y;
|
|
||||||
var dist2 = dx * dx + dy * dy;
|
|
||||||
var rayon2 = rayon * rayon;
|
|
||||||
|
|
||||||
if (dist2 < rayon2) {
|
|
||||||
ibac=i
|
|
||||||
can_etiq[i].style.background = "palegreen"
|
|
||||||
cercle.setAttribute("cx",posx[i]);
|
|
||||||
cercle.setAttribute("cy",posy[i]);
|
|
||||||
cercle.setAttribute("r",rayon);
|
|
||||||
cercle.style.visibility="visible";
|
|
||||||
// grossir ou diminuer la taille du cercle
|
|
||||||
// cercle.addEventListener("wheel", function(e) {
|
|
||||||
// rayon=rayon + (e.deltaY>0 ? -1 : +1);
|
|
||||||
// cercle.setAttribute("r",rayon );
|
|
||||||
// } , false);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cercle.style.visibility="hidden";
|
|
||||||
if (nb_pers!=0) {can_etiq[ibac].style.backgroundColor = "oldlace";}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function afficher_formulaire(e) {
|
</main>
|
||||||
var formul=document.getElementById('ajout')
|
<footer>
|
||||||
souris_x = position_souris(ima_fond, e).x ;
|
|
||||||
souris_y = position_souris(ima_fond, e).y;
|
|
||||||
if (souris_y-document.getElementById('ajout').height<0) {sourisy=50};
|
|
||||||
formul.style.top=souris_y+40+"px";
|
|
||||||
formul.style.left=souris_x-80+"px";
|
|
||||||
setTimeout(function () { document.getElementById("nom").focus(); },10);
|
|
||||||
formul.className='visible';
|
|
||||||
|
|
||||||
// document.getElementById('ajout_personne').reset(); // ne fonctioone pas !
|
</footer>
|
||||||
if (mode_saisie) {
|
<script type="application/javascript" src="main.js"></script>
|
||||||
document.getElementById('nom').setAttribute('value', "");
|
<script src="opencv.js" onload="onOpenCvReady();" type="text/javascript"></script>
|
||||||
document.getElementById('nom_jeune_fille').setAttribute('value', "");
|
</body>
|
||||||
document.getElementById('prenom').setAttribute('value', "");
|
|
||||||
document.getElementById('annee').setAttribute('value', "");
|
|
||||||
document.getElementById('note').setAttribute('value', "");
|
|
||||||
}
|
|
||||||
mode_saisie="true";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function misajour_xml(){
|
|
||||||
tit.setAttribute("titx",cant.style.left);
|
|
||||||
tit.setAttribute("tity",cant.style.top);
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
position=data_xml.getElementsByTagName( "position")[i];
|
|
||||||
position.setAttribute("etx",can_etiq[i].style.left);
|
|
||||||
position.setAttribute("ety",can_etiq[i].style.top);
|
|
||||||
};
|
|
||||||
lecture_xml();
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
function enregistrer_fichier(fichier) {
|
|
||||||
misajour_xml()
|
|
||||||
var texte_xml=(new XMLSerializer()).serializeToString(data_xml)
|
|
||||||
texte_xml=formatXml(texte_xml)
|
|
||||||
var blob = new Blob([texte_xml], {type: "text/plain;charset=utf-8"});
|
|
||||||
if (navigator.msSaveBlob) {
|
|
||||||
navigator.msSaveBlob(blob, fichier);
|
|
||||||
} else {
|
|
||||||
var a = document.createElement('a');
|
|
||||||
if (a.download === '');
|
|
||||||
a.setAttribute('download', fichier);
|
|
||||||
a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(texte_xml));
|
|
||||||
a.style.display = 'none';
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
document.body.removeChild(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatXml(xml, tab) { // tab = optional indent value, default is tab (\t)
|
|
||||||
var formatted = '', indent= '';
|
|
||||||
tab = tab || '\t';
|
|
||||||
xml.split(/>\s*</).forEach(function(node) {
|
|
||||||
if (node.match( /^\/\w/ )) indent = indent.substring(tab.length); // decrease indent by one 'tab'
|
|
||||||
formatted += indent + '<' + node + '>\r\n';
|
|
||||||
if (node.match( /^<?\w[^>]*[^\/]$/ )) indent += tab; // increase indent
|
|
||||||
});
|
|
||||||
return formatted.substring(1, formatted.length-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
function image_finale() {
|
|
||||||
misajour_xml()
|
|
||||||
var decalx=5;
|
|
||||||
var decaly=29;
|
|
||||||
var can_imf = document.createElement("canvas");
|
|
||||||
document.body.appendChild(can_imf);
|
|
||||||
imf_ctx = can_imf.getContext("2d");
|
|
||||||
can_imf.width=ima_fond.width;
|
|
||||||
can_imf.height=ima_fond.height;
|
|
||||||
imf_ctx.drawImage(ima_fond,0,0)
|
|
||||||
if (titre!=='') {
|
|
||||||
var taille=titre.length;
|
|
||||||
hauteur=25
|
|
||||||
roundedRect(imf_ctx,tx-decalx,ty-decaly,taille*11,hauteur,5,'lightyellow','yellow');
|
|
||||||
imf_ctx.drawImage(cant, tx-decalx, ty-decaly)
|
|
||||||
};
|
|
||||||
for (var i = 0; i < nb_pers; i++) {
|
|
||||||
var taille=Math.max(nom[i].length,prenom[i].length,nomjf[i].length+5);
|
|
||||||
hauteur=30
|
|
||||||
if (nomjf[i].replace(/\t/g, '').length>1) {hauteur=45};
|
|
||||||
// if (!nomjf[i].charCodeAt(1)==9) {hauteur=45};
|
|
||||||
roundedRect(imf_ctx,etx[i]-decalx,ety[i]-decaly,taille*7+10,hauteur,15,'oldlace','blue');
|
|
||||||
imf_ctx.drawImage(can_etiq[i],etx[i]-decalx,ety[i]-decaly)
|
|
||||||
}
|
|
||||||
var a = document.createElement('a');
|
|
||||||
if (a.download === '');
|
|
||||||
a.setAttribute('download', enreg_noms);
|
|
||||||
a.setAttribute('href', can_imf.toDataURL("image/png").replace("image/png", "image/octet-stream"));
|
|
||||||
a.style.display = 'none';
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
document.body.removeChild(a);
|
|
||||||
document.body.removeChild(can_imf);
|
|
||||||
|
|
||||||
function roundedRect(ctx, x, y, width, height, radius ,couleur_fond ,couleur_trait) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = couleur_trait;
|
|
||||||
ctx.moveTo(x, y + radius);
|
|
||||||
ctx.lineTo(x, y + height - radius);
|
|
||||||
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
|
|
||||||
ctx.lineTo(x + width - radius, y + height);
|
|
||||||
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
|
|
||||||
ctx.lineTo(x + width, y + radius);
|
|
||||||
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
|
|
||||||
ctx.lineTo(x + radius, y);
|
|
||||||
ctx.quadraticCurveTo(x, y, x, y + radius);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.fillStyle = couleur_fond;
|
|
||||||
ctx.fill();
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
function onOpenCvReady() {
|
|
||||||
document.getElementById('status').innerHTML = 'OpenCV.js est chargé !';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="opencv.js" onload="onOpenCvReady();" type="text/javascript"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
87
style_photomem.css
Normal file
87
style_photomem.css
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
body{
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
circle {
|
||||||
|
fill: transparent;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bouton_image {
|
||||||
|
background-color: blue;
|
||||||
|
color: white;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu_modif {
|
||||||
|
display: block;
|
||||||
|
color: black;
|
||||||
|
background-color: gainsboro;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
width: 80px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ajout {
|
||||||
|
border: 2px solid red;
|
||||||
|
border-radius: 10px;
|
||||||
|
top: 100px;
|
||||||
|
left: 200px;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
padding-left: 1em;
|
||||||
|
background-color: Azure;
|
||||||
|
width: 230px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ajout input:focus {
|
||||||
|
border: solid 2px green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cotecote {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visible {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.etiq {
|
||||||
|
background-color: oldlace;
|
||||||
|
border: 1px solid blue;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: absolute;
|
||||||
|
font-family: Arial;
|
||||||
|
font-size: 13px;
|
||||||
|
left: -200px;
|
||||||
|
top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tit {
|
||||||
|
background-color: LightYellow;
|
||||||
|
border: 2px solid Yellow;
|
||||||
|
border-radius: 5px;
|
||||||
|
position: absolute;
|
||||||
|
left: -200px;
|
||||||
|
top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#actions button, #actions input {
|
||||||
|
background: cadetblue;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 1em 2em;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user