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);
Related
I receive a raw data of an excel when I send my http request. I am using fileSaver package to save base64 files like pdf (turned into a blob) with it and it works alright. what I receive is as the image below. My question is how can I turn this into saveable blob without data corruption? note that when I save this sting as file in postman it saves fine.
this approach did not work and saves a corrupt excel that cannot be opened:
var blob = new Blob([s2ab(response)], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
FileSaver.saveAs(blob, action.payload.culture + ".xlsx");
Solved in this way:
before you do anything add arrayBuffer as response-type to your http req header.
firstly convert the binary of arraybuffer to base64:
export function arrayBufferToBase64(buffer: ArrayBufferLike) {
let binary = "";
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
then decode this base64 to a blob:
export const base64toBlob = (b64Data: string, contentType = "", sliceSize = 512): Blob => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
};
Now download it:
const blob = base64toBlob(arrayBufferToBase64(response.data));
FileSaver.saveAs(blob, `${orderType}_${formatedDates.from}_${formatedDates.to}.xlsx`);
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
I can convert a blob to string using FileReader, but I want to convert it back:
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
base64data = reader.result;
var blobToSend = base64data.substr(base64data.indexOf(',')+1);
rtcMultiConnection.send({"command":{
"recording":blobToSend,
"type":blob.type,
"size":blob.size
}});
}
This is sent with https://github.com/muaz-khan/RTCMultiConnection but the main question is how to reconstruct the blob after being sent. Sadly sending the blob as is didn't work.
source: Creating a Blob from a base64 string in JavaScript
This method correctly converts back base64 data to the original binary data.
For the sake of performance improvements, the data is processed in blocks of the size of sliceSize.
NOTE: source is in TypeScript
public static Base64ToBlob(b64Data, contentType = "", sliceSize = 512): Blob
{
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize)
{
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++)
{
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
From a previous answer on Stackoverflow I found the bzip2 lib for javascript: https://github.com/antimatter15/bzip2.js
It does pretty much what I need, except that I need the output as a Uint8Array instead of a string.
I use this function from the bzip2 lib:
bzip2.simple = function(bits){
var size = bzip2.header(bits);
var all = '', chunk = '';
do{
all += chunk;
chunk = bzip2.decompress(bits, size);
}while(chunk != -1);
return all;
}
I found a way of transforming the string output into a Uint8Array :
function str2ab(str)
{
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
};
But for speed reasons I was hoping there was a good way to re-write the original bzip2 function so it directly outputs as a Uint8Array.
One of the main problems I’m having is that I don’t know how to dynamically increase the array.
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">