Node.js pipe image into memory and display it - node.js

I am making a Node.js/Electron application that downloads and displays images. I am downloading an image from the internet using request. I want to save this image in memory and display it without saving the file on the local hard drive. I am aware I could accomplish what I am asking here by inserting <img src="url"> into the DOM, but this is a heavily simplified version of my code and what I am trying to accomplish can not be done with that.
var image = fs.createWriteStream(?); // Is there anyway to save the image to memory?
request(url).pipe(image);
$('img').exampleScriptToSetImage(image); // And is there any way to display that image in a element without saving it to the local disk and loading its path?

Indeed! You can pipe your requested image data into a concat stream, convert the buffer to base64, and set the base64 encoding as your image source.
var path = require('path')
var request = require('request') // or hyperquest, simple-get, etc...
var concat = require('concat-stream')
var image = request(url)
image.pipe(concat({ encoding: 'buffer' }, function (buf) {
var ext = path.extname(file.name).slice(1) // assuming you have the file name
if (ext === 'svg') ext = 'svg+xml'
var src = 'data:image/' + ext + ';base64,' + buf.toString('base64')
var img = document.createElement('img')
img.src = src
document.body.appendChild(img)
})

Related

Serve clickable download URL in NodeJS

At my endpoint in my NodeJS server, after retrieving an audio file stored as a Buffer in MongoDB, I want to represent it with a URL (much like how you do with URL.createObjectURL(blob) in the frontend on the browser). I then plan to res.render() the URL in HTML through Handlebars on the client, so that the user can click on it to download it:
<a href={{url}}>Click me to download the file!</a>
In the NodeJs server, I have converted the MongoDB Buffer into a JavaScript ArrayBuffer through:
var buffer = Buffer.from(recordingFiles[0].blobFile);
var arrayBuffer = Uint8Array.from(buffer).buffer;
I am unsure where to proceed from here. I seen solutions using fs or res.download(), but they don't seem applicable to my situation. Thanks in advance for any help!
Hopefully this can help.
var blob = new Blob(BUFFER, {type: "audio mime type"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
Do you always need to preload the audio file onto the page?
If not, then I would advise you to add a separate endpoint to download the file on demand. The frontend link can send a get request to the endpoint and download the file only if the user clicked it.
Otherwise you'd always be downloading the buffer behind the scenes, even if the user didn't intend to download it. This is especially problematic on slow connections.
Frontend:
<a href={{`${baseUrl}/download/${audioId}`}}>Click me to download the file!</a>
Backend:
const stream = require('stream');
app.get('/download/:audioId', function (request, response) {
// Retrieve the tag from our URL path
const audioId = request.params.audioId;
const fileData; // TODO: Get file buffer from mongo.
const fileContents = Buffer.from(fileData, 'base64');
const readStream = new stream.PassThrough();
readStream.end(fileContents);
response.set('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', '<your MIME type here>');
readStream.pipe(response);
});
A list of relevant MIME types can be found here.

Save binary image to file

I make an API request which returns a binary image. How can I save it to a file like photo.png on my machine? Doing some research, I've tried the following but when I open the image, my machine says it's damaged:
const buffer = new Buffer(imageBinary);
const b64 = buffer.toString("base64");
const path = `temp/${userId}`;
const url = path + "/photo.png";
if (!fs.existsSync(path)) fs.mkdirSync(path);
if (fs.existsSync(url)) fs.unlinkSync(url)
fs.createWriteStream(url).write(b64);
return url;
Edit: Here is the binary data FYI: https://gist.github.com/AskYous/1fd26dc0eb02b4ec1672dcf5c61a34df
You do not need to re-encode the buffer as base64. Just write the binary buffer as is:
fs.createWriteStream(url).write(imageBinary);

Converting blob from database to an image javascript

I have a database, where one of the tables has a blob field and I want to display it as an image. I can't really find any solution for this - any working npm package or a sample of code would be useful. I'm using reactjs and nodejs.
What you want to do is create an URL that you can pass to the img src of the HTML img
JS
var url = window.URL || window.webkitURL;
var imageSrc = url.createObjectURL('your blob');
document.querySelector("#myimage").src = imageSrc;
HTML
<img id="myimage"/>
Method 1 create readable stream and pipe to response
var stream = require('stream');
var bufferStream = new stream.PassThrough();
bufferStream.end(new Buffer( blob, 'binary' ));
res.writeHead(200, {
'Content-Type' : 'image/jpg'
});
// res is standered express res object
bufferStream.pipe(res)
Method 2
pass blob to base64
var bufferBase64 = new Buffer( blob, 'binary' ).toString('base64');
show image
class Example extends React.Component{
render() {
return <img src={"data:image/jpeg;" + bufferBase64} />
}
}
reference
https://stackoverflow.com/.../how-to-create-a-readstream-with-a-buffer-using-nodejs

Image not Uploading while using multer single image input option?

I am using multer to upload single image...
router.post('/register', upload.any(), function(req,res,next){
var img = req.files;
}
If I print the img the it is showing the object properly( originalname, mimeType, size etc) but when i trying to add the propertys in individual variable ( originalname = img.originanae;/req.files.originalename;) then originalname is showing undefined.
Why ??
use req.files[0].originalname instead of req.files.originalname

Can't write/append to JSON file in Node Webkit

I want to have persistent memory (store the user's progress) in a .json file in %AppData%. I tried doing this according to this post, but it doesn't work. For testing purposes I'm only working with storing one object.
The code below doesn't work at all. If I use fs.open(filePath, "w", function(err, data) { ... instead of readFile(..., it does create a json file in %AppData%, but then it doesn't write anything to it, it's always 0 bytes.
var nw = require('nw.gui');
var fs = require('fs');
var path = require('path');
var file = "userdata.json";
var filePath = path.join(nw.App.dataPath, file);
console.log(filePath); // <- This shows correct path in Application Data.
fs.readFile(filePath ,function (err, data) {
var idVar = "1";
var json = JSON.parse(data);
json.push("id :" + idVar);
fs.writeFile(filePath, JSON.stringify(json));
});
If anyone has any idea where I'm messing this up, I'd be grateful..
EDIT:
Solved, thanks to kailniris.
I was simply trying to parse an empty file
There is no json in the file you try to read. Before parsing data check if the file is empty. If it is then create an empty json, push the new data into it then write it to the file else parse the json in the file.

Resources