try to resize the stream image with sharp Node.js

泪湿孤枕 提交于 2020-05-29 07:20:30

问题


I am trying to resize the width and height of input Stream-image from the user to the server with sharp function but nothing happens with the image. It keeps on his original size, How should I use the sharp function so that I can get the image smaller or bigger?

Please help me

This is how my code looks like:

'use strict';


const builder = require('botbuilder');
const restify = require('restify');
const utils = require('./utils.js');
const request = require('request');
const sharp = require('sharp');
const fs = require('fs');     
const resizeImage = require('resize-image');


// Create chat connector for communicating with the Bot Framework Service
const connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// Setup Restify Server
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
    console.log(`${server.name} listening to ${server.url}`);
});

// Listen for messages from users
server.post('/api/messages', connector.listen());

const bot = new builder.UniversalBot(connector);

// default dialog

//resize the images

//Sends greeting message when the bot is first added to a conversation
bot.on('conversationUpdate', function (message) {
    if (message.membersAdded) {
        message.membersAdded.forEach(function (identity) {
            if (identity.id === message.address.bot.id) {
                
         
                var reply = new builder.Message()
                    .address(message.address)
                    
                    .text('Hi, please send a screenshot for the error');
                    

                bot.send(reply);
            }
        });
    }
}
);

bot.dialog('/', function(session) {
    if(utils.hasImageAttachment(session)){
        //--others

        var stream = utils.getImageStreamFromMessage(session.message);
      ***//resize the image stream
      sharp('stream')
      .resize(100, 100)
      .toFile('stream', function(err) {
        // output.jpg is a 200 pixels wide and 200 pixels high image
        // containing a scaled and cropped version of input.jpg
      }); 
      //***
        const params = {
            'language': 'en',
            'detectOrientation': 'true',

        };
        const options = {
            uri: uriBase,
          qs: params,
            body: stream ,
          
            headers: {
                'Content-Type': 'application/octet-stream',
                'Ocp-Apim-Subscription-Key' : subscriptionKey
            }
        };

request.post(options, (error, response, body) => {
    if (error) {
      console.log('Error: ', error);
      return;
    }

 const obj =   JSON.parse(body);
 console.log(obj);

 
  //------------ get the texts from json as string
  if(obj.regions =="" ){
    
    session.send('OOOOPS I CANNOT READ ANYTHING IN THISE IMAGE :(');

}else{


let buf = ''
if(obj && obj.regions) {
obj.regions.forEach((a, b, c) => {
if(a && a.lines) {
a.lines.forEach((p, q, r) => {
if(p && p.words) {
p.words.forEach((x, y, z) => {
  

buf += ` ${x.text}  ` 



})
}
})
}
})
}
session.send(buf);
}

});
               

    } else {
        session.send('nothing');

        
    }
});

Thanks


回答1:


According the doc of Sharp of function toFile(), this function returns a promise when no callback is provided.

So there should be no I/O block when excusing toFile function, and continue runing the following code which is request.post in your code snippet. At that time, the image may not be modified.

You can try to either use promise style code flow, like:

sharp('stream')
      .resize(100, 100)
      .toFile('stream')
      .then((err,info)=>{
         //do request post 
      })

or put the request code inside the callback function of toFile(), like:

sharp('stream')
      .resize(100, 100)
      .toFile('stream',function(err,info)=>{
       //do request post
      })



回答2:


Your use of sharp('stream') doesn't work because the function is looking for a string as its input and you are trying to feed it a stream. Per the docs, you need to read from the readableStream and then process the image.

The example below I tested (locally) and runs. As is, it will save the image file on the server in the location of the app.js file. The commented-out ".pipe(stream)" creates a writeableStream you could then access at a later point if that is what you need. In that case, you wouldn't use .toFile().

Hope of help!

bot.dialog('/', function (session) {
    if (utils.hasImageAttachment(session)) {
        //--others

        var stream = utils.getImageStreamFromMessage(session.message);

        var transformer = sharp()
            .resize(100)
            .jpeg()
            .toFile('image.jpg', function (err) {
                if (err)
                    console.log(err);
            })
            .on('info', function (err, info) {
                session.send('Image height is ' + info.height);
            });
        stream.pipe(transformer); //.pipe(stream);

        const params = {
            'language': 'en',
            'detectOrientation': 'true',

        };

        const options = {
            uri: "https://smba.trafficmanager.net/apis",
            qs: params,
            body: stream,

            headers: {
                'Content-Type': 'application/octet-stream',
                'Ocp-Apim-Subscription-Key': ""
            }
        };

        request.post(options, (error, response, body) => {
            if (error) {
                console.log('Error: ', error);
                return;
            }

            console.log(body);
            const obj = JSON.stringify(body);
            console.log(body);


            //------------ get the texts from json as string
            if (obj.regions == "") {
                session.send('OOOOPS I CANNOT READ ANYTHING IN THISE IMAGE :(');
            } else {
                let buf = ''
                if (obj && obj.regions) {
                    obj.regions.forEach((a, b, c) => {
                        if (a && a.lines) {
                            a.lines.forEach((p, q, r) => {
                                if (p && p.words) {
                                    p.words.forEach((x, y, z) => {
                                        buf += ` ${x.text}  `
                                    })
                                }
                            })
                        }
                    })
                }
                session.send(buf);
            }
        });
    } else {
        session.send('nothing');
    }
});



回答3:


I have used Sharp in the below way in my case which works perfectly fine.

            sharp('stream')
            .png()
            .resize(100, 100)
            .toBuffer((err, buffer, info) => {
                if (err)
                    console.log(err);

                if (buffer) {
                    return buffer;
                }
            });

Sharp's toFile() saves the output in a file, so you could give a file name as an argument. toBuffer() will return a buffered object. Hope it helps!



来源:https://stackoverflow.com/questions/51983346/try-to-resize-the-stream-image-with-sharp-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!