Add fixed aspect ratio and image scaling on download
This commit is contained in:
parent
272fb59545
commit
1bed329472
11
index.html
11
index.html
@ -39,10 +39,13 @@
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Capture a photo from your webcam and save it using the student number.</p>
|
||||
</header>
|
||||
|
||||
<div class="relative bg-black rounded-xl overflow-hidden aspect-video flex items-center justify-center">
|
||||
<video id="video" class="w-full h-full object-cover" autoplay playsinline muted></video>
|
||||
<img id="preview-img" class="hidden w-full h-full object-cover" alt="Captured student photo">
|
||||
<p id="camera-status" class="absolute text-gray-300 text-sm">Requesting camera access…</p>
|
||||
<div class="space-y-2">
|
||||
<div class="relative bg-black rounded-xl overflow-hidden aspect-[145/185] max-w-[280px] mx-auto flex items-center justify-center">
|
||||
<video id="video" class="w-full h-full object-cover" autoplay playsinline muted></video>
|
||||
<img id="preview-img" class="hidden w-full h-full object-cover" alt="Captured student photo">
|
||||
<p id="camera-status" class="absolute text-gray-300 text-sm px-4 text-center">Requesting camera access…</p>
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 dark:text-gray-500 text-center">Frame matches the final 145×185 photo — fill it with the student's face and shoulders.</p>
|
||||
</div>
|
||||
|
||||
<canvas id="canvas" class="hidden"></canvas>
|
||||
|
||||
27
js/app.js
27
js/app.js
@ -7,6 +7,10 @@ const inputError = document.getElementById('input-error');
|
||||
const captureBtn = document.getElementById('capture-btn');
|
||||
const downloadLink = document.getElementById('download-link');
|
||||
|
||||
const OUTPUT_WIDTH = 145;
|
||||
const OUTPUT_HEIGHT = 185;
|
||||
const TARGET_RATIO = OUTPUT_WIDTH / OUTPUT_HEIGHT;
|
||||
|
||||
let captured = false;
|
||||
|
||||
async function startCamera() {
|
||||
@ -53,10 +57,27 @@ function capturePhoto() {
|
||||
}
|
||||
inputError.classList.add('hidden');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
const videoWidth = video.videoWidth;
|
||||
const videoHeight = video.videoHeight;
|
||||
const videoRatio = videoWidth / videoHeight;
|
||||
|
||||
let sx, sy, sw, sh;
|
||||
if (videoRatio > TARGET_RATIO) {
|
||||
sh = videoHeight;
|
||||
sw = sh * TARGET_RATIO;
|
||||
sx = (videoWidth - sw) / 2;
|
||||
sy = 0;
|
||||
} else {
|
||||
sw = videoWidth;
|
||||
sh = sw / TARGET_RATIO;
|
||||
sx = 0;
|
||||
sy = (videoHeight - sh) / 2;
|
||||
}
|
||||
|
||||
canvas.width = OUTPUT_WIDTH;
|
||||
canvas.height = OUTPUT_HEIGHT;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(video, sx, sy, sw, sh, 0, 0, OUTPUT_WIDTH, OUTPUT_HEIGHT);
|
||||
|
||||
const dataUrl = canvas.toDataURL('image/png');
|
||||
const filename = `${sanitizeFilename(studentNumber)}.png`;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user