无法使用 multer-s3-transform 将图像 contentType 从 jpg 更改为 webp

问题描述

我正在尝试将图像大小调整为 3 种类型:large.jpg、medium.webp、small.webp 我正在使用 multer-s3-transform

但所有结果图像 contentType 都是 'image/jpeg' image

我的原始图像是 jpg,我希望它转换为 webp。有人可以帮助我,这是我的代码

const multerS3Config = multerS3({
s3: s3,bucket: process.env.wasabi_BUCKET_NAME,cacheControl: 'max-age=31536000',contentType: multerS3.AUTO_CONTENT_TYPE,shouldTransform: function (req,file,cb) {
    // console.log('in should transform ',file)
    cb(null,/^image/i.test(file.mimetype))
},transforms: [{
    id: 'lg',key: function (req,cb) {
        const filename = file.originalname.replace(/\..+$/,"");
        const newFilenameLarge = `${filename}-large.jpg`;

        var fullPath = `${req.params.slug}/chapter-${req.body.chapter}/${Date.Now()}-${newFilenameLarge}`;
        cb(null,fullPath)
    },transform: function (req,cb) {
        cb(null,sharp().jpeg({ quality: 90 }).resize(1000))
    }
},{
    id: 'md',"");
        const newFilenameMedium = `${filename}-medium.webp`;

        var fullPath = `${req.params.slug}/chapter-${req.body.chapter}/${Date.Now()}-${newFilenameMedium}`;
        cb(null,cb) {
        
        console.log(file)
        cb(null,sharp().webp({ quality: 90 }).resize(690))
    }
},{
    id: 'sm',"");
        const newFilenameSmall = `${filename}-small.webp`;

        var fullPath = `${req.params.slug}/chapter-${req.body.chapter}/${Date.Now()}-${newFilenameSmall}`;
        cb(null,sharp().webp({ quality: 90 }).resize(400))
    }
}],cb) {
    cb(null,true)
}

});

解决方法

所以我通过使用multer和sharp来解决我的问题

上传控制器:

multipleUpload = async (req,res,next) => {
       MulterUploadMiddleware(req,res)
        .then(async () => { 
            var params = {
                slug: req.params.slug,chapter: `chapter-${req.body.chapter}`
            }
            var imagesURL = await S3UploadMiddleWare.uploadMultiple(req.files,params)
            saveURLToDb(imagesURL)
        })
        .catch(err => next(err))
        

        function saveURLToDb(imagesURL) {
            console.log(imagesURL)
            const newChapter = new Chapter({
                title: `chapter of ${req.params.slug}`,chapter: `chapter-${req.body.chapter}`,chapterSlug: `${req.params.slug}-${shortid()}`,comicSlug: req.params.slug,})
            imagesURL.forEach((url,index) => {
                newChapter.image[index] = url
            });
            newChapter
            .save()
            .then(res.redirect('back'))
        };
           
    };

S3UploadMiddleWare:

const AWS               = require('aws-sdk');
const wasabiEndpoint    = new AWS.Endpoint(process.env.WASABI_ENDPOINT);
const sharp             = require("sharp");
const s3 = new AWS.S3({
    endpoint: wasabiEndpoint,accessKeyId: process.env.WASABI_ACCESS_KEY_ID,secretAccessKey: process.env.WASABI_SECRET_ACCESS_KEY,});

var self = module.exports = {
    uploadMultiple: async (files,params) => {
        const images = [];

        const resizePromises = files.map(async (file) => {
            const filename = `${params.slug}/${params.chapter}/${Date.now()}-${file.originalname.replace(/\..+$/,"")}`;
            console.log(filename)
             sharp(file.buffer)
                .resize({ width: 1000,fit: 'contain'})
                .jpeg({ quality: 90 })
                .toBuffer()
                .then(resized => s3.upload({
                    ACL: 'public-read',Body: resized,Bucket: process.env.WASABI_BUCKET_NAME,ContentType: file.mimetype,Key: `${filename}-large.jpg`,}).promise())
             sharp(file.buffer)
                .resize({ width: 690,fit: 'contain'})
                .webp({ quality: 90 })
                .toBuffer()
                .then(resized => s3.upload({
                    ACL: 'public-read',ContentType: 'image/webp',Key: `${filename}-medium.webp`,}).promise())
             sharp(file.buffer)
                .resize({ width: 400,Key: `${filename}-small.webp`,}).promise())

                images.push({url: filename});
               
        });

        
        await Promise.all([...resizePromises]).then(console.log('done upload'));

        return images
    }
}

MulterUploadMiddleWare:

    const Chapter = require('../models/Chapter');
const multer = require("multer");
const path = require("path");
const util = require("util");

const multerStorage = multer.memoryStorage()

function chapterIsExisted(req) {
    // 1. Implement this!
    console.log(req.body)
    return (
        Chapter
            .findOne({ comicSlug: req.params.slug,chapter: `chapter-${req.body.chapter}` })
            .then(chapterExisted => {
                console.log(chapterExisted)
                if (chapterExisted == null) { return false }
                return true
            }))
};

const filter = async (req,file,cb) => {
    var check = await chapterIsExisted(req)
    console.log(check)
    if (check == false) {
        cb(null,true)
    } else {
        let errorMess = `chapter ${req.body.chapter} đã có,hãy nhập chapter khác`;
        return cb(errorMess,false);
    }
};

const upload = multer({
    storage: multerStorage,fileFilter: filter
}).array("many-files",200);;


let multipleUploadMiddleware = util.promisify(upload);
 
 module.exports = multipleUploadMiddleware;