Chỉnh sửa phần upload ảnh
This commit is contained in:
+28
-17
@@ -15,6 +15,7 @@ const { protect, optionalAuth } = require('../middlewares/authMiddleware');
|
||||
const { verifyReferer, setNoCacheHeaders } = require('../middlewares/securityMiddleware');
|
||||
const { resizeTo8K } = require('../utils/imageHelper');
|
||||
const { getGPSCoordinates, injectGPSCoordinates } = require('../utils/exifHelper');
|
||||
const { imageQueue } = require('./imageQueue');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -37,11 +38,16 @@ const storage = multer.diskStorage({
|
||||
const upload = multer({
|
||||
storage: storage,
|
||||
fileFilter: (req, file, cb) => {
|
||||
// Only accept images
|
||||
if (file.mimetype.startsWith('image/')) {
|
||||
// Chỉ chấp nhận các định dạng ảnh phổ biến đã được xử lý (Stitched)
|
||||
const filetypes = /jpeg|jpg|png/;
|
||||
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
|
||||
const mimetype = filetypes.test(file.mimetype) ||
|
||||
file.mimetype === 'application/octet-stream'; // Đôi khi trình duyệt gửi JPG dưới dạng octet-stream
|
||||
|
||||
if (mimetype && extname) {
|
||||
cb(null, true);
|
||||
} else {
|
||||
cb(new Error('Only image files are allowed!'), false);
|
||||
cb(new Error('Chỉ chấp nhận các định dạng ảnh JPEG, PNG, DNG hoặc INSP!'), false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -93,21 +99,14 @@ router.post('/scenes', protect, uploadSinglePanorama, async (req, res) => {
|
||||
const tempFilePath = req.file.path;
|
||||
const processedFileName = `processed_${req.file.filename}.jpg`;
|
||||
const processedFilePath = path.join(uploadDir, processedFileName);
|
||||
|
||||
// Lấy tọa độ GPS gốc từ ảnh vừa upload trước khi nén/xử lý
|
||||
|
||||
// Lấy tọa độ GPS gốc từ metadata
|
||||
const originalGPS = await getGPSCoordinates(tempFilePath);
|
||||
|
||||
// Thực hiện xử lý ảnh tuần tự để đảm bảo file được tạo thành công trước khi lưu DB
|
||||
// 1. Resize to 8K (Sẽ convert từ DNG sang JPG nếu sharp hỗ trợ libraw, nếu không sẽ báo lỗi)
|
||||
await resizeTo8K(tempFilePath, processedFilePath);
|
||||
// 2. Inject GPS vào file JPG vừa tạo
|
||||
await injectGPSCoordinates(processedFilePath, latitude, longitude);
|
||||
// 3. Cleanup temp file (file gốc dng)
|
||||
if (fs.existsSync(tempFilePath)) fs.unlinkSync(tempFilePath);
|
||||
const ext = path.extname(req.file.originalname).toLowerCase();
|
||||
|
||||
// 5. Save Asset to DB
|
||||
const asset = new Asset({
|
||||
filePath: processedFilePath,
|
||||
filePath: tempFilePath, // Tạm thời dùng file gốc cho đến khi worker xử lý xong
|
||||
uploadedBy: req.user._id,
|
||||
coordinates: originalGPS ? { lat: originalGPS.lat, lng: originalGPS.lng } : { lat: latitude, lng: longitude }
|
||||
});
|
||||
@@ -133,7 +132,7 @@ router.post('/scenes', protect, uploadSinglePanorama, async (req, res) => {
|
||||
const scene = new Scene({
|
||||
name: title,
|
||||
assetId: asset._id,
|
||||
scene_url: processedFilePath, // Lưu đường dẫn ảnh trực tiếp
|
||||
scene_url: tempFilePath, // Tạm thời
|
||||
gps: {
|
||||
lat: latitude,
|
||||
lng: longitude
|
||||
@@ -141,12 +140,24 @@ router.post('/scenes', protect, uploadSinglePanorama, async (req, res) => {
|
||||
createdBy: req.user._id,
|
||||
privacy: privacy || 'private',
|
||||
shareToken,
|
||||
sharedWith: parsedSharedWith
|
||||
sharedWith: parsedSharedWith,
|
||||
status: 'processing' // Đánh dấu đang xử lý
|
||||
});
|
||||
await scene.save();
|
||||
|
||||
// Đẩy tác vụ xử lý ảnh (Stitch + Resize) vào hàng đợi BullMQ
|
||||
// Loại bỏ needsStitch và rotation vì người dùng đã stitch ảnh thủ công
|
||||
await imageQueue.add('process-panorama', {
|
||||
tempFilePath,
|
||||
processedFilePath,
|
||||
latitude,
|
||||
longitude,
|
||||
assetId: asset._id,
|
||||
sceneId: scene._id
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
message: 'Scene created successfully',
|
||||
message: 'Scene đã được tạo! Ảnh đang được xử lý 8K ngầm...',
|
||||
scene
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user