Node JS createWriteStream download image - node.js

I have the following code which downloads an image from a URL and then performs some action:
var file = fs.createWriteStream(local_file);
var request = https.get(file_link, function(response) {
var request_response = response.pipe(file);
request_response.on('finish', function(){}};
However when viewing the download image in a browser, I'm getting a whole page of random characters and texts, which seems like an encoding issue.
My question is, how do I download an image using Node JS with the correct encoding?$
Thanks!

You can try with this, using the request module.
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');
});

Related

How do I set my images uploaded to S3 with nodejs script to display instead of download?

I have a node js script that uploads files to AWS S3 through the command line. The problem Im having is when I try to view the file in the browser it automatically downloads it.
I have done some research and most other posts point out the headers, but I have verified the headers are correct (image/png)
Additionally, when I upload the same file through the AWS console (log into AWS), I am able to view the file within the browser.
var fs = require('fs');
var path = require('path');
AWS.config.update({region: myRegion});
s3 = new AWS.S3({apiVersion: '2006-03-01'});
var uploadParams = {
Bucket: process.argv[2],
Key: '', // Key set below
Body: '', // Body set below after createReadStream
ContentType: 'image/jpeg',
ACL: 'public-read',
ContentDisposition: 'inline'
};
var file = process.argv[3];
var fileStream = fs.createReadStream(file);
fileStream.on('error', function(err) {
console.log('File Error', err);
});
uploadParams.Body = fileStream;
uploadParams.Key = path.basename(file);
s3.putObject(uploadParams, function(errBucket, dataBucket) {
if (errBucket) {
console.log("Error uploading data: ", errBucket);
} else {
console.log(dataBucket);
}
});
I get successful upload, but unable to view file in browser as it auto downloads.
You have to specify the contentDisposition as part of request headers. You can not specify it as part of request paramenters. Specify it in headers explicitly as below .
var params = {Bucket : "bucketname" , Key : "keyName" , Body : "actualData"};
s3.putObject(params).
on('build',function(req){
req.httpRequest.headers['Content-Type'] = 'application/pdf' ; // Whatever you want
req.httpRequest.headers['ContentDisposition'] = 'inline';
}).
send( function(err,data){
if(err){
console.log(err);
return res.status(400).json({sucess: false});
}else{
console.log(success);
return res.status(200).json({success: true});
}
});
Code to upload obejcts/images to s3
module.exports = function(app, models) {
var fs = require('fs');
var AWS = require('aws-sdk');
var accessKeyId = "ACESS KEY HERE";
var secretAccessKey = "SECRET KEY HERE";
AWS.config.update({
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey
});
var s3 = new AWS.S3();
app.post('/upload', function(req, res){
var params = {
Bucket: 'bucketname',
Key: 'keyname.png',
Body: "GiveSomeRandomWordOraProperBodyIfYouHave"
};
s3.putObject(params, function (perr, pres) {
if (perr) {
console.log("Error uploading data: ", perr);
} else {
console.log("Successfully uploaded data to myBucket/myKey");
}
});
});
}
The above code will make sure the object has been uploaded to s3. You cab see it listed in s3 bucket in the browser but you cant view its contents in s3 bucket.
You can not view items within S3. S3 is a storage box. you can only download and upload elements in it. If you need to view the contents you would have to download and view it in the browser or any explorer of your choice. If you simply need to list the objects in s3. Use the below code.
Code to list objects of s3
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: 'mykey', secretAccessKey: 'mysecret', region: 'myregion'});
var s3 = new AWS.S3();
var params = {
Bucket: 'bucketName',
Delimiter: '/',
Prefix: 's/prefix/objectPath/'
}
s3.listObjects(params, function (err, data) {
if(err)throw err;
console.log(data);
});
Use S3 list to list the elements of S3. This way you can view them. Create a hyperlink for each of the listed item and make it point to s3 download url. This way you can view in the browser and also download it if you need.
In case if you need to view the contents of it via node JS, use the code below to load the image as if you are loading it from a remote URL.
Code to Download contents:
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('httpo://s3/URL' 'name.png', function(){
console.log('done');
});
Code to load image into a buffer :
const request = require('request');
let url = 'http://s3url/image.png';
request({ url, encoding: null }, (err, resp, buffer) => {
// typeof buffer === 'object'
// Use the buffer
// This buffer will now contains the image data
});
Use the above to load the image into a buffer. Once its in buffer, you can manipulate it the way you need. The above code wont downloads the image but it help you to manipuate the image in s3 using a buffer.
Contains Example Code. The link will contain Specific Node JS code examples for uploading and Manipulating objects of s3. use it for reference.

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

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
});
});
});

upload binary file to redmine with node

I try to upload a file to redmine with node, I can upload and attach text files, but when I try to upload a binary file I get the token but the file doesn't work. I tried with json, xml and binary, ascii, base64 encoding.
I want upload binary files because I'm doing end to end test testing I want open Issues with screenshots, and upload a report.
I'm using node-rest-client for service calling
Could someone give me any suggestion to fix this problem?
Thanks,
I define the class RMClient
var Client = require('node-rest-client').Client;
var Q = require('q');
var RMClient = function(baseUri, apiToken){
this._apiToken = apiToken;
var client = new Client();
client.registerMethod('openIssue', baseUri+'/issues.json', 'POST');
client.registerMethod('uploadFile', baseUri+'/uploads.json', 'POST');
client.registerMethod('getIssues', baseUri+'/issues.json', 'GET');
this._client = client;
};
option 1:
var deferred = Q.defer();
var file fs.readFileSync(filePath);
//code for sending file to redmine uploads.json
return deferred.promise;
Option 2
var deferred = Q.defer();
var rs = fs.createReadStream(filePath, {'flags': 'r', 'encoding': null, 'autoClose': true});
var size = fs.statSync(filePath).size;
var file = '';
rs.on('error', function(err){
deferred.reject(err);
});
rs.on('data', function(chunk){ file += chunk; });
rs.on('end', function(){
//code for sending file to redmine uploads.json
});
return deferred.promise;
Code that I use to upload the file:
try{
if(!file){
throw new Error('File must\'nt be void');
}
var rmc = new RMClient(myRMURI, myAPItoken);
var headers = {
'X-Redmine-API-Key': rmc._apiToken,
'Content-Type': 'application/octet-stream',
'Accept':'application/json',
'Content-Length': size
};
var args = {
'data':file,
'headers': headers
};
if(parameters){
args.parameters = parameters;
}
rmc._client.methods.uploadFile(args, function(data, response){
if(response.statusCode != 201){
var err = new Error(response.statusMessage);
deferred.reject(err);
return;
}
var attach = JSON.parse(data);
console.log(attach);
if(data.errors){
var msg = ''.concat.apply('', attach.errors.map(function(item, i){
return ''.concat(i+1,'- ',item,(i+1<attach.errors.length)?'\n':'');
}));
console.error(msg);
deferred.reject(Error(msg));
}else{
deferred.resolve(attach.upload.token);
}
});
}catch(err){
console.error(err);
deferred.reject(err);
}
I faced the same issue and solved it this way:
Use "multer";
When you have an uploaded file, make a request using node "request" module, with req.file.buffer as body.
Then uploading files using the Rest API, you have to send the raw file contents in the request body, typically with Content-Type: application/octet-stream. The uploaded file doesn't need any further encoding or wrapping, esp. not as multipart/form-data, JSON or XML.
The response of the POST request to /uploads.xml contains the token to attach the attachment to other objects in Redmine.

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