Blob from javascript binary string - javascript

I have a binary string created with FileReader.readAsBinaryString(blob).
I want to create a Blob with the binary data represented in this binary string.

Is the blob that you used not available for use anymore?
Do you have to use readAsBinaryString? Can you use readAsArrayBuffer instead. With an array buffer it would be much easier to recreate the blob.
If not you could build back the blob by cycling through the string and building a byte array then creating a blob from it.
$('input').change(function(){
var frb = new FileReader();
frb.onload = function(){
var i, l, d, array;
d = this.result;
l = d.length;
array = new Uint8Array(l);
for (var i = 0; i < l; i++){
array[i] = d.charCodeAt(i);
}
var b = new Blob([array], {type: 'application/octet-stream'});
window.location.href = URL.createObjectURL(b);
};
frb.readAsBinaryString(this.files[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="file">

Related

Substitute for Uint8Array in javascript?

Since my javascript program is going to upload documents to the server using the FormData object, and the documents are in base64 format, I need to convert a base64 string to a byte array, and this link seems to be the correct one for that:
Convert base64 string to ArrayBuffer:
function _base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
Unfortunately, my program depends on an older version of javascript which doesn't define Uint8Array.
Does anyone know if there's a alternative way of accomplishing what I want or if there is an alternative to Uint8Array that I can use?
thanks
Unluckly it seems that you don't have access to TypedArrays and their buffers, so you can use a simple array.
function _base64ToArray(base64) {
var binary_string = window.atob(base64);
var bytes = [];
for (var i = 0; i < binary_string.length; i++) {
bytes.push(binary_string.charCodeAt(i));
}
return bytes;
}
Using an array is it not the same as a buffer, but I hope this can solve your problem anyway.

Convert Base64 String to Javascript Uint16Array?

I'm working in an Javascript application that receives a base64 array. This array encodes a 16 bits per pixel raw image.
Thus, I would like to do some calculations in it. For this, I need to unpack this Base64 string in a Uint16Array, so I can iterate over pixels and perform the required calculations.
What are my options for doing that?
After some hours looking for a solution, I found a way for doing this:
function getData()
{
fetch("test_data/img_base64.txt")
.then(res => res.text())
.then((out) => {
rawString = window.atob(out);
uint8Array = new Uint8Array(rawString.length);
for(var i = 0; i < rawString.length; i++)
{
uint8Array[i] = rawString.charCodeAt(i);
}
uint16Array = new Uint16Array(uint8Array.buffer);
console.log(uint16Array);
})
.catch(err => { throw err });
}
First I fetch my base64 string from a file. Then using window.atob it is converted to a JavaScript string. After this, I need to fill a Uint8Array with every byte loaded from the string. Finally, I had to convert this Uint8Array, into the final Uint16Array.
That was tough to achieve exactly what I was looking. But I have found it.
You can use this function that converts a base64 string into a binary Uint16 Array
var BASE64_MARKER = ';base64,';
function convertDataURIToBinary(dataURI) {
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var array = new Uint16Array(new ArrayBuffer(rawLength));
for(i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}
If you're targeting Firefox and feeling adventurous you can shorten the function down to this:
var BASE64_MARKER = ';base64,';
function convertDataURIToBinaryFF(dataURI) {
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var raw = window.atob(dataURI.substring(base64Index));
return Uint8Array.from(Array.prototype.map.call(raw, function(x) {
return x.charCodeAt(0);
}));
};

Converting base64 Image to file object in JavaScript

I am trying to create a file object from a base64 image which was cut from another image. I am able to do it but the resulting file size is almost thrice the actual size. Below is the function that I am using:
convertDataURItoFile(dataURI, fileName) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob: any = new Blob([ia], { type: mimeString });
//A Blob() is almost a File() - it's just missing the two properties below which we will add
blob.lastModifiedDate = new Date();
blob.name = fileName;
//Cast to a File() type
return <File>blob;
}
Any idea on why the file size increasing so drastically? How can I compress it? Thanks in advance.
I am trying to create a file object from a base64 image which was cut
from another image. I am able to do it but the resulting file size is
almost thrice the actual size.
Cannot reproduce resulting .size of Blob being thrice the size of the content of input data URI. Do you mean the data URI .length can be thrice the size of Blob .size?
function convertDataURItoFile(dataURI, fileName) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ia], { type: mimeString });
//A Blob() is almost a File() - it's just missing the two properties below which we will add
blob.lastModifiedDate = new Date();
blob.name = fileName;
//Cast to a File() type
console.log(`input data size: ${datauriLength} Blob.size: ${blob.size}`);
return blob;
}
const [datauri, filename] = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAADCCAYAAAD+Wo90AAAABHNCSVQICAgIfAhkiAAAApVJREFUeJzt1DEBACAMwLCBf88ggZMeiYJeXTPnDEDY/h0A8GJUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkHcBRH8DgsmlTc8AAAAASUVORK5CYII=", "filename.png"];
const datauriLength = datauri.length;
const reader = new FileReader;
reader.onload = () => {
console.log(`data URI: ${reader.result}`)
document.querySelector("iframe").src = reader.result;
};
reader.readAsDataURL(convertDataURItoFile(datauri, filename));
<iframe></iframe>
If .name and .lastModifiedDate need to be added to Blob, you can substitute using File constructor for Blob, which expects file name parameter to be set at second parameter to File constructor, and optionally expected .lastModidied and or .lastModifiedDate parameters at third parameter to constructor.
function convertDataURItoFile(dataURI, fileName) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
// use `File` constructor here
var blob = new File([ia], fileName, { type: mimeString, lastModifiedDate: new Date() });
//A Blob() is almost a File() - it's just missing the two properties below which we will add
// blob.lastModifiedDate = new Date();
// blob.name = fileName;
//Cast to a File() type
console.log(`input data size: ${datauriLength} Blob.size: ${blob.size}`);
return blob;
}
const [datauri, filename] = ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAADCCAYAAAD+Wo90AAAABHNCSVQICAgIfAhkiAAAApVJREFUeJzt1DEBACAMwLCBf88ggZMeiYJeXTPnDEDY/h0A8GJUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkHcBRH8DgsmlTc8AAAAASUVORK5CYII=", "filename.png"];
const datauriLength = datauri.length;
const reader = new FileReader;
reader.onload = () => {
console.log(`data URI: ${reader.result}`)
document.querySelector("iframe").src = reader.result;
};
reader.readAsDataURL(convertDataURItoFile(datauri, filename));
<iframe></iframe>
You can also utilize fetch() to create and get Blob representation of data URI, see Answer by #Endless at Creating a Blob from a base64 string in JavaScript

Javascript: UInt8Array to Float32Array

I have some audio buffer in usigned 8bit PCM format need to play via web audio which only accept signed 32bit PCM. And now I have ArrayBuffer for pieces of pcm_u8 data(come from Uint8array). How can I convert it to Float32Array?
ECMAScript 2015 and onwards has TypedArray.from which converts any typed array (and indeed, any iterable) to the specified typed array format.
So converting a Uint8Array to a Float32Array is now as easy as:
const intArray = new Uint8Array()
const floatArray = Float32Array.from(intArray)
This function converts an ArrayBuffer to Float32Array
var convertBlock(buffer) { // incoming data is an ArrayBuffer
var incomingData = new Uint8Array(buffer); // create a uint8 view on the ArrayBuffer
var i, l = incomingData.length; // length, we need this for the loop
var outputData = new Float32Array(incomingData.length); // create the Float32Array for output
for (i = 0; i < l; i++) {
outputData[i] = (incomingData[i] - 128) / 128.0; // convert audio to float
}
return outputData; // return the Float32Array
}
This one converts a Uint8Array to Float32Array
var convertBlock(incomingData) { // incoming data is a UInt8Array
var i, l = incomingData.length;
var outputData = new Float32Array(incomingData.length);
for (i = 0; i < l; i++) {
outputData[i] = (incomingData[i] - 128) / 128.0;
}
return outputData;
}

Javascript. Append to blob

Because BlobBuilder is deprecated, we have to use Blob, so instead of
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(data);
var blob = bb.getBlob();
We do
var blob = new Blob([data]);
That is ok, but what if I want to append Data to same blob more times? Something like:
for(var i=0;i<10;i++){
bb.append(" "+i);
}
How to do it without BlobBuilder? Thanks all!
Thanks to minitech♦!
You answer moved me to answer my question. So what you show is again working with a variable and at the end write it to blob. I wanted so said update a blob, or with other words append to blob. So you can do it on this way:
var blob = new Blob([], {type: "text/plain"});
for (var i=0; i<10; i++){
blob = new Blob([blob," "+i], {type: "text/plain"});
}
Here is Fiddle:
http://jsfiddle.net/yuM2N/111/
[data] is an array of parts, so you can just append to an array:
var parts = [];
for (var i = 0; i < 10; i++) {
parts.push(" " + i);
}
var blob = new Blob(parts);

Categories