Проблемы при попытке загрузить несколько изображений из Multer с помощью Jimp (Express) в NodeJS - PullRequest
1 голос
/ 11 октября 2019

Я хочу отобразить несколько изображений на своем веб-сайте, используя Multer (nodejs).

Я создал следующую функцию:

exports.upload = multer(options).array('photo',3);

exports.images = async (req, res, next) => {
    const imgArray = req.files;

    const imgFormat = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        imgFormat.push(imgArray[i].mimetype.split('/')[1] );
    }

    req.body.photo = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        req.body.photo.push(`${uuid.v4()}.${imgFormat[i]}`);
    }

    for (let i = 0; i < imgArray.length; i++) {
        const imgDetails = imgArray[i];
        const photo = await jimp.read(imgDetails.buffer);
        await photo.resize(1200, jimp.AUTO);
        await photo.write(`./public/uploads/${(req.body.photo)}`)
    }
    next();
    console.log(req.body.photo);

};

Я использую mongoose для доступа к своей базе данных. На MongoDB мне удается получить изображения без каких-либо проблем:

посмотреть, что я получу в MongoDB Но когда я console.log req.body.photo, я получаю следующий массив:

 [ 'cdb88df7-149d-4506-9ec2-7550c32ace66.jpeg',
   'efd9113b-9bd1-410e-a402-e969bf7aa8e3.png',
   '6408dbdc-4093-44a9-91f1-e34e7c5918e1.jpeg' ]

В моем memoryStorage я сохраняю строку, состоящую из трех изображений, когда мне нужно их разделить:

Что я получу: cdb88df7-149d-4506-9ec2-7550c32ace66.jpeg,efd9113b-9bd1-410e-a402-e969bf7aa8e3.png,6408dbdc-4093-44a9-91f1-e34e7c5918e1.jpeg

Что я хочу:cdb88df7-149d-4506-9ec2-7550c32ace66.jpegefd9113b-9bd1-410e-A402-e969bf7aa8e3.png6408dbdc-4093-44a9-91f1-e34e7c5918e1.jpeg

Получение изображений, отделенных друг от друга, а не в массиве, заставляет мой код работать, я проверил его.

Подскажите, пожалуйста, как это сделать? У меня кончились идеи. Большое спасибо

Ответы [ 4 ]

0 голосов
/ 15 октября 2019

Для тех, кто заинтересован, вот мой последний код, который разрешил все проблемы, упомянутые выше:

exports.images = async (req, res, next) => {
    const imgArray = req.files;

    const imgFormat = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        imgFormat.push(imgArray[i].mimetype.split('/')[1] );
    }

    req.body.photo = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        req.body.photo.push(`${uuid.v4()}.${imgFormat[i]}`);
    }

    for (let i = 0; i < imgArray.length; i++) {
        const imgDetails = imgArray[i];
        const photo = await jimp.read(imgDetails.buffer);
        await photo.resize(1200, jimp.AUTO);
        await photo.write(`./public/uploads/${(req.body.photo[i])}`)

    }
    next();

};

С помощью этого кода я могу загружать несколько изображений через multer и jimp. Большое спасибо @ за вашу помощь

0 голосов
/ 12 октября 2019

Спасибо @chuklore за ваш ответ. Помимо того, что вы позволили мне изучить новую практику ES6, вы помогли мне продвинуться вперед в решении моей проблемы. Но я все еще сталкиваюсь с проблемой после того, как я выполнил вашу рекомендацию.

Теперь я могу получить изображения, отделенные друг от друга: i.ibb.co/n8TbdhM/image.png

Так что, когда я зацикливаюсь с PUG, я получаю три изображения как нужно, НОэто всегда одно и то же изображение: i.ibb.co/BTDPWN5/image.png

Как вы можете видеть на скриншоте выше, я повторяю через PUG то, что должно было быть три разных изображения.

Когда я проверяю эти изображения в своей памяти, это действительно одно и то же изображение с другим UUID.

Так что, должно быть, что-то пошло не так в моем коде, но я не могу понять это. Когда в console.log (imgDetails.buffer) я получаю три разных буфера, не всегда одинаковые. Поэтому я не знаю, откуда возникла проблема:

console.log (imgDetails.buffer): https://i.ibb.co/XVFzz4x/image.png

Вот мой код снова:

exports.images = async (req, res, next) => {
    // get all images details
    const imgArray = req.files;
    // get extension (pgn, jpeg...)
    const imgFormat = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        imgFormat.push(imgArray[i].mimetype.split('/')[1] );
    }
    // get unique ID by image
    req.body.photo = [];
    for(let i = 0; i < imgArray.length; i++ ) {
        req.body.photo.push(`${uuid.v4()}.${imgFormat[i]}`);
    }
    // unpack images from the array
    let [imageOne, imageTwo, imageThree] = req.body.photo;

    for (let i = 0; i < imgArray.length; i++) {
        const imgDetails = imgArray[i];
        // get buffer for each image
        const photo = await jimp.read(imgDetails.buffer);
        await photo.resize(600, jimp.AUTO);
        await photo.write(`./public/uploads/${(imageOne)}`);
        await photo.write(`./public/uploads/${(imageTwo)}`);
        await photo.write(`./public/uploads/${(imageThree)}`)
    }
    next();

};

Я могу предоставить подробную информацию об остальной части моего кода, если это необходимо. Спасибо

0 голосов
/ 14 октября 2019

@ chuklore. Большое спасибо за вашу помощь, мне удалось заставить ее работать, следуя вашим ценным инструкциям и добавив небольшие изменения. Вот код, который отлично работает на моей стороне:

exports.image = async (req, res, next) => {
    if(!req.files){
        next();
        return;
    }

    let [firstFile,secondFile, thirdFile] = req.files;

    const extension1 = firstFile.mimetype.split('/')[1];
    const extension2 = secondFile.mimetype.split('/')[1];
    const extension3 = thirdFile.mimetype.split('/')[1];

    req.body.photo = [
        `${uuid.v4()}.${extension1}`,
        `${uuid.v4()}.${extension2}`,
        `${uuid.v4()}.${extension3}`];

    let [imageOne, imageTwo, imageThree] = req.body.photo;

    const photo1 = await jimp.read(firstFile.buffer);
    const photo2 = await jimp.read(secondFile.buffer);
    const photo3 = await jimp.read(thirdFile.buffer);

    await photo1.resize(600, jimp.AUTO);
    await photo2.resize(600, jimp.AUTO);
    await photo3.resize(600, jimp.AUTO);

    await photo1.write(`./public/uploads/${(imageOne)}`);
    await photo2.write(`./public/uploads/${(imageTwo)}`);
    await photo3.write(`./public/uploads/${(imageThree)}`);

    next();
};

Если кто-нибудь придумает, как его улучшить, пожалуйста, дайте мне знать. Поскольку при условии, что мне нужно 50 изображений на моем веб-сайте, я не могу дублировать 50 раз каждую строку.

Кроме того, когда я загружаю только одно изображение (вместо трех), я получаю «Не удается прочитать свойство« mimetype »из undefined». Очевидно, что загрузка трех изображений является обязательной, но я не хочу, чтобы это было так.

Я пробовал много вещей, таких как:

    for(let i=0; i < req.files.length; i++ ) {
        if( typeof req.files[i].mimetype ==='undefined') {
        // ...
        }

Пока ничего не работает. Любая идея ? Спасибо

0 голосов
/ 12 октября 2019

Вы можете попытаться назначить переменные своим изображениям с помощью новой ES6 «Разрушение массива»

Начиная с документов:

Синтаксис назначения деструктурирования - это выражение JavaScript, которое позволяетраспакуйте значения из массивов или свойства из объектов в отдельные переменные.

, следовательно, вот так

let [imageOne, imageTwo, imageThree] = req.body.photo;

Тогда вы можете использовать изображения отдельно, как вам хочется, если вы утешаете. log () imageOne вы получите

console.log(imageOne) //output cdb88df7-149d-4506-9ec2-7550c32ace66.jpeg

В своем коде вы можете реализовать его следующим образом

 exports.upload = multer(options).array('photo',3);

exports.images = async (req, res, next) => {
const imgArray = req.files;

const imgFormat = [];
for(let i = 0; i < imgArray.length; i++ ) {
    imgFormat.push(imgArray[i].mimetype.split('/')[1] );
}

req.body.photo = [];
for(let i = 0; i < imgArray.length; i++ ) {
    req.body.photo.push(`${uuid.v4()}.${imgFormat[i]}`);
}

for (let i = 0; i < imgArray.length; i++) {
    const imgDetails = imgArray[i];
    const photo = await jimp.read(imgDetails.buffer);
    await photo.resize(1200, jimp.AUTO);
    await photo.write(`./public/uploads/${(req.body.photo)}`)
}  

  setTimeout(() => {
   let [imageOne, imageTwo, imageThree] = req.body.photo;
 }, 450);


 setTimeout(() => {
    next();
  }, 600); 

};

Что если вы попытаетесь сделать это вместо этогоforloop, чтобы позже определить, что является реальной проблемой, потому что я думаю, что это может быть цикл

let [firstFile,secondFile,thirdFile] = req.files
 const photo1 = await jimp.read(firstFile.buffer);
 const photo2 = await jimp.read(secondFile.buffer);
 const photo3 = await jimp.read(thirdFile.buffer);

 await photo1.resize(600, jimp.AUTO);
 await photo2.resize(600, jimp.AUTO);
 await photo3.resize(600, jimp.AUTO);

await photo1.write(`./public/uploads/${(firstFile)}`);
await photo2.write(`./public/uploads/${(secondFile)}`);
await photo3.write(`./public/uploads/${(thirdFile)}`);
...