Angular: Convert base64 string to Byte Array in IE - javascript

I am trying to convert a base64 string to byte array and open it as a pdf file in IE. The only problem is atob is not supported in IE, so trying to use Buffer like this:
let b64Data = myBase64Url.split(',', 2)[1];
var byteArray = new Buffer(b64Data ,'base64').toString('binary');
var blob = new Blob([byteArray], {type: 'application/pdf'});
window.navigator.msSaveOrOpenBlob(blob);
I am getting a popup successfully to open the file
But the file is corrupted
What am i doing wrong ? Is there a better way to convert base64 to byte array in IE ?

In order for the base64 to be properly decoded, it must be only the base64 data, i.e. no mimetype information preceding it.
You will also need to remove .toString('binary') so that you're passing a buffer instead of a string.

Related

What to use instead of Buffer(bitmap)

I'm using the following method to convert files into base64 encoding and it's been working fine for a long time, but I see now that Buffer is depricated.
// function to encode file data to base64 encoded string
function base64_encode(file) {
var bitmap = fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString("base64");
}
let base64String = base64_encode("Document.png");
Can someone please help me modify this to work with the new suggested method as I'm not sure how to modify it myself?
Thank you so much in advance.
It is not Buffer that is deprecated but its constructor, so instead of new Buffer() you use e.g. Buffer.from.
However fs.readFileSync already returns a Buffer if no encoding is specified, so there is not really a need to pass that to another buffer. Instead you can do return fs.readFileSync(file).toString("base64")
Using the Sync part of the API is most of the time something would like to avoid and if possible switch over to the promise-based API.

How to create a blob from a base64 string; javascript

Basically what the title says; I have a base64 string that encodes an image and I want to convert it into a blob so I can pass it into my File constructor. I realise many similar questions have been asked however many of the other answers make use of the atob function which has been deprecated; So im trying to look for alternatives.
Try this
var base64String = "dGVzdAo=";
var blob = new Blob([base64String], {type: 'text/plain'});

Base64 Decode embedded PDF in Typescript

Within an XML file we have a base64 encoded String representing a PDF file, that contains some table representations, i.e. similar to this example. When decoding the base64 string of that PDF document (i.e. such as this), we end up with a PDF document of 66 kB in size, which can be opened in any PDF viewer correctly.
On trying to decode that same base64 encoded string with Buffer in TypeScript (within a VSCode extension), i.e. with the functions below:
function decodeBase64(base64String: string): string {
const buf: Buffer = Buffer.from(base64String, "base64");
return buf.toString();
}
// the base64 encoded string is usually extracted from an XML file directly
// for testing purposes we load that base64 encoded string from a local file
const base64Enc: string = fs.readFileSync(".../base64Enc.txt", "ascii");
const base64Decoded: string = decodeBase64(base64Enc);
fs.writeFileSync(".../table.pdf", base64Decoded);
we end up with a PDF of 109 kB in size and a document that can't be opened using PDF viewers.
For a simple PDF, such as this one, with a base64 encoded string representation like this, the code above works and the PDF can be read in any PDF viewer.
I've also tried to directly read in the locally stored base64 encoded representation of the PDF file using
const buffer: string | Buffer = fs.readFileSync(".../base64Enc.txt", "base64");
though isn't producing something useful either.
Even with a slight adaptation of this suggestion, due to atob(...) not being present (with suggestions to replace atob with Buffer), which ended up in a code like this:
const buffer: string = fs.readFileSync(".../base64Enc.txt", "ascii");
// atob(...) is not present, other answers suggest to use Buffer for conversion
const binary: string = Buffer.from(buffer, 'base64').toString();
const arrayBuffer: ArrayBuffer = new ArrayBuffer(binary.length);
const uintArray: Uint8Array = new Uint8Array(arrayBuffer);
for (let i: number = 0; i < binary.length; i++) {
uintArray[i] = binary.charCodeAt(i);
}
const decoded: string = Buffer.from(uintArray.buffer).toString();
fs.writeFileSync(".../table.pdf", decoded);
I'm not ending up with a readable PDF. The "decoded" table.pdf sample ends up with 109 kB in size.
What am I doing wrong here? How can I decode a PDF such as the table.pdf sample to obtain a readable PDF document, similar to the functionality provided by Notepad++?
Borrowing heavily from answers to How to get an array from ArrayBuffer?, if you get a Uint8Array right from the Buffer using the Uint8Array constructor:
const buffer: string = fs.readFileSync(".../base64Enc.txt", "ascii");
const uintArray: Uint8Array = new Uint8Array(Buffer.from(buffer, 'base64'));
fs.writeFileSync(".../table.pdf", uintArray);
Writing the Uint8Array directly to the file guarantees there's no corruption due to encoding changes from moving to and from strings.
Just a note: the Uint8Array points to the same internal array of bytes as the Buffer. Not that it matters in this case, since this code doesn't reference the Buffer outside of the constructor, but in case someone decides to create a new variable for the output of Buffer.from(buffer, 'base64').

Blob's DataUri vs Base64 string DataUri

As you know & stated in w3 it is possible to create a url for a Blob object in javascript by using Blob's createObjectUrl. On the other hand, if we have a data as a Base64 encoded string we can present it as a Url with the format "data[MIMEType];base64,[data>]".
Let's suppose that I have a base64 encoded string that was generated from an image that is very popular on these days :) "The red dot" image in wikipedia.
var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";
I'm 100% sure that if I create a URL conforming the Data URI Scheme as stated above, then, I'll be able to put a link element and download it from the browser: please see the code example below:
var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";
var reddotLink = document.createElement("a");
reddotLink.target = "_blank";
reddotLink.href = "data:image/png;base64," + reddotB64;
document.body.appendChild(reddotLink);
reddotLink.click();
document.body.removeChild(reddotLink);
This works prettywell and displays the image in a new tab. On the other hand I'll try to create the link by using Blob as follow:
var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";
var reddotBlob = new Blob([atob(reddotB64)], { type: 'image/png' });
var reddotLink = document.createElement("a");
reddotLink.target = "_blank";
reddotLink.href = URL.createObjectURL(reddotBlob);
document.body.appendChild(reddotLink);
reddotLink.click();
document.body.removeChild(reddotLink);
This code is decoding base64 encoded string variable reddotB64 via atob function. And then, creating a Blob object and continues with URL.createObjectURL function. In that case, since I've decoded reddotB64 from base64 to binary and created a Blob of type image/png and then create object url from that I expect it to work but it's not working.
Do you have a clue why it's not working? Or am I missing anything on the standards? Or doing something wrong in Javascript?
Here is the answer. Looks like it is an encoding issue. In order to convert/decode Base64 string to binary(UInt8Array/byte) using atob is not enough. After using atob it is required to use UTF-16 character code: and we achieve this by using charCodeAt function for every character in the decoded string. As a result we get UTF-16 encoded binary string which is definately working. Just create a Blob and then call URL.createObjectURL.

How to send base64 encoded image string into JSON object in javascript?

I wanted to convert a image file into JSON object in javascript.
So I have converted image into a string using base64 encoding.
How to convert this string to JSON object?
Simple, set value to an keyObj.
var base64String = 'data:image/png;base64....'
var imgObj = {
url: base64String
}
<img src=''+ imgObj.url +''/>
I would create a new Image() and set the src to the image. Then onload of the image, draw it to a canvas (which can be in memory, doesn't need to be in the DOM), and from there use toDataURL(). See this page for more details: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

Categories