TIF_NGANJUK_E41212268/templates/upload.html

131 lines
4.7 KiB
HTML

{% extends "base.html" %}
{% block title %}Ambil Gambar Tomat{% endblock %}
{% block content %}
<div class="container mt-5">
<div id="notif-container" class="mb-4">
{% if error %}
<div class="alert alert-danger text-center" role="alert">
{{ error }}
</div>
{% endif %}
</div>
<div class="text-center mb-4">
<h1 class="display-6">Ambil Gambar Tomat Anda</h1>
<p class="text-muted">Pastikan kamera Anda menghadap ke tomat yang akan diprediksi atau unggah gambar tomat dari perangkat Anda!</p>
</div>
<!-- Kamera -->
<div class="card shadow-sm mb-4">
<div class="card-body text-center">
<div id="camera-container" class="border rounded mb-3 mx-auto" style="width: 100%; max-width: 480px; aspect-ratio: 4 / 3; background-color: #f8f9fa;">
<video id="camera" autoplay muted playsinline style="width: 100%; height: 100%; object-fit: cover; border-radius: 8px;"></video>
</div>
<button id="capture" class="btn btn-primary w-100">Ambil Gambar</button>
</div>
</div>
<!-- Form Unggah Gambar -->
<div class="card shadow-sm">
<div class="card-body">
<form action="/upload" method="post" enctype="multipart/form-data" class="text-center">
<div class="form-group mb-3">
<label for="file" class="form-label">Pilih Gambar</label>
<input type="file" class="form-control" id="file" name="file">
</div>
<button type="submit" class="btn btn-secondary w-100">Unggah Gambar</button>
</form>
</div>
</div>
</div>
<script>
// Akses kamera
const video = document.getElementById('camera');
const captureButton = document.getElementById('capture');
const notifContainer = document.getElementById('notif-container');
// Mulai kamera
navigator.mediaDevices.getUserMedia({
video: { facingMode: { exact: "environment" } }
})
.then((stream) => {
video.srcObject = stream;
})
.catch((error) => {
console.warn('Gagal akses kamera belakang, coba kamera default:', error);
// Fallback ke kamera default (depan atau webcam laptop)
return navigator.mediaDevices.getUserMedia({ video: true });
})
.then((stream) => {
if (stream) {
video.srcObject = stream;
}
})
.catch((error) => {
console.error("Gagal mengakses kamera:", error);
showNotif('Tidak dapat mengakses kamera. Periksa izin kamera.', 'danger');
});
// Fungsi menampilkan notifikasi
function showNotif(message, type) {
notifContainer.innerHTML = `
<div class="alert alert-${type} text-center" role="alert">
${message}
</div>
`;
}
// Event tombol ambil gambar
captureButton.addEventListener('click', () => {
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
// Convert canvas ke base64
const imageData = canvas.toDataURL('image/png');
// Tampilkan loading
showNotif('Sedang memproses gambar...', 'info');
captureButton.innerText = 'Sedang memproses...';
captureButton.disabled = true;
// Kirim data ke server menggunakan AJAX
fetch('/predict', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ image: imageData }),
})
.then(response => {
if (!response.ok) {
return response.json().then(data => {
throw new Error(data.error || 'Prediksi gagal.');
});
}
return response.json();
})
.then(data => {
if (data.success) {
showNotif(`Prediksi: ${data.predicted_class} dengan akurasi ${data.confidence}%`, 'success');
} else {
showNotif(data.error || 'Prediksi gagal. Silakan coba lagi.', 'danger');
}
})
.catch(error => {
console.error('Error:', error.message);
showNotif(error.message || 'Terjadi kesalahan saat memproses gambar.', 'danger');
})
.finally(() => {
captureButton.innerText = 'Ambil Gambar';
captureButton.disabled = false;
});
});
</script>
{% endblock %}