Search code examples
node.jsftpsharp

How can i get binary from image using node ftp?


I want to get binary from image to rotate then, using sharp.rotate();

I try to do this content += chunk; but dosent work.

let Client     = require('ftp');
    let fs      = require('fs');
    let sharp   = require('sharp');

    let path = 'users/'+userId+'/headerImage/header';
    let Ftp = new Client();//create new istance of Ftp

    //Start. Here we get image from server
    await Ftp.on('ready', function(){
        Ftp.get(path, async function(err, stream){
            if(err){
                res.status(400).send(err);
            };

            var content = '';
            await stream.on('data', async (chunk) => {
                content += chunk;
              });

            await stream.on('end', async function(){
                console.log(content);
                let image = await sharp(content);

                await image
                    .rotate(90)
                    .toBuffer()
                    .then(async data => {
                        console.log(data);
                    })
                    .catch(error => {
                        console.log(error);
                    });
                Ftp.end();
            });
        });
    });
    await Ftp.connect({
        host: fileTransferProtocol.host,
        port: fileTransferProtocol.port,
        user: fileTransferProtocol.user,
        password: fileTransferProtocol.pass
    });

console: Error: [Error: Input file is missing]


Solution

  • I believe the problem you are having is that you are not handling the incoming data as a buffer. The stream variable inside the Ftp.get callback is of type ReadableStream. By default, stream data will be returned as Buffer objects unless you specify an encoding for the data, using the readable.setEncoding() method.

    For your specific purpose, you want to handle the data as a Buffer object, since that is what the sharp function is expecting. To store the incoming data into a Buffer modify what happens on the data event.

    var content = new Buffer(0);
    
    stream.on("data", async chunk => {
      content = Buffer.concat([content, chunk]);
    });
    

    Also, I don't think you are using async/await duly. The ftp module runs with callbacks and events, not promises. Appending those functions with await won't make them run synchronously.

    Please check the following link to find more information about this feature:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

    If you want to us async/await to handle your ftp requests try this module:

    https://www.npmjs.com/package/promise-ftp

    It provides an asynchronous interface for communicating with an FTP server.