TIFNGK_E41222722/templates/upload.html

285 lines
11 KiB
HTML

{% extends "base.html" %}
{% block title %}Upload Gambar{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow">
<div class="card-header bg-success text-white">
<h4 class="mb-0"><i class="fas fa-upload me-2"></i>Upload Gambar Sapi</h4>
</div>
<div class="card-body">
<!-- Info Panel -->
<div class="alert alert-info mb-4">
<i class="fas fa-info-circle me-2"></i>
<strong>Petunjuk:</strong> Upload gambar sapi dengan format JPG, JPEG, PNG, atau BMP.
Pastikan gambar jelas dan bagian tubuh sapi terlihat dengan baik.
</div>
<!-- Error Message -->
{% if error %}
<div class="alert alert-danger">
<i class="fas fa-exclamation-circle me-2"></i>
{{ error }}
</div>
{% endif %}
<!-- Upload Form -->
<form method="POST" action="{{ url_for('predict') }}" enctype="multipart/form-data" id="uploadForm">
<div class="mb-4">
<label for="file" class="form-label fw-bold">Pilih Gambar</label>
<!-- Custom File Upload -->
<div class="upload-area border border-2 border-dashed rounded p-4 text-center"
id="uploadArea">
<i class="fas fa-cloud-upload-alt fa-4x text-success mb-3"></i>
<h5>Drag & Drop atau Klik untuk Upload</h5>
<p class="text-muted mb-3">Format: JPG, JPEG, PNG, BMP (Maks. 16MB)</p>
<input type="file" class="form-control d-none" id="file" name="image"
accept=".jpg,.jpeg,.png,.bmp" required>
<button type="button" class="btn btn-success" id="browseBtn">
<i class="fas fa-folder-open me-2"></i>Pilih File
</button>
</div>
<!-- File Info -->
<div id="fileInfo" class="mt-3 d-none">
<div class="alert alert-success">
<i class="fas fa-check-circle me-2"></i>
<span id="fileName"></span>
<button type="button" class="btn-close float-end" id="removeFile"></button>
</div>
</div>
</div>
<!-- Image Preview -->
<div class="mb-4 text-center" id="previewContainer" style="display: none;">
<h6 class="mb-3">Preview Gambar:</h6>
<div class="preview-wrapper">
<img id="preview" class="img-fluid rounded shadow"
style="max-height: 300px; border: 3px solid #28a745;" alt="Preview">
</div>
<p class="text-muted mt-2 small" id="imageDimensions"></p>
</div>
<!-- Submit Button -->
<button type="submit" class="btn btn-success btn-lg w-100" id="submitBtn" disabled>
<i class="fas fa-search me-2"></i>Deteksi Sekarang
</button>
</form>
<!-- Loading Indicator -->
<div id="loading" class="text-center mt-4 d-none">
<div class="spinner-border text-success" style="width: 3rem; height: 3rem;" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-3 fw-bold">Sedang menganalisis gambar...</p>
<p class="text-muted small">Proses ini membutuhkan waktu beberapa detik</p>
</div>
<!-- Format yang Didukung -->
<div class="mt-4">
<h6 class="mb-2">Format yang Didukung:</h6>
<div class="d-flex gap-2">
<span class="badge bg-secondary">JPG</span>
<span class="badge bg-secondary">JPEG</span>
<span class="badge bg-secondary">PNG</span>
<span class="badge bg-secondary">BMP</span>
</div>
</div>
</div>
</div>
<!-- Tips Card -->
<div class="card mt-4">
<div class="card-header bg-info text-white">
<h5 class="mb-0"><i class="fas fa-lightbulb me-2"></i>Tips Pengambilan Gambar</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6><i class="fas fa-check-circle text-success me-2"></i>Disarankan:</h6>
<ul class="list-unstyled">
<li><i class="fas fa-arrow-right text-success me-2"></i>Gambar dengan pencahayaan cukup</li>
<li><i class="fas fa-arrow-right text-success me-2"></i>Fokus pada bagian mulut dan kaki</li>
<li><i class="fas fa-arrow-right text-success me-2"></i>Ambil dari jarak dekat (0.5-1 meter)</li>
<li><i class="fas fa-arrow-right text-success me-2"></i>Gunakan latar belakang polos</li>
</ul>
</div>
<div class="col-md-6">
<h6><i class="fas fa-times-circle text-danger me-2"></i>Tidak Disarankan:</h6>
<ul class="list-unstyled">
<li><i class="fas fa-times text-danger me-2"></i>Gambar buram atau blur</li>
<li><i class="fas fa-times text-danger me-2"></i>Terlalu jauh dari objek</li>
<li><i class="fas fa-times text-danger me-2"></i>Pencahayaan kurang/tidak merata</li>
<li><i class="fas fa-times text-danger me-2"></i>Banyak objek dalam satu frame</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.upload-area {
border: 2px dashed #28a745 !important;
background-color: #f8f9fa;
transition: all 0.3s;
cursor: pointer;
}
.upload-area:hover {
background-color: #e9ecef;
border-color: #218838 !important;
}
.upload-area.dragover {
background-color: #d4edda;
border-color: #28a745 !important;
}
.preview-wrapper {
position: relative;
display: inline-block;
}
#removeFile {
cursor: pointer;
}
</style>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('file');
const browseBtn = document.getElementById('browseBtn');
const fileInfo = document.getElementById('fileInfo');
const fileName = document.getElementById('fileName');
const removeFile = document.getElementById('removeFile');
const previewContainer = document.getElementById('previewContainer');
const preview = document.getElementById('preview');
const submitBtn = document.getElementById('submitBtn');
const loading = document.getElementById('loading');
const imageDimensions = document.getElementById('imageDimensions');
const uploadForm = document.getElementById('uploadForm');
// Click on upload area
uploadArea.addEventListener('click', function() {
fileInput.click();
});
// Browse button click
browseBtn.addEventListener('click', function(e) {
e.stopPropagation();
fileInput.click();
});
// Drag and drop events
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
uploadArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
uploadArea.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
uploadArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
uploadArea.classList.add('dragover');
}
function unhighlight() {
uploadArea.classList.remove('dragover');
}
uploadArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
fileInput.files = files;
handleFileSelect(files[0]);
}
// File input change
fileInput.addEventListener('change', function() {
if (this.files[0]) {
handleFileSelect(this.files[0]);
}
});
// Handle file selection
function handleFileSelect(file) {
// Check file size (16MB max)
if (file.size > 16 * 1024 * 1024) {
alert('File terlalu besar. Maksimal 16MB.');
fileInput.value = '';
return;
}
// Check file type
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/bmp'];
if (!allowedTypes.includes(file.type)) {
alert('Tipe file tidak didukung. Gunakan JPG, JPEG, PNG, atau BMP.');
fileInput.value = '';
return;
}
// Show file info
fileName.textContent = `${file.name} (${(file.size / 1024).toFixed(2)} KB)`;
fileInfo.classList.remove('d-none');
// Show preview
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
previewContainer.style.display = 'block';
// Get image dimensions
const img = new Image();
img.onload = function() {
imageDimensions.textContent = `${this.width} x ${this.height} pixels`;
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
// Enable submit button
submitBtn.disabled = false;
}
// Remove file
removeFile.addEventListener('click', function() {
fileInput.value = '';
fileInfo.classList.add('d-none');
previewContainer.style.display = 'none';
submitBtn.disabled = true;
});
// Form submit
uploadForm.addEventListener('submit', function(e) {
if (!fileInput.files[0]) {
e.preventDefault();
alert('Pilih file terlebih dahulu');
return;
}
submitBtn.disabled = true;
loading.classList.remove('d-none');
});
});
</script>
{% endblock %}