nodejs resize and save image from remote server - node.js

node js resize and save image from remote server.
Hi,
How can I resize image without to save locally and then to save it.
when I run bellow code, I get error: "Error: Input buffer contains unsupported image format"
code:
var fs = require('fs');
var request = require('request');
var sharp = require('sharp');
function getImage()
{
request('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', function (err, res, body) {
var binary = Buffer.from(body.toString(), 'base64');
sharp(binary).resize(198, 110).toFile('test.jpg', (err, info ) =>
{
console.log('err: ', err);
console.log('info: ', info);
});
});
}

I found resolving for my question:
var resizer = sharp().resize(198, 110).toFile('test.jpg', (err, info) => {
console.log('err: ', err);
console.log('info: ', info);
});
request('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png').pipe(resizer);

If you can make sure that https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png returns the image, you can try to pipe the response directly to sharp rather than converting response to base64 format & processing.
var resize = sharp(binary).resize(198, 110);
resize.on('error', function() {
//handle error
});
resize.on('finish', function() {
// done
});
request('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')
.pipe(process);
Update:
Removed .toFile('test.jpg'); part

Related

Nodejs download image

I'm trying to download an image from my server using request.
I've managed to download something but i get more data than the image.
function _download(uri, save_as, destination) {
let options = {
uri: uri,
timeout: 100000,
followAllRedirects: true
};
return new Promise(( _resolve,_reject) => {
let ext, filename, bar, total, downloaded, req;
req = request(options).on('response', (resp) => {
if (resp.statusCode === 200){
ext = _getFileType(resp.headers['content-type']);
filename = destination+'/'+save_as+ext;
var stream = fs.createWriteStream(filename)
resp.pipe(stream).on('error',function(err){
_reject(err);
}).on('finish',function(){
_resolve(filename);
});
} else {
_reject("unable to download image %s",uri);
}
}).on('error', function(err) {
console.log(err)
_reject(err);
})
});
}
My original url is in form of https://www.test.com/image/original/12345, my server than redirects with a 301 status to my s3 bucket where image is stored.
Unfortunately due to the url of the image i have to wait that for the response header content type to determinate what kind of image it's and use it to pipe the image.
Everything works quite as expected... but i get more data than what is stored in s3.
Does anyone have any suggestion ?
please refer to the link below
var fs = require('fs'),
request = require('request');
var download = function(uri, filename, callback){
request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('https://www.google.com/images/srpr/logo3w.png', 'google.png', function(){
console.log('done');
});
please visit this link
And this link also

Nodejs is not receiving any code from Flask app.

I am really new in node js and a little bit more experienced in flaks. I am trying to connect a nodejs backend with a flask api. Basically I am sending a file that was uploaded in the nodejs app for processing (converting to another format) to my flask app.
For sending the data I am using request. In this way:
app.post('/converttest', uploader.single('file'), function(req,res){
var file = req.file,
result = {
error: 0,
uploaded: []
};
flow.exec(
function() { // Read temp File
fs.readFile(file.path, this);
},
function(err, data) { // Upload file to S3
var formData = {
file: data,
};
requestPack.post({url:'http://127.0.0.1:5000/api/resource/converter', formData: formData});
},
function(err, httpResponse, body) { //Upload Callback
if (err) {
return console.error('upload failed:', err);
}
res.redirect('/console');
});
});
Then I am receiving the file for processing in the flask app, like:
#app.route('/api/resource/converter', methods = ['POST','GET'])
def converter_csv():
if request.method == 'POST':
f = request.form['file']
if not f:
abort(400)
print('-----Converting-------')
file = open("temp/converting.txt","w")
file.write(f)
#....conversion process...
# Finish the process
return Response(converted_file,status=200)
In my console for the localhost of the flask app, I am getting:
127.0.0.1 - - [09/Aug/2017 15:47:59] "POST /api/resource/converter HTTP/1.1" 200 -
However my nodejs app did not receive any response. It just got frozen.
I appreciate any orientation anyone can give me. Thanks.
I think flow.exec is not in proper order
router.post('/converttest', uploader.single('file'), function(req, res) {
var filePath = req.file.path;
fs.readFile(filePath, 'utf8', function(err, data) { //change format reading as required
try {
formData = {file:data}
requestPack.post({url:'http://127.0.0.1:5000/api/resource/converter', formData: formData});
} catch(err) {
return console.error('upload failed:', err);
res.redirect('/console')
}
fs.unlink(filePath);}); });
I ended up using requestify. Seems like they make it a little bit easier for beginners like me:
var requestify = require('requestify');
app.get('/convertupload', function(req,res){
res.render('pages/convertupload');
});
app.post('/converttest', uploader.single('file'), function(req,res){
var file = req.file,
result = {
error: 0,
uploaded: []
};
flow.exec(
function() { // Read temp File
fs.readFile(file.path,this);
},
function(err, data) { // Upload file to S3
var formData = {
file: data
};
requestify.post('http://127.0.0.1:5000/api/resource/converter', {
form: formData
})
.then(function(response) {
// Get the response body (JSON parsed or jQuery object for XMLs)
console.log(response)
response.getBody();
});
res.redirect('/login');
});
});

Upload file to servlet from node without saving it

On my node express server, I am receiving a pdf file. I am using the below code to get the pdf contents from the request
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function() {
console.log('PDF data is '+JSON.stringify(data));
});
Now that PDF content is available on node, I need to send it as it is to a J2EE server. In order to do that, I am first saving the PDF file in the node server, reading it from the node server and then piping it to request.post (https://github.com/request/request)
var req = require('request');
fs.writeFile('abc.pdf', data, 'binary', function(err) {
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
//send our data via POST request
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload')
});
This works fine. However, I feel the part of saving the PDF file on the node server and then reading it is (before posting to the J2EE server using request module) is completely unnecessary, as I am not making any changes to the file.
Once I have the PDF contents in 'data' variable, I would like to directly post them to the J2EE server. However, I have not been able to find a way to use the request module to directly post file contents. I have seen some examples related to POST using request module but they refer to formData. In my case, I don't have formData but instead reading the file from request and directly posting it to the J2EE server.
Is there a way to achieve this and avoid the file write and read?
EDIT
Below is my complete code
function upload(request, response) {
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function () {
fs.writeFile('abc.pdf', data, 'binary', function(err){
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myj2eeapp/Upload'));
})
})
}
You can pipe directly from the data request to the servlet
var req = require('request');
function upload(request, response) {
var target = req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload');
request.pipe(target);
target.on('finish', function () {
console.log('All done!');
//send the response or make a completed callback here...
});
}

Unable to get png file saved if I tried to process the image immediately

I am trying to fetch the image remote then process it by node-tesseract. Code following:
var request = require('request');
var fs = require('fs');
request.get('http://cn.bing.com/s/a/hpc18.png').pipe(fs.createWriteStream('bing.png'));
Code above is doing well and the png file will be saved correctly.
Then I want to process the png by tesseract ocr(node binding)
tesseract.process('bing.png', options, function (err, text) {
//do something
});
After running all code above, I found that the text is null. Then i checked the picture, the png file didn't generate correctly - it's an empty file.
Anyone could help? I tried to sleep some time between those two parts but it didn't work. Why even the png file wasn't generated?
Regards,
Lyu
Can you try this out:
var fs = require('fs');
var request = require('request');
var tesseract = require('tesseract');
request.get({url: 'http://cn.bing.com/s/a/hpc18.png', encoding: 'binary'}, function (err, response, body) {
fs.writeFile("bing.png", body, 'binary', function(err) {
if(err)
console.log(err);
else
tesseract.process('bing.png', options, function (err, text) {
//do something
});
});
});

How to upload a remote image in Node/request?

I would like to upload a remote image to my own server using Node and the request module. I've figure out how to upload local images using the following code:
var options = {
url: 'https://myownserver.com/images'
};
var req = request.post(options , function optionalCallback(err, httpResponse, body) {
console.log('Upload successful! Server responded with:', body);
});
var form = req.form();
form.append('file', fs.createReadStream(__dirname + '/testimg.png'));
What modifications would I need to make to this code to be able to upload a remote image? This is the image I have been working with: https://www.filepicker.io/api/file/egqDUkbMQlmz7lqKYTZO
I've tried using fs.createReadStream on the remote URL, but was unsuccessful. If possible, I would prefer not having to save the image locally before uploading it to my own server.
This is a piece of code I'm using with a scraper. I'm using the callback here so I can use this as the location when saving to my model. I'm putting the location of your image below, but in my code I use req.body.image.
var downloadURI = function(url, filename, callback) {
request(url)
.pipe(fs.createWriteStream(filename))
.on('close', function() {
callback(filename);
});
};
downloadURI('https://myownserver.com/images', __dirname + '/testimg.png', function(filename) {
console.log(done);
}

Resources