« Back to History
face-enroll.js
|
20260721_154032.php
Initial Bulk Import
Copy Code
// face-enroll.js document.addEventListener('DOMContentLoaded', async function(){ await loadFaceApiModels(); // default base /erp/models/face-api const video = document.getElementById('fc-enroll-video'); const captureBtn = document.getElementById('fc-enroll-capture'); const sendBtn = document.getElementById('fc-send-enroll'); const samplesWrap = document.getElementById('fc-samples'); let stream=null; const samples = []; // will store {blob, descriptor} async function startCamera(){ if(stream) return; try { stream = await navigator.mediaDevices.getUserMedia({video:{facingMode:'user'}, audio:false}); video.srcObject = stream; } catch(e) { alert('Camera access required.'); console.error(e); } } function stopCamera(){ if(!stream) return; stream.getTracks().forEach(t=>t.stop()); stream=null; video.srcObject=null; } captureBtn.addEventListener('click', async ()=>{ if(!stream) { await startCamera(); if(!stream) return; } // capture frame to canvas const canvas = document.createElement('canvas'); canvas.width = video.videoWidth || 640; canvas.height = video.videoHeight || 480; canvas.getContext('2d').drawImage(video,0,0,canvas.width,canvas.height); const blob = await new Promise(res=> canvas.toBlob(res,'image/jpeg',0.9)); // compute descriptor const descriptor = await getDescriptorFromImageBlob(blob); if(!descriptor){ alert('No face detected. Try again with better lighting.'); return; } samples.push({blob, descriptor}); // render thumbnail const img = document.createElement('img'); img.src = URL.createObjectURL(blob); img.style.width='120px'; img.style.margin='6px'; const div = document.createElement('div'); div.appendChild(img); const rem = document.createElement('button'); rem.textContent='Remove'; rem.className='btn'; rem.onclick=()=>{ samplesWrap.removeChild(div); samples.splice(samples.indexOf(obj),1); }; div.appendChild(rem); const obj = {div, blob, descriptor}; samplesWrap.appendChild(div); }); sendBtn.addEventListener('click', async ()=>{ const empSel = document.getElementById('enroll_employee_id'); const eid = empSel ? empSel.value : null; if(!eid) { alert('Select employee'); return; } if(samples.length < 1){ alert('Capture at least 1 sample (2-3 recommended)'); return; } // send descriptor arrays to server (we'll store them) const embeddings = samples.map(s => s.descriptor); try { const res = await fetch('/erp/api/attendance/enroll_embedding.php',{ method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ employee_id: parseInt(eid,10), embeddings }) }); const j = await res.json(); if(j && j.ok){ alert('Enrollment saved'); samples.length=0; samplesWrap.innerHTML=''; } else alert('Enroll failed: ' + (j.error || j.msg || 'unknown')); } catch(e){ console.error(e); alert('Network error'); } }); // auto-start startCamera(); });