diff --git a/cam_web.py b/cam_web.py
index c8aa1c2..7198710 100644
--- a/cam_web.py
+++ b/cam_web.py
@@ -44,6 +44,7 @@ def init_db():
right_filename TEXT NOT NULL,
timestamp REAL NOT NULL,
metadata TEXT,
+ comment TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
@@ -89,7 +90,7 @@ def get_images_api():
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
# 按时间倒序排列
- cursor.execute("SELECT id, left_filename, right_filename, timestamp, metadata, created_at FROM images ORDER BY timestamp DESC")
+ cursor.execute("SELECT id, left_filename, right_filename, timestamp, metadata, comment, created_at FROM images ORDER BY timestamp DESC")
rows = cursor.fetchall()
conn.close()
@@ -101,7 +102,8 @@ def get_images_api():
"right_filename": row[2],
"timestamp": row[3],
"metadata": row[4],
- "created_at": row[5]
+ "comment": row[5] or "", # 如果没有comment则显示空字符串
+ "created_at": row[6]
})
return jsonify(images)
@@ -194,6 +196,7 @@ def upload_images():
left_file = request.files.get('left_image')
right_file = request.files.get('right_image')
metadata_str = request.form.get('metadata') # 如果需要处理元数据
+ comment = request.form.get('comment', '') # 获取comment字段
if not left_file or not right_file:
logger.warning("Received request without required image files.")
@@ -244,9 +247,9 @@ def upload_images():
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute('''
- INSERT INTO images (left_filename, right_filename, timestamp, metadata)
- VALUES (?, ?, ?, ?)
- ''', (left_filename, right_filename, float(timestamp_str), json.dumps(metadata)))
+ INSERT INTO images (left_filename, right_filename, timestamp, metadata, comment)
+ VALUES (?, ?, ?, ?, ?)
+ ''', (left_filename, right_filename, float(timestamp_str), json.dumps(metadata), comment))
conn.commit()
image_id = cursor.lastrowid # 获取新插入记录的 ID
conn.close()
@@ -277,7 +280,25 @@ def upload_images():
logger.error(f"Error processing upload: {e}")
return jsonify({"error": str(e)}), 500
-# --- 可选:添加一个简单的状态检查路由 ---
+@app.route('/api/images/comment', methods=['PUT'])
+def update_image_comment():
+ """API: 更新图片的comment"""
+ data = request.json
+ image_id = data.get('id')
+ comment = data.get('comment', '')
+
+ if not image_id:
+ return jsonify({"error": "Image ID is required"}), 400
+
+ conn = sqlite3.connect(DATABASE_PATH)
+ cursor = conn.cursor()
+ # 更新comment字段
+ cursor.execute("UPDATE images SET comment = ? WHERE id = ?", (comment, image_id))
+ conn.commit()
+ conn.close()
+
+ return jsonify({"message": f"Comment for image {image_id} updated successfully"})
+
@app.route('/status')
def status():
with frame_lock:
diff --git a/templates/list_images.html b/templates/list_images.html
index 1be3a19..f58c7b7 100644
--- a/templates/list_images.html
+++ b/templates/list_images.html
@@ -1,11 +1,19 @@
+
Saved Images List
+
Saved Images
@@ -41,18 +85,20 @@
+
|
-
+
|
ID |
Left Image |
Right Image |
Timestamp |
- Created At |
+ Comment |
Actions |
@@ -82,6 +128,7 @@
}
// 渲染表格
+ // 修改渲染表格的函数
function renderTable(images) {
const tbody = document.getElementById('imagesTableBody');
tbody.innerHTML = ''; // 清空现有内容
@@ -90,14 +137,14 @@
const row = tbody.insertRow();
row.insertCell(0).innerHTML = ``;
row.insertCell(1).textContent = image.id;
-
+
const leftCell = row.insertCell(2);
const leftImg = document.createElement('img');
// 修改这里:使用 Flask 静态文件路径
leftImg.src = `/static/received/left/${image.left_filename}`;
leftImg.alt = "Left Image";
leftImg.className = 'image-preview';
- leftImg.onerror = function() { this.src = 'data:image/svg+xml;utf8,'; };
+ leftImg.onerror = function () { this.src = 'data:image/svg+xml;utf8,'; };
leftCell.appendChild(leftImg);
const rightCell = row.insertCell(3);
@@ -106,15 +153,47 @@
rightImg.src = `/static/received/right/${image.right_filename}`;
rightImg.alt = "Right Image";
rightImg.className = 'image-preview';
- rightImg.onerror = function() { this.src = 'data:image/svg+xml;utf8,'; };
+ rightImg.onerror = function () { this.src = 'data:image/svg+xml;utf8,'; };
rightCell.appendChild(rightImg);
row.insertCell(4).textContent = new Date(image.timestamp * 1000).toISOString();
- row.insertCell(5).textContent = image.created_at;
+
+ // 添加可编辑的comment单元格
+ const commentCell = row.insertCell(5);
+ const commentInput = document.createElement('input');
+ commentInput.type = 'text';
+ commentInput.value = image.comment || '';
+ commentInput.dataset.id = image.id;
+ commentInput.className = 'comment-input';
+ commentInput.style.width = '100%';
+ commentInput.addEventListener('change', function () {
+ updateComment(image.id, this.value);
+ });
+ commentCell.appendChild(commentInput);
+
row.insertCell(6).innerHTML = ``;
});
}
+ // 添加更新comment的函数
+ async function updateComment(id, comment) {
+ try {
+ const response = await fetch('/api/images/comment', {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ id: id, comment: comment })
+ });
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({ error: response.statusText }));
+ throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
+ }
+ document.getElementById('status').textContent = `Comment for image ID ${id} updated.`;
+ } catch (error) {
+ console.error('Error updating comment:', error);
+ document.getElementById('status').textContent = 'Error updating comment: ' + error.message;
+ }
+ }
+
// 删除图片
async function deleteImage(id) {
if (!confirm(`Are you sure you want to delete image ID ${id}?`)) return;
@@ -165,7 +244,7 @@
document.getElementById('refreshBtn').addEventListener('click', loadImages);
// --- 修改:使用 fetch API 发起导出请求 ---
- document.getElementById('exportBtn').addEventListener('click', async function() {
+ document.getElementById('exportBtn').addEventListener('click', async function () {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Please select at least one image to export.');
@@ -205,7 +284,7 @@
}
});
- document.getElementById('deleteSelectedBtn').addEventListener('click', async function() {
+ document.getElementById('deleteSelectedBtn').addEventListener('click', async function () {
const selectedIds = getSelectedIds();
if (selectedIds.length === 0) {
alert('Please select at least one image to delete.');
@@ -236,7 +315,7 @@
});
// 全选复选框事件监听
- document.getElementById('selectAllCheckbox').addEventListener('change', function() {
+ document.getElementById('selectAllCheckbox').addEventListener('change', function () {
const isChecked = this.checked;
const checkboxes = document.querySelectorAll('.selectCheckbox');
checkboxes.forEach(checkbox => {
@@ -246,7 +325,7 @@
});
// 监听单个复选框变化以更新全选框和按钮状态
- document.getElementById('imagesTable').addEventListener('change', function(e) {
+ document.getElementById('imagesTable').addEventListener('change', function (e) {
if (e.target.classList.contains('selectCheckbox')) {
updateSelectAllCheckbox();
}
@@ -257,4 +336,5 @@
+
\ No newline at end of file