Chrome Extension Blob data issue - javascript

I am trying to create a blob from a canvas image from within a Chrome extension, however I am getting an error "Uncaught TypeError: object is not a function" when trying to create a Blob using any method!
var blob = new Blob();
var blob = new Blob(['body { color: red; }'], {type: 'text/css'});
are two examples that fail with the above error. I am actually trying to convert a DataURL to a blob so the code I am using (which also fails) is...
function dataURItoBlob(dataURI) {
'use strict'
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
I am assuming that Chrome will not support new blobs??

The issue was that the call to create a Blob was being done from a JS file, the correct place was the background JavaScript file. By moving the method to create the blob into the background file I as able to use it.

Related

Blazor Server-Side JS Invoking

Hi I'm trying to move the bytes of my video which is in c# to javascript to make the bytes into URL.createObjectURL on Blazor server-side
I moved the bytes using Js Invoke
.cs
if (!string.IsNullOrEmpty(item.PathFile))
{
//Byte Video
byte[] result = GetFile(item.PathFile);
if (result != null)
{
var url = await Js.InvokeAsync<string>("videoUrl", result);
data.ImageString = url;
}
}
.js
function videoUrl(value) {
var byteCharacters = atob(value);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
//Byte Array -> Blob
var file = new Blob([byteArray], { type: 'data:video/mp4;base64' });
//Blob -> Object URL
var fileURL = URL.createObjectURL(file);
return fileURL;
}
My problem is, I tried this script for a video with a size of 3 Mb it runs fine, but when I try for a 133Mb video I get an error:
Error: System.ArgumentException: The JSON value of length 139569235 is too large and not supported.
I've tried to fix it, but it still fails, it makes me a little frustrated
So is there a solution for my error ? or what should I do?
I thank you for any suggestions or feedback
So, reading on the AspNetDocs github, there is a startup option that can change the max message size, but I think it only applies to calls from JS to .Net (https://github.com/dotnet/AspNetCore.Docs/issues/21208). Worth a check though.
services.AddServerSideBlazor()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 32000);
Personally though, I would do as Mister Magoo said in the comment and either use an API or chunk the data and reassemble at the other end.

create and automatically force download file using js

I have used HTML file reader API to read the file,
and i got the below result
data:application/pdf;base64,JVBERi0xLjYNJeLjz9MNCjE2OSAwIG9iaiA8PC9MaW5lYXJpemVkIDEvTCAyMDgwNTMxL08gMTczL0UgMjg1ODM3L04gMjQvVCAyMDc3MDkyL0ggWyAxMTM2IDc1OV0+Pg1lbmRvYmoNICAgICAgICAgIA14cmVmDTE2OSA0Mg0wMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDE4OTUgMDAwMDAgbg0KMDAwMDAwMjAzMSAwMDAwMCBuDQowMDAwMDAyMTY0IDAwMDAwIG4NCjAwMDAwMDIzMTkgMDAwMDAgbg0KMDAwMDAwMjgzOCAwMDAwMCBuDQowMDAwMDAyODY0IDAwMDAwIG4NCjAwMDAwMDM3OTAgMDAwMDAgbg0KMDAwMDAwNDMyNCAwMDAwMCBuDQowMDAwMDA0NDE1IDAwMDAwIG4NCjAwMDAwMDU2MDcgMDAwMDAgbg0KMDAwMDAwNTY1MiAwMDAwMCBuDQowMDAwMDA1Njc3IDAwMDAwIG4NCjAwMDAwMDU3OTUgMDAwMDAgbg0KMDAwMDAwNTg0NSAwMDAwMCBuDQowMDAwMDA1ODcwIDAwMDAwIG4NCjAwMDAwMDU5ODYgMDAwMDAgbg0KMDAwMDAwNzQxOSAwMDAwMCBuDQowMDAwMDA3Nzk4IDAwMDAwIG4NCjAwMDAwMDgxMDQgMDAwMDAgbg0KMDAwMDAwODQxMyAwMDAwMCBuDQowMDAwMDA4OTQ0IDAwMDAwIG4NCjAwMDAwMDk2NTAgMDAwMDAgbg0KMDAwMDAxMDA1NiAwMDAwMCBuDQowMDAwMDEwMjIxIDAwMDAwIG4NCjAwMDAwMTA1NDIgMDAwMDAgbg0KMDAwMDAxMDc1MCAwMDAwMCBuDQowMDAwMDExMDM1IDAwMDAwIG4NCjAwMDAwMTEwOTYgMDAwMDAgbg0KMDAwMDAxMTQxMiAwMDAwMCBuDQo...AwMDAwIG4NCjAwMDIwNTkxMzggMDAwMDAgbg0KMDAwMjA2MjUxMyAwMDAwMCBuDQowMDAyMDYyOTE4IDAwMDAwIG4NCjAwMDIwNjI5NjYgMDAwMDAgbg0KMDAwMjA2MzMyNSAwMDAwMCBuDQowMDAyMDYzNDEyIDAwMDAwIG4NCjAwMDIwNjM2NDggMDAwMDAgbg0KMDAwMjA2NDU0NiAwMDAwMCBuDQowMDAyMDY1NTU0IDAwMDAwIG4NCjAwMDIwNjU1NzMgMDAwMDAgbg0KMDAwMjA2NTY1MCAwMDAwMCBuDQowMDAyMDY1Njg3IDAwMDAwIG4NCjAwMDIwNjU3MTggMDAwMDAgbg0KMDAwMjA2NTc4OSAwMDAwMCBuDQowMDAyMDY1OTIxIDAwMDAwIG4NCjAwMDIwNjYwNTMgMDAwMDAgbg0KMDAwMjA2NjE0NSAwMDAwMCBuDQowMDAyMDY2MjAyIDAwMDAwIG4NCjAwMDIwNjk5MDEgMDAwMDAgbg0KMDAwMjA2OTk1MSAwMDAwMCBuDQowMDAyMDcwMDE3IDAwMDAwIG4NCjAwMDIwNzAwNDkgMDAwMDAgbg0KMDAwMjA3MDA5OCAwMDAwMCBuDQowMDAyMDcwMTQyIDAwMDAwIG4NCjAwMDIwNzAxODggMDAwMDAgbg0KMDAwMjA3MDIxMCAwMDAwMCBuDQowMDAyMDcwMjc5IDAwMDAwIG4NCjAwMDIwNzAzMTcgMDAwMDAgbg0KMDAwMjA3MDM3NSAwMDAwMCBuDQowMDAyMDcwNDk5IDAwMDAwIG4NCjAwMDIwNzA1MzEgMDAwMDAgbg0KMDAwMjA3MDU1MiAwMDAwMCBuDQowMDAyMDcwNTc4IDAwMDAwIG4NCjAwMDIwNzY4NDMgMDAwMDAgbg0KdHJhaWxlcg08PC9TaXplIDE2OS9FbmNyeXB0IDE3MCAwIFI+Pg1zdGFydHhyZWYNMTE2DSUlRU9GDQ==
How to write a file and force download the same file using the above string?
Warning: I don't have IE available to test with, but this was based off code that DOES work under IE.
My DataURL is an image so I had to change out the header. You might not have to with your header -- but I left the code in place so you could see how it was done.
Thanks to IE, you need two different processes.
On IE, you convert your DataURI to a blob then download the blob.
On everything else, you would just download the URI itself.
document.getElementById("d_button").addEventListener("click", download);
var filename="testfile";
// FROM http://stackoverflow.com/questions/12168909/blob-from-dataurl
function dataURItoBlob(dataURI) {
// 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([ab], {
type: mimeString
});
return blob;
// Old code
// var bb = new BlobBuilder();
// bb.append(ab);
// return bb.getBlob(mimeString);
}
const dataURI = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
function download() {
if (window.navigator.msSaveBlob) { // for IE
const blob = dataURItoBlob(dataURI);
window.navigator.msSaveBlob(blob, `${filename}.png`);
return;
}
let dt = dataURI;
/* Change MIME type to trick the browser to downlaod the file instead of displaying it */
dt = dt.replace(/^data:image\/[^;]*/, "data:application/octet-stream");
/* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
dt = dt.replace(/^data:application\/octet-stream/, `data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=${filename}.png`);
this.href = dt;
}
Download this
I got answer using <a> tag force the download the file.
var element = document.createElement('a');
element.setAttribute('href',text );
element.setAttribute('download', filename);
element.setAttribute('target', '_blank');
element.style.display = 'none';
document.body.appendChild(element);
$("#page_header").removeClass('loader');
element.click();
I got another answer using force the download the file.
using this link install file saver (https://www.npmjs.com/package/file-saver)
result : 'data:application/pdf;base64,JVBERi0xLjYNJeLjz9MNCjE2OSAwIG9iaiA8PC9MaW5lYXJpemVkIDEvTCAyMDgwNTMxL08gMTczL0UgMjg1ODM3L04gMjQvVCAyMDc3MDkyL0ggWyAxMTM2IDc1OV0+Pg1lbmRvYmoNICAgICAgICAgIA14cmVmDTE2OSA0Mg0wMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDE4OTUgMDAwMDAgbg0KMDAwMDAwMjAzMSAwMDAwMCBuDQowMDAwMDAyMTY0IDAwMDAwIG4NCjAwMDAwMDIzMTkgMDAwMDAgbg0KMDAwMDAwMjgzOCAwMDAwMCBuDQowMDAwMDAyODY0IDAwMDAwIG4NCjAwMDAwMDM3OTAgMDAwMDAgbg0KMDAwMDAwNDMyNCAwMDAwMCBuDQowMDAwMDA0NDE1IDAwMDAwIG4NCjAwMDAwMDU2MDcgMDAwMDAgbg0KMDAwMDAwNTY1MiAwMDAwMCBuDQowMDAwMDA1Njc3IDAwMDAwIG4NCjAwMDAwMDU3OTUgMDAwMDAgbg0KMDAwMDAwNTg0NSAwMDAwMCBuDQowMDAwMDA1ODcwIDAwMDAwIG4NCjAwMDAwMDU5ODYgMDAwMDAgbg0KMDAwMDAwNzQxOSAwMDAwMCBuDQowMDAwMDA3Nzk4IDAwMDAwIG4NCjAwMDAwMDgxMDQgMDAwMDAgbg0KMDAwMDAwODQxMyAwMDAwMCBuDQowMDAwMDA4OTQ0IDAwMDAwIG4NCjAwMDAwMDk2NTAgMDAwMDAgbg0KMDAwMDAxMDA1NiAwMDAwMCBuDQowMDAwMDEwMjIxIDAwMDAwIG4NCjAwMDAwMTA1NDIgMDAwMDAgbg0KMDAwMDAxMDc1MCAwMDAwMCBuDQowMDAwMDExMDM1IDAwMDAwIG4NCjAwMDAwMTEwOTYgMDAwMDAgbg0KMDAwMDAxMTQxMiAwMDAwMCBuDQo...AwMDAwIG4NCjAwMDIwNTkxMzggMDAwMDAgbg0KMDAwMjA2MjUxMyAwMDAwMCBuDQowMDAyMDYyOTE4IDAwMDAwIG4NCjAwMDIwNjI5NjYgMDAwMDAgbg0KMDAwMjA2MzMyNSAwMDAwMCBuDQowMDAyMDYzNDEyIDAwMDAwIG4NCjAwMDIwNjM2NDggMDAwMDAgbg0KMDAwMjA2NDU0NiAwMDAwMCBuDQowMDAyMDY1NTU0IDAwMDAwIG4NCjAwMDIwNjU1NzMgMDAwMDAgbg0KMDAwMjA2NTY1MCAwMDAwMCBuDQowMDAyMDY1Njg3IDAwMDAwIG4NCjAwMDIwNjU3MTggMDAwMDAgbg0KMDAwMjA2NTc4OSAwMDAwMCBuDQowMDAyMDY1OTIxIDAwMDAwIG4NCjAwMDIwNjYwNTMgMDAwMDAgbg0KMDAwMjA2NjE0NSAwMDAwMCBuDQowMDAyMDY2MjAyIDAwMDAwIG4NCjAwMDIwNjk5MDEgMDAwMDAgbg0KMDAwMjA2OTk1MSAwMDAwMCBuDQowMDAyMDcwMDE3IDAwMDAwIG4NCjAwMDIwNzAwNDkgMDAwMDAgbg0KMDAwMjA3MDA5OCAwMDAwMCBuDQowMDAyMDcwMTQyIDAwMDAwIG4NCjAwMDIwNzAxODggMDAwMDAgbg0KMDAwMjA3MDIxMCAwMDAwMCBuDQowMDAyMDcwMjc5IDAwMDAwIG4NCjAwMDIwNzAzMTcgMDAwMDAgbg0KMDAwMjA3MDM3NSAwMDAwMCBuDQowMDAyMDcwNDk5IDAwMDAwIG4NCjAwMDIwNzA1MzEgMDAwMDAgbg0KMDAwMjA3MDU1MiAwMDAwMCBuDQowMDAyMDcwNTc4IDAwMDAwIG4NCjAwMDIwNzY4NDMgMDAwMDAgbg0KdHJhaWxlcg08PC9TaXplIDE2OS9FbmNyeXB0IDE3MCAwIFI+Pg1zdGFydHhyZWYNMTE2DSUlRU9GDQ=='
file_name : 'sample.jpg'
fileType : 'image/jpeg'
**Function Call**
this.urltoFile(result, file_name, fileType)
.then(function(file){
var blob = new Blob ([file], {type: fileType});
FileSaver.saveAs(blob, file_name);
this.loading = false;
});
**function definition**
urltoFile(url, filename, mimeType){
return (fetch(url)
.then(function(res){return res.arrayBuffer();})
.then(function(buf){return new File([buf], filename, {type:mimeType});})
)},

In-browser gzip decompression using HTML5 Blob API and createObjectURL?

I am investigating an idea to make use of the browsers built in gzip decompression facility by using the HTML5 Blob API. With a trick the browser may do the uncompressing when the Blob is referenced as an Object URL via URL.createObjectURL and then inserted into the DOM. It appears that the only obstacle is the ability to set Content-Encoding for the blob.
If it would be possible to set the content-encoding of the Blob Object to gzip the browser will decompress the Blob and it will be possible to return the result to a library or application. If this would be possible, it may result in a stable and fast decompressing solution that costs just a few bytes instead of for example 22.6kb for pako_inflate.min.js.
I hereby want to inform if anyone knows of a solution to use a javascript Blob to uncompress gzip data in the browser.
The code that I use to test via the browser console is the following. It will change the background of a page to green on success.
/* create blob */
var createBlobUrl = function(fileData,mimeType) {
var blob;
// Create blob
try {
blob = new Blob([fileData], {type: mimeType});
} catch (e) { // Backwards-compatibility
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
blob = new BlobBuilder();
blob.append(fileData);
blob = blob.getBlob(mimeType);
}
return URL.createObjectURL(blob);
};
/* CSS: body, * { background:green; } */
var zip = window.atob('H4sIAAAAAAAA/0vKT6nUUdBSqFZISkzOTi/KL81LsUovSk3Ns1aoBQCLj6wTHQAAAA==');
function str2bytes (str) {
var bytes = new Uint8Array(str.length);
for (var i=0; i<str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
var bloburl = createBlobUrl(str2bytes(zip),'text/css');
var link = document.createElement('link');
link.setAttribute('rel','stylesheet');
link.setAttribute('type','text/css');
link.setAttribute('href',bloburl);
document.head.appendChild(link);

Illegal Constructor error: convert Base64 to Blob fails on cordova

I want to convert my Base64 image to a blob in my cordova app project using AngularJS but i keep getting Illegal constructor error. I have tried a lot of the solutions given online but none seems to be working. Any help is appreciated.
var imageElement = angular.element(document.querySelector('#profileImg'));
var imageURI = dataURIToBlobURI(imageElement.attr('src'));
function dataURIToBlobURI(dataURI) {
// 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);
}
var bb = new Blob([ab], {type: 'image/png'});
return bb;
}
I keep getting an error over here new Blob([ab], {type: 'image/png'}) and dont seem to knw how to make it work. Only happens when the app is in Android or iOS not when viewed in Chrome.
I have tried the following but all to no avail.
var bb = new Blob(ab);
var bb = new Blob([ab]);
var bb = new Blob(dataURI);
Thanks
Kingsley! Possible, device where you could reproduce the error doesn't support Blob actually. Actually you could use two ways:
Firstly, check
polyfill or smth similar to fix your problem. It will allow you to use Blob as a constructor.
Secondly, you could use BlobBuilder except of Blob. Small exmaple below,
var bb = new BlobBuilder();
bb.append('blob content');
var blob = bb.getBlob('text/plain');
I used this to solve my problem. Just incase anyone runs into this problem. All solutions didnt work for me on my device. Just follow instructions and add the javascript file and you shud be fine. https://github.com/blueimp/JavaScript-Canvas-to-Blob
var b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +
'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +
'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7',
imageUrl = 'data:image/gif;base64,' + b64Data,
blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl);

How to create File object from Blob?

DataTransferItemList.add allows you to override copy operation in javascript. It, however, only accepts File object.
Copy event
The code in my copy event:
var items = (event.clipboardData || event.originalEvent.clipboardData);
var files = items.items || items.files;
if(files) {
var blob = Blob.fromDataURL(_this.editor.selection.getSelectedImage().toDataURL("image/png"));
files.add(blob);
}
The error in chrome:
Uncaught TypeError: Failed to execute add on DataTransferItemList: parameter 1 is not of type File.
Trying the new File(Blob blob, DOMString name)
In Google Chrome I tried this, according to the current specification:
var blob = Blob.fromDataURL(_this.editor.selection.getSelectedImage().toDataURL("image/png"));
var file = new File(blob, "image.png");
Problem here is, that Google Chrome doesn't stick to specifications very much.
Uncaught TypeError: Failed to construct File: Illegal constructor
Neither does Firefox in this case:
The method parameter is missing or invalid.
Trying the new File([Mixed blobParts], DOMString name, BlobPropertyBag options)
Solution suggested by #apsillers doesn't work too. This is non stadard method used (but useless) in both Firefox and Chrome.
Binary data
I tried to avoid blob, but the file constructor failed anyway:
//Canvas to binary
var data = atob( //atob (array to binary) converts base64 string to binary string
_this.editor.selection.getSelectedImage() //Canvas
.toDataURL("image/png") //Base64 URI
.split(',')[1] //Base64 code
);
var file = new File([data], "image.png", {type:"image/png"}); //ERROR
You can try that in console:
Chrome <38:
Chrome >=38:
Firefox:
Blob
Passing Blob is probably correct and works in Firefox:
var file = new File([new Blob()], "image.png", {type:"image/png"});
Firefox:
Chrome <38:
Chrome >=38:
Q: So how can I make File from Blob?
Note: I added more screenshots after #apsillers reminded me to update Google Chrome.
The File constructor (as well as the Blob constructor) takes an array of parts. A part doesn't have to be a DOMString. It can also be a Blob, File, or a typed array. You can easily build a File out of a Blob like this:
new File([blob], "filename")
This was the complete syntax which I had to use to convert a blob into a file, which I later had to save to a folder using my server.
var file = new File([blob], "my_image.png",{type:"image/png", lastModified:new Date().getTime()})
this works with me, from canvas to File [or Blob], with filename!
var dataUrl = canvas.toDataURL('image/jpeg');
var bytes = dataUrl.split(',')[0].indexOf('base64') >= 0 ?
atob(dataUrl.split(',')[1]) :
(<any>window).unescape(dataUrl.split(',')[1]);
var mime = dataUrl.split(',')[0].split(':')[1].split(';')[0];
var max = bytes.length;
var ia = new Uint8Array(max);
for (var i = 0; i < max; i++) {
ia[i] = bytes.charCodeAt(i);
}
var newImageFileFromCanvas = new File([ia], 'fileName.jpg', { type: mime });
Or if you want a blob
var blob = new Blob([ia], { type: mime });

Categories

Resources