node.js / gphoto2 - how to save file (jpg) - node.js

Im trying to build a web gui for a canon eos 7d using node.js (0.10.20), libgphoto2 (2.5.2.) and gphoto2 module for node on a Raspberry Pi (latest raspbian).
Everything seems to work fine except for saving the files in node.
im using the following code snippet:
app.get('/shoot', function(req, res){
camera.takePicture({download:true}, function(er, data){
res.header('Content-Type', 'image/jpeg');
res.send(data);
fs.writeFile("public/images/sampleImg.jpg", data);
});
});
The file created is unreadable/not a valid jpg image
using the cli tool for libgphoto creates a valid image:
pi#raspi /srv/node/eos $ gphoto2 --capture-image-and-download
so i assume the error is somewhere in the node-code for saving data
how would i properly save the data in node to a .jpg file?

I am working on something very similar.
I seem to remember needing to specify that the data from the camera was binary, something like:
app.get('/shoot', function(req, res){
camera.takePicture({download:true}, function(er, data){
res.header('Content-Type', 'image/jpeg');
res.send(new Buffer(data, 'binary'));
fs.writeFile(
"public/images/sampleImg.jpg",
new Buffer(data, 'binary'),
function (err){}
);
});
});
Shoot me an email if you want to collaborate.
http://tonyspiro.com/uploading-and-resizing-an-image-using-node-js/
http://lists.basho.com/pipermail/riak-users_lists.basho.com/2011-May/004270.html

Related

Uploading image using angular 4 and nodejs

I am using angular 4 and node using multer to upload image. Everything is running fine there is no error but I dont see the file in the folder. Here is the code.
<td><input type="file" (change)="fileChange($event)" placeholder="Upload file" accept=".pdf,.jpeg,.png"></td>
In component
return this.http.post('http://localhost:3000/api/doc/uploadfile', FormData , {headers:this.headerss}).map((res: Response)=>{
const data=res.json();
console.log(data);
return data;
}).
catch(this.handleError);
It shows everything being submitted fine
Than in nodejs I am using multer
var upload=multer({dest: './uploads/'}).single('avatar');
router.post('/uploadfile', function(req, res){
upload(req, res, function(err){
if(err){
console.log(err);
return err;
}
console.log("request"+ req)
return res.send("completed"+ req)
})
There is no error everything goes fine. But I dont see any image being loaded. Please let me know how can I fix this...Thanks
I had to remove content-type and it worked fine

ExpressJS Post download works but download windows wont appear?

im trying to create a download for a user but somehow my download doesnt work even tho it works?Let me explain :
Server post request :
app.post('/downloadRequest', function (req, res) {
var fileName = "testname.txt";
var file = __dirname +'/test.txt';
res.download(file,fileName,function(err) {
if(err) throw err;
console.log("downloaded");
});
});
When im calling it,no error message appears. Also it shows "downloaded" in the console.Im clueless..

Sails.JS file upload - can't get a file on req.file()

I've just begun using Sails.JS and I tried to make a simple file upload. In Sails.JS, I've done this:
uploadFile: (req, res) => {
req.file('avatar').upload({
dirname: '../../assets/uploads'
}, function (err, uploadedFiles){
if (err) return res.serverError(err);
return res.json({
message: uploadedFiles.length + ' file(s) uploaded successfully!',
files: uploadedFiles
});
});
}
For Postman, I've done this:
The problem is, after I upload a file via Postman, I don't get a file in req.file(). However, console.log(req) does show my uploaded file's binary (or something like that). I just can't figure out what happened.

Show BASE64 video with node/express

So, bit of an odd problem. I have a bunch of media files saved as base64 strings in mongo, some are images, some are videos.
I made an API for getting the media files:
app.get('/api/media/:media_id', function (req, res) {
media.findById(req.params.media_id)
.exec(function (err, media) {
if (err) {
res.send(err);
}
var file = new Buffer(media.file, 'base64');
res.writeHead(200, {'Content-Type': media.type, 'Content-Transfer-Encoding': 'BASE64', 'Content-Length': file.length});
res.end(file);
});
});
Now, images have no problems. They load just fine, both directly from the API, and when I call the API from a front-end (for example <img src="/api/media/23498423">)
THE PROBLEM
If I fetch a video from a front-end, like the images - but with a video- or object-tag:
<video src="/api/media/3424525" controls></video>
there's no problem, but if I load the video in a browser directly from the API:
http://localhost:8080/api/media/3424525
the server process crashes, no errors. It simply just freezes up. And we're not talking about huge video files - it's a 1.5MB video.
The media type in the header for all the videos I'm testing with is video/mp4. Oh, and just to be clear: if I do the same with images, everything works perfectly.
EDIT:
Okay, so as suggested by #idbehold and #zeeshan I took a look at gridfs and gridfs-stream, and for the purpose of my app, this certainly is what I should have used in the first place. However, after implementing gridfs in my app, the problem still persists.
app.get('/api/media/:media_id', function (req, res) {
gfs.findOne({ _id: req.params.media_id }, function (err, file) {
if (err) {
return res.status(400).send(err);
}
if (!file) {
return res.status(404).send('');
}
res.set('Content-Type', file.contentType);
res.set('Content-Disposition', 'inline; filename="' + file.filename + '"');
var readstream = gfs.createReadStream({
_id: file._id
});
readstream.on("error", function (err) {
console.log("Got an error while processing stream: ", err.message);
res.end();
});
readstream.pipe(res);
});
});
When I call the media file (be it image or video) from a front-end, within a HTML tag, everything works out fine. But if I load a video (again, smallish videos from 1.5mb to max 6mb total size) directly in the browser, the server process freezes. To be a bit more clear: I am testing on windows, and the server app (server.js) is run in console. The console and the process it is running is what freezes. I cannot load any more pages/views in the node app, and I cannot even stop/kill/shutdown the node app or the console.
Streaming videos directly to/from GridFS using gridfs-stream either with mongodb-native db instance or mongoose.
var mongo = require('mongodb'),
Grid = require('gridfs-stream'),
db = new mongo.Db('yourDatabaseName', new mongo.Server("127.0.0.1", 27017)),
gfs = Grid(db, mongo);
//store
app.post('/video', function (req, res) {
req.pipe(gfs.createWriteStream({
filename: 'file_name_here'
}));
res.send("Success!");
});
//get
app.get('/video/:vid', function (req, res) {
gfs.createReadStream({
_id: req.params.vid // or provide filename: 'file_name_here'
}).pipe(res);
});
for complete files and running project:
Clone node-cheat direct_upload_gridfs, run node app followed by npm install express mongodb gridfs-stream.
Truly an odd problem...
I could be way off, but it's worth a shot:
One of the differences when opening a url directly from the browser is that the browser will also try to fetch http://localhost:8080/favicon.ico (while trying to find the tab icon). Maybe the problem is not related to your video code, but rather to some other route, trying to handle the /favicon.ico request?
Have you tried using wget or curl?
I don't know the answer, maybe this is a dumb suggestion, but what is the browser you are using? Maybe something from Microsoft causes the problem...

How to upload a file and then display its contents in Node.Js Express app?

I'm trying to find an answer to this question for a long time: I need to upload a text/html file through my Node.Js express app and to save its contents into a variable for further treatment.
I can make the multipart form, of course, and post the content, but what I can access so far is only req.files which contains information about the file, but not the actual contents.
How do I get the actual text/html contents from the file?
I don't want to save it to my server, just pass on the content to my app and get rid of the file, so I don't want to use a module like formidable.
Can anyone help please?
Thank you!
The file is saved by default in a temporary folder (likely /tmp). You need to open the file, read its contents, and then delete it.
You'll want to use this API: http://nodejs.org/api/fs.html
And you could do this:
fs = require('fs');
fs.readFile(req.files.path, function (err, data) {
if (err) throw err;
// data will contain your file contents
console.log(data)
// delete file
fs.unlink(req.files.path, function (err) {
if (err) throw err;
console.log('successfully deleted ' + req.files.path);
});
});
Use multer https://github.com/expressjs/multer with the option inMemory: true.
As a crude example you'll want to do something like this.
app.post('test', function(req, res, next) {
var result = '';
multer({
inMemory: true,
onFileUploadData: function(file, data) {
result += data;
},
onFileUploadComplete: function(file) {
console.log(result); // This is what you want
}
})(req, res, next);
});

Resources