Node.js convert bitmap string data to base64 - node.js

I have a server which receives bitmap string in endpoint. Something like that:
TkxSNdgbAAAgNgEBnA8AAAQDeAAAAAAAAAAAAAAAAgCcWZRTtVplbBt0w3PjNeMVToGHAbTADO4P
f/g7YfJnW1HeU0YSZlGmWTY4Vi8y8Bl1nCNHwG/Qu+GGwmLGGs07LxtnA2smOTd5wPhg8HjMH6OL
c8B8ZiZZmllLOmsyYw6yTCNcPyI+eMxMzxlPkWPi0NLF6cWpxc3M28y24WbxcB4b/hpR7DXgx8HG
h2smGzRLNEw0jvKa5/Hj4eE8R5vHYZZlHoYPivP5MTkyNZJrEotbmfOZWYYpHaQcuBz6M8RjkoxZ
y5JrjmtmLUO8452nD6gPuPzQSI8BxzdIviHcIeTF60GPJash6wFPIUcgazB8c/wPww+rgP3gTeFp
mPhY7E7E1sYuQm9zJvIkPJ0f/Bz4/NDmAMAvNdiH2AfJE84DzBb5B2OyZhxeJ/wD+YnHwE7AP/Lo
0hmTPZGN8cZhxmjmaaYefAs82g37CfHAMPNCPkobkiSmZSpzOGa+zmcYYB9ID9eE86C/GZ53szHw
mMjZwtnhdemmY0bn5AOzH7hczPAJ/BkMDobmnLnLecskwzHDM8MVwyQ2c4wbxw8H7pB86xlvMO5g
Is there anyway to convert this data to base64 string?

You can do this in two steps:
Read URL into response buffer
Convert data to base 64
My example code
const fetch = require("node-fetch");
async function fetchpicture() {
const response = await fetch('https://pixabay.com/photos/stadttheater-freiburg-main-page-5002861/');
const picture = await response.buffer();
const b64 = picture.toString('base64')
return b64;
}
fetchpicture().then(b64 => console.log(b64));
You will get
PCFET0NUWVBFIGh0bWw+CjwhLS1baWYgbHQgSUUgN10+IDxodG1sIGNsYXNzPSJuby1qcyBpZTYgb2xkaWUiIGxhbmc9ImVuLVVTIj4gPCFbZW5kaWZdLS0+CjwhLS1baWYgSUUgN10+ICAgIDxodG1sIGNsYXNzPSJuby1qcyBpZTcgb2xkaWUiIGxhbmc9ImVuLVVTIj4gPCFbZW5kaWZdLS0+CjwhLS1baWYg

Related

Encrypt compressed data using zlib and cryptojs

I'm in node js, trying to compress an object using zlib.deflate and then encrypt it using cryptojs AES.
Then, when I try to get the original value, I fail on the zlib.inflate call with the error: "incorrect header check".
const zlib = require('zlib');
const { AES, enc } = require('crypto-js');
const obj = {
a: "a",
b: "b"
};
const inputToDeflate = JSON.stringify(obj);
const compressed = zlib.deflateSync(inputToDeflate);
const encrypted = AES.encrypt(compressed.toString(), 'f11').toString();
const decrypted = AES.decrypt(encrypted, 'f11');
const decompressed = zlib.inflateSync(decrypted.toString(enc.Utf8));
I think you're losing zlib header when converting it to string before encryption. We need to change this compressed.toString() some way that the header still preserve inside, something like base64 encoding.
const buffer = Buffer.from(compressed).toString("base64")
const encrypted = AES.encrypt(buffer, 'f11').toString();
Decryption is remind the same, but we need to decode the result back from base64 to original zlib data like before.
const decrypted = AES.decrypt(encrypted, 'f11').toString(enc.Utf8);
const decryptedBuffer = Buffer.from(decrypted,'base64')
const decompressed = zlib.inflateSync(decryptedBuffer);
const resultString = decompressed.toString()
That's it. But I have suggestion here to do encryption part first before compression. Because the result string is different. Take a look in this full code :
Full Code
const zlib = require('zlib');
const { AES, enc } = require('crypto-js');
const obj = {
a: "a",
b: "b"
};
const inputToDeflate = JSON.stringify(obj);
const compressed = zlib.deflateSync(inputToDeflate);
// Compact the data to base64
const buffer = Buffer.from(compressed).toString("base64")
const encrypted = AES.encrypt(buffer, 'f11').toString();
console.log("compressed + base64 + encrypted length",encrypted.length)
const decrypted = AES.decrypt(encrypted, 'f11').toString(enc.Utf8);
// Convert the result from base64 to original compressed data
const decryptedBuffer = Buffer.from(decrypted,'base64')
const decompressed = zlib.inflateSync(decryptedBuffer);
// Convert buffer to string
const resultString = decompressed.toString()
// vice versa
console.log(resultString)
Output:
compressed + base64 + encrypted length 88
{"a":"a","b":"b"}
Suggestion
const zlib = require('zlib');
const { AES, enc } = require('crypto-js');
const obj = {
a: "a",
b: "b"
};
const inputData = JSON.stringify(obj);
const encrypted = AES.encrypt(inputData, 'f11').toString();
const compressed = zlib.deflateSync(encrypted);
console.log("encrypted + compressed length",encrypted.length)
const decompressed = zlib.inflateSync(compressed);
const decrypted = AES.decrypt(decompressed.toString(), 'f11').toString(enc.Utf8);
console.log(decrypted)
Output:
encrypted + compressed length 64
{"a":"a","b":"b"}
I think it much more efficient to do encryption first and then compression.

How to convert image.png to binary in NodeJS?

I am trying to consume Azure Forms Recognizer API, where I have to provide the body in the form of "[Binary PNG data]" as stated here.
The connection seems the be working fine, however I am getting this response:
{"error":{"code":"InvalidImage","innerError":{"requestId":"73c86dc3-51a3-48d8-853b-b6411f54c51e"},"message":"The input data is not a valid image or password protected."}}
I am using a png that is my local directory and I've tried converting it in many different ways including:
fs.readFile('test.png', function(err, data){
if (err) throw err;
// Encode to base64
let encodedImage = new Buffer(data, 'binary').toString('base64');
// Decode from base64
var decodedImage = new Buffer(encodedImage, 'base64').toString('binary');});
or
let data_string = fs.createReadStream('test.png');
and many others. None of them seem to work and I always get the same response from my post request.
I would appreciate if anyone could share how to convert this png into the correct format. Thank you in advance
To base 64:
const file = fs.readFileSync('/some/place/image.png')
const base64String = Buffer.from(file).toString('base64')
Then pass the base64String to Azure
If you want just a BLOB so a binary file, you can do this
const file = fs.readFileSync('/some/place/image.png')
const blob = Buffer.from(file)
const processFile = (file: any) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(){
const binaryData = Buffer.from(reader.result as string,'binary');
console.log(binaryData);
};
}

export to excel from a byte [] in angular

I have the response json from the backend (spring boot):
private byte[] archivoExcel;
private String extension;
private String mime;
What I need in angular is to get this byte [] and export it to excel, for this my answer json in angular is:
export class RespuestaExportar {
archivoExcel: ArrayBuffer;
extension: string;
mime: string;
}
and in my component.ts file I have:
this.reversionesService.getReversionesExportarSeguimiento(this.solicitud).subscribe(res => { this.respuestaExportar=res; let file = new Blob([this.respuestaExportar.archivoExcel], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
var fileURL = URL.createObjectURL(file); window.open(fileURL); }
When I run the 'export' button, it consumes correctly, and it downloads the excel, but this file is damaged. Do I need one more step to solve it? or there is another alternative, since I need to get this byte [] from the backEnd.
I think you can guide yourself from this service that I perform for my backend (SpringBoot) I send a responseObject as json
ObjectResponse response = new ObjectResponse();
ByteArrayInputStream in = getExcel();
byte[] array = new byte[in.available()];
in.read(array);
httpStatus = HttpStatus.OK;
response.setResultado(array);
return new ResponseEntity<>(response, httpStatus);
and I get a Json response with the structure that sent the data is that when serializing it, the response.getResult arrives in base64, that is, already transformed to the client that receives it.
So in my frontend (Angular) I proceed to transform it into a Blob and be able to work the file.
this.subcriber = this.reporteService.generarExcel (). subscribe ((b64Data: any) => {
const byteCharacters = atob (b64Data.result);
const byteNumbers = new Array (byteCharacters.length);
for (let i = 0; i <byteCharacters.length; i ++) {
byteNumbers [i] = byteCharacters.charCodeAt (i);
}
const byteArray = new Uint8Array (byteNumbers);
let blob = new Blob ([byteArray], {type: 'application / vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
const url = window.URL.createObjectURL (blob);
const anchor = document.createElement ('a');
anchor.download = `file.xlsx`;
anchor.href = url;
anchor.click ();
messageService = {
state: false,
messages: null
};
}, (err) => {
this.subcriber.unsubscribe ();
})
I hope it helps you

Saving Data URI as Image?

On a node server I would like to save uploaded datauri data as an image. To do this I've tried decoding the content of this png-
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAIAAAFlEcHbAAAAB3RJTUUH1gMWFjk7nUWcXQAAAAlwSFlzAABOIAAATiABFn2Z3gAAAARnQU1BAACxjwv8YQUAAAAeSURBVHjaY7h79y7DhAkTGIA04/Tp0xkYGJ49ewYAgYwLV/R7bDQAAAAASUVORK5CYII=
And saving it as a .png extension. Looks like there is more too it than that. How do I decode the datauri and save it as a file?
I've created a library to be used with Node.js that helps with encoding and decoding of data URI schemes. I believe it can help you, check:
https://github.com/DiegoZoracKy/image-data-uri
Using this library, in your case, the code would be:
'use strict';
const ImageDataURI = require('image-data-uri');
const dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAIAAAFlEcHbAAAAB3RJTUUH1gMWFjk7nUWcXQAAAAlwSFlzAABOIAAATiABFn2Z3gAAAARnQU1BAACxjwv8YQUAAAAeSURBVHjaY7h79y7DhAkTGIA04/Tp0xkYGJ49ewYAgYwLV/R7bDQAAAAASUVORK5CYII=';
const fileName = 'decoded-image.png';
ImageDataURI.outputFile(dataURI, filePath);
I was trying to decode the data using atob and saving this as a png file. I'm instead saving it base64 encoded but specifying the encoding in the write buffer.
fs.writeFileSync('tmp/myfile.png', new Buffer(data, 'base64'));
You can convert your data uri to a blob using below code:
function dataURItoBlob(dataURI) {
var byteStr;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteStr = atob(dataURI.split(',')[1]);
else
byteStr = unescape(dataURI.split(',')[1]);
var mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0];
var arr= new Uint8Array(byteStr.length);
for (var i = 0; i < byteStr.length; i++) {
arr[i] = byteStr.charCodeAt(i);
}
return new Blob([arr], {type:mimeStr});
}
and then you can append this blob data to from data and upload it as a file:
var blob = dataURItoBlob(dataURI);
var fd = new FormData(document.forms[0]);
fd.append("image", blob);

How do I parse a data URL in Node?

I've got a data URL like this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
What's the easiest way to get this as binary data (say, a Buffer) so I can write it to a file?
Put the data into a Buffer using the 'base64' encoding, then write this to a file:
var fs = require('fs');
var string = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
var regex = /^data:.+\/(.+);base64,(.*)$/;
var matches = string.match(regex);
var ext = matches[1];
var data = matches[2];
var buffer = Buffer.from(data, 'base64');
fs.writeFileSync('data.' + ext, buffer);
Try this
const dataUrl = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
const buffer = Buffer.from(dataUrl.split(",")[1], 'base64');
I also met such questions (parsing and validating data URL) recently and found the following workaround: https://gist.github.com/bgrins/6194623
I created 2 packages to make working with data URL easier in the code. Here they are:
https://github.com/killmenot/valid-data-url
https://github.com/killmenot/parse-data-url
Check out examples
I was looking into the sources of Node.js and stumbled upon this code that decodes a data URL into a Buffer. Although the function is not public and exclusively intended to parse encoded ES modules, it sheds light on aspects of data URLs that are apparently not considered by some other answers: the content of data URLs must not be base64 encoded and may be URL encoded, and it may even be unencoded.
Essentially, the Node.js logic boils down to something like the code below plus error handling:
const parsed = new URL(url);
const match = /^[^/]+\/[^,;]+(?:[^,]*?)(;base64)?,([\s\S]*)$/.exec(parsed.pathname);
const { 1: base64, 2: body } = match;
const buffer = Buffer.from(decodeURIComponent(body), base64 ? 'base64' : 'utf8');
This will correctly handle different encodings of a Javascript file with the content console.log("Node.js");:
data:text/javascript,console.log("Node.js");
data:text/javascript,console.log(%22Node.js%22)%3B
data:text/javascript;base64,Y29uc29sZS5sb2coIk5vZGUuanMiKTs=
The resulting buffer can be converted into a string if required with buffer.toString().
This method works for me
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var data = dataURI.split(',')[1];
var byteString = Buffer.from(data, "base64");
// separate out the mime component
var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([byteString], { type: mimeString });
return blob;
}
to use
var uri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
dataURItoBlob(uri)

Resources