base64 decoded image error when opening, NodeJS - string

I am receiving string base64 encoded, when I try to decode and save in to an image file, it seems to be everything working fine, but when I download open the file, my viewer does not recognize it.
I know my string is a valid image because I use http://www.freeformatter.com/base64-encoder.html
and it sends me the right image.
Is there something I am missing?
var imagestring = "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";
var decodedImage = new Buffer(imagestring, 'base64');
fs.writeFile('imagedecoded.jpg', decodedImage , function(err) {});

Related

Convert an imagen from an url to base64 without downloading it

I want to generate a pdf with images and text, for this I'm using the jsPdf package which includes this method to add images.
addImage(imageData, format, x, y, width, height, alias, compression, rotation)
The imageData argument accepts base64 format data and this part is which I'm struggling with.
My images are not local but hosted in cloudinary and I would prefer not to download them, searching on the web I've found that if I don't want to download the image I will need:
Fetch the image data, for this I'm using node-fetch package(fetch in the code).
Convert the image data into a Buffer.
Finally encode that buffer into a base64.
This is my attempt so far:
const fetchImage = async () => {
const imageUrl = <url-of-my-image>;
const response = await fetch(imageUrl, {
compress: false
});
const dataUrlPrefix = `data:${response.headers.get('content-type')};base64,`;
const body = await response.text();
const buffer = Buffer.from(body)
const imageBase64 = buffer.toString('base64');
const imageDataUrl = dataUrlPrefix+imageBase64;
doc.text("Hello world!", 10, 10);
doc.addImage(imageDataUrl, 'webp', 15, 40, 120, 120)
doc.save("a4.pdf");
}
The code runs without errors but the image is not being inserted into the pdf, it just display the "Hello World!" text but nothing else.
My guess is that I'm doing something wrong in the converting/encoding process (before I add it to jsPdf) because if I convert my image with an online converter like this one the base64 string that results is successfully decoded into an actual image when using a online base64 decoder like this one, whereas when I run the base64 output from my nodejs code i.e. the output for the imageBase64 or imageDataUrl variables in the same base64 decoder it results in not image being decoded.

Save file from url base64 data to pdf

I am making a react app where I have a field that allows users to upload PDF files.
I have successfuly uploaded and sent the files as base64 string to the server and I do receive it, however I am having trouble with saving the file back to pdf, here is what I have tried:
const fs = require("fs");
const invoice = { fileData: "data:application/pdf;base64,JVBERi0xLjandtherestofthedatastring..." };
const invoiceFileContents = new Buffer.from(invoice.fileData, "base64");
fs.writeFileSync(__dirname + "invoicetest.pdf", invoiceFileContents);
This does create a pdf file, but I am unable to open it, Adobe says its broken.
I managed to solve it, the appended string infront of the whole data string data:application/pdf;base64, should be trimmed:
const invoiceFileContents = new Buffer.from(
invoice.fileData.substring(invoice.fileData.indexOf("base64") + 7),
"base64"
);

How to convert base64 string of an image to an uploadable file without writing it to a filesystem

I have a variable in my NodeJS application which contains base64 string of an image. I need to send a form to some server with POST request containing this image. The problem is I can't convert base64 string to an image without writing it to a filesystem. Here's my code:
const imagePath = path.resolve(__dirname, '../../../images/anomalies/' + Date.now() + '.png')
fs.writeFileSync(imagePath, img, { encoding: 'base64' })
setTimeout(() => {
fs.unlinkSync(imagePath)
}, 30_000)
const form = new FormData()
form.append('photo', fs.createReadStream(imagePath))
As you can see, I need to write base64 string to a file and then grab it with fs.createReadStream. Otherwise file won't upload. I tried converting it to ReadStream via stream-buffers (but server still not accepted that data) and also I tried to make a Blob from it but Node don't have blobs and all these modules on npm are either too old or don't have typings which is not great at all. I also tried Buffer.from(base64, 'base64'), which doesn't work as well.
Is there any way to create an uplodable image file from base64 encoded string without accessing filesystem in NodeJS?
You should be able to convert the Buffer object returned by fs.readFileSync to a base64 string
const base64Image = fs.readFileSync(imagePath).toString('base64')

Send base64 image using axios in nodejs

I am receiving a base64 encoded image from the client (as a screenshot) and would like to upload it to another server using multipart encoding
var base64Encoded="iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==";
const x =Axios({url:"https://slack.com/api/files.upload",method:"POST", data:{title:"Hello", file: <INSERT HERE>, filetype:"png", channel: "testchannel"},headers:{Authorization: authorization,'Content-Type': 'multipart/form-data'}});
I've tried a lot here
Converting it to a buffer
var buffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==", 'base64');
Converting the buffer into a readable stream
var buffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAYAAAC/zKGXAAAAK0lEQVR42u3KMQ0AAAgDsOFfJwcusMBL0t6tSToHJYqiKIqiKIqiKIri57hqIbTd/KhOmQAAAABJRU5ErkJggg==", 'base64');
console.log(buffer);
const readable = new Readable();
readable._read = function(){};
readable.push(buffer)
readable.push(null)
None of these seem to work. Slack API simply gives me a invalid form data response
It works if i upload via postman
PS: I have to send axios request using the nodejs server, not browser

Converting binary strings to Buffers in Node.js

I have a web service that takes a base 64 encoded string representing an image, creates a thumbnail of that image using the imagemagick library, then stores both of them in mongodb. I am doing this with the following code (approximately):
var buf = new Buffer(req.body.data, "base64"); //original image
im.resize({ srcData: buf, width: 256 }, function(err, stdout, stderr) {
this.thumbnail = new Buffer(stdout, "binary");
//store buf and stdout in mongo
});
You will notice that I am creating a Buffer object using the "binary" encoding, which the docs say not to do:
'binary' - A way of encoding raw binary data into strings by using
only the first 8 bits of each character. This encoding method is
deprecated and should be avoided in favor of Buffer objects where
possible. This encoding will be removed in future versions of Node.
First off I'm not sure what they are saying there. I'm trying to create a Buffer object and they seem to imply I should already have one.
Secondly, the source of the problem appears to be that the imagemagick resize method returns a string containing binary data. Doing typedef(stdout) return "string" and printing it out to the screen certainly appears to show a bunch of non-character data.
So what do I do here? I can't change how imagemagick works. Is there another way of doing what I'm trying to do?
Thats how I am doing the same with success, storing images in mongodb.
//original ---> base64
var thumbnail = new Buffer(req.body.data).toString('base64');
//you can store this string value in a mongoose model property, and save to mongodb
//base64 ---> image
var buffer = new Buffer(thumbnail, "base64");
I am not sure if storing images as base64 is the best way to do it
Please try this as your base64 might not be pre-handled:
var imgRawData =
req.body.images[0].replace(/^data:image\/png;base64,|^data:image\/jpeg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,/, "");
var yourBuffer = new Buffer(imgRawData, "base64");
Then, save the yourBuffer into MongoDB buffer.

Resources