업로드 이미지 WebP 최적화 1차 적용
This commit is contained in:
76
backend/src/lib/image-storage.js
Normal file
76
backend/src/lib/image-storage.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const fs = require('fs/promises')
|
||||
const path = require('path')
|
||||
const sharp = require('sharp')
|
||||
const { nanoid } = require('nanoid')
|
||||
|
||||
const UPLOAD_ROOT = path.join(__dirname, '..', '..', 'uploads')
|
||||
|
||||
function ensureImageMimeType(file) {
|
||||
return typeof file?.mimetype === 'string' && file.mimetype.startsWith('image/')
|
||||
}
|
||||
|
||||
function createMemoryUpload(multer, { fileSize = 6 * 1024 * 1024, maxCount } = {}) {
|
||||
return multer({
|
||||
storage: multer.memoryStorage(),
|
||||
limits: {
|
||||
fileSize,
|
||||
...(typeof maxCount === 'number' ? { files: maxCount } : {}),
|
||||
},
|
||||
fileFilter: (req, file, cb) => {
|
||||
if (ensureImageMimeType(file)) return cb(null, true)
|
||||
cb(new Error('image_file_required'))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function writeOptimizedImage({
|
||||
file,
|
||||
directory,
|
||||
width,
|
||||
height,
|
||||
fit = 'inside',
|
||||
quality = 82,
|
||||
}) {
|
||||
if (!file?.buffer?.length) {
|
||||
const error = new Error('file_required')
|
||||
error.code = 'file_required'
|
||||
throw error
|
||||
}
|
||||
|
||||
if (!ensureImageMimeType(file)) {
|
||||
const error = new Error('image_file_required')
|
||||
error.code = 'image_file_required'
|
||||
throw error
|
||||
}
|
||||
|
||||
const { data, info } = await sharp(file.buffer, { failOn: 'none' })
|
||||
.rotate()
|
||||
.resize({
|
||||
width,
|
||||
height,
|
||||
fit,
|
||||
withoutEnlargement: true,
|
||||
})
|
||||
.webp({ quality })
|
||||
.toBuffer({ resolveWithObject: true })
|
||||
|
||||
const filename = String(Date.now()) + '-' + nanoid() + '.webp'
|
||||
const absoluteDir = path.join(UPLOAD_ROOT, directory)
|
||||
const absolutePath = path.join(absoluteDir, filename)
|
||||
await fs.mkdir(absoluteDir, { recursive: true })
|
||||
await fs.writeFile(absolutePath, data)
|
||||
|
||||
return {
|
||||
src: '/uploads/' + directory + '/' + filename,
|
||||
size: data.length,
|
||||
originalSize: file.size || file.buffer.length,
|
||||
width: info.width || 0,
|
||||
height: info.height || 0,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createMemoryUpload,
|
||||
ensureImageMimeType,
|
||||
writeOptimizedImage,
|
||||
}
|
||||
Reference in New Issue
Block a user