How to convert Blob to File in JavaScript
Asked Answered
E

9

266

I need to upload an image to NodeJS server to some directory. I am using connect-busboy node module for that.

I had the dataURL of the image that I converted to blob using the following code:

dataURLToBlob: function(dataURL) {
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) {
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = decodeURIComponent(parts[1]);
        return new Blob([raw], {type: contentType});
    }
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
}

I need a way to convert the blob to a file to upload the image.

Could somebody help me with it?

Edouard answered 26/11, 2014 at 21:27 Comment(3)
Files are Blobs, just tack on the meta properties and you're good to go.Leodora
The default for a blob when uploading it is blob. So, I first extracted the name of the file I was cropping and then gave the same filename so the cropped file while uploading it to server by doing form.append("blob",blob, filename);.Edouard
@Edouard did my answer below help out? Is so, please mark it as the correct answer.Walter
W
221

This function converts a Blob into a File and it works great for me.

Vanilla JavaScript

function blobToFile(theBlob, fileName){
  //A Blob() is almost a File() - it's just missing the two properties below which we will add
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
}

TypeScript (with proper typings)

public blobToFile = (theBlob: Blob, fileName:string): File => {
  const b: any = theBlob;
  //A Blob() is almost a File() - it's just missing the two properties below which we will add
  b.lastModifiedDate = new Date();
  b.name = fileName;
    
  //Cast to a File() type
  return theBlob as File;
}

Usage

const myBlob = new Blob();

//do stuff here to give the blob some data...

const myFile = blobToFile(myBlob, "my-image.png");
Walter answered 1/4, 2015 at 12:7 Comment(11)
I think the cast should happen first so you don't need to use any in TypeScript. See this example.Boni
This does not work for all purposes. Adding this "File" to an ajax call will not set the filename correctly.Anastassia
This is not a good solution, the produced object still a blob.Josey
@Josey It's been a while now, but if I recall correctly a file is a type of blob, so this should workWalter
Hey Chris, I did not want to be offended you. Just wanted point out the the object type will be Blob and not File :(. Maybe I just needed something else.Josey
Just add b.__proto__ = File.prototype, and your solution becomes a dream that even tricks b instanceOf File to trueMufinella
Please note that lastModifiedDate is deprecated ( developer.mozilla.org/en-US/docs/Web/API/File/lastModifiedDate ), you should now use lastModified, setting lastModified throws an error in Firefox if the blob accidentally happens to be an instance of File already.Dragon
this throws error Cannot assign to read only property 'name' of object '[object File]'Cuman
This should not be the accepted answer, https://mcmap.net/q/108776/-how-to-convert-blob-to-file-in-javascript or https://mcmap.net/q/108776/-how-to-convert-blob-to-file-in-javascript should be.Czardom
Thanks a lot for this. new File() does not work straightforward on Cordova. Didn't realize that a file was just a type of blob if it weren't for this answer.Evasion
@JacobPoulRichardt You're correct, but this can can be fixed by adding the file name to the formdata like this: formData.append("file", yourFileObj, yourFileObj.name);Freckly
B
428

You can use the File constructor:

var file = new File([myBlob], "name");

As per the w3 specification this will append the bytes that the blob contains to the bytes for the new File object, and create the file with the specified name http://www.w3.org/TR/FileAPI/#dfn-file

Brobdingnagian answered 27/7, 2015 at 21:29 Comment(11)
This is what I was looking for, the one difference is the first argument is actually an array so I used it as: var file = new File([myBlob], "name");Hawkshaw
Yes. I am looking for this solution too. Stamplay server can not get the file name from blob object. So I need to convert it back to file. But Safari do not support file API... back to 0 now :(Trull
Exactly what I was looking for. Thanks for this. Other solutions keep the file name to be 'bolb' whatever I changes it to, but your solution is keeping my file name.Lithotomy
File constructors do not work e.g. in PhantomJS: TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')Carrollcarronade
Edge has currently (2017-10-04) a bug that prevents the usage of this constructor. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…Weil
Be sure to add file type, otherwise it will not work properly. new File([myBlob], "name", { type: "image/jpeg", });Affecting
this is throwing ` ReferenceError: File is not defined` for meSwats
dumb way fd = new FormData; fd.append('f', new Blob, "name"), fd.get('f') :)Pressey
IE11 is not supporting new File() constructor, is there any alternative to convert a blob to File type ? assigning a filename and lastdateModified to blob is not working.Merwyn
You can add image name using timestamp like this. var file = new File([blobImage], ${Date.now()}.png);Directions
The File ctor method does not work for me on Ionic Capacitor on Native Devices - iOS, Android. Using the method that morphs the Blob object does work, however.Disaffiliate
W
221

This function converts a Blob into a File and it works great for me.

Vanilla JavaScript

function blobToFile(theBlob, fileName){
  //A Blob() is almost a File() - it's just missing the two properties below which we will add
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
}

TypeScript (with proper typings)

public blobToFile = (theBlob: Blob, fileName:string): File => {
  const b: any = theBlob;
  //A Blob() is almost a File() - it's just missing the two properties below which we will add
  b.lastModifiedDate = new Date();
  b.name = fileName;
    
  //Cast to a File() type
  return theBlob as File;
}

Usage

const myBlob = new Blob();

//do stuff here to give the blob some data...

const myFile = blobToFile(myBlob, "my-image.png");
Walter answered 1/4, 2015 at 12:7 Comment(11)
I think the cast should happen first so you don't need to use any in TypeScript. See this example.Boni
This does not work for all purposes. Adding this "File" to an ajax call will not set the filename correctly.Anastassia
This is not a good solution, the produced object still a blob.Josey
@Josey It's been a while now, but if I recall correctly a file is a type of blob, so this should workWalter
Hey Chris, I did not want to be offended you. Just wanted point out the the object type will be Blob and not File :(. Maybe I just needed something else.Josey
Just add b.__proto__ = File.prototype, and your solution becomes a dream that even tricks b instanceOf File to trueMufinella
Please note that lastModifiedDate is deprecated ( developer.mozilla.org/en-US/docs/Web/API/File/lastModifiedDate ), you should now use lastModified, setting lastModified throws an error in Firefox if the blob accidentally happens to be an instance of File already.Dragon
this throws error Cannot assign to read only property 'name' of object '[object File]'Cuman
This should not be the accepted answer, https://mcmap.net/q/108776/-how-to-convert-blob-to-file-in-javascript or https://mcmap.net/q/108776/-how-to-convert-blob-to-file-in-javascript should be.Czardom
Thanks a lot for this. new File() does not work straightforward on Cordova. Didn't realize that a file was just a type of blob if it weren't for this answer.Evasion
@JacobPoulRichardt You're correct, but this can can be fixed by adding the file name to the formdata like this: formData.append("file", yourFileObj, yourFileObj.name);Freckly
P
72

Joshua P Nixon's answer is correct but I had to set last modified date also. so here is the code.

var file = new File([blob], "file_name", {lastModified: 1534584790000});

1534584790000 is an unix timestamp for "GMT: Saturday, August 18, 2018 9:33:10 AM"

Profanatory answered 8/11, 2018 at 10:24 Comment(2)
Points for not breaking instanceof like the accepted answerFukuoka
side note, if anyone is doing this and doesn't want to hard code that it was last modified in august 2018, you can always put lastModified: Date.now() and that'll return the current time in milliseconds! (just like how the example given is august 18 2018 at 9:33:10 in milliseconds)Cantina
C
41

Typescript

public blobToFile = (theBlob: Blob, fileName:string): File => {       
    return new File(
        [theBlob as any], // cast as any
        fileName, 
        {
            lastModified: new Date().getTime(),
            type: theBlob.type 
        }
    )
}

Javascript

function blobToFile(theBlob, fileName){       
    return new File([theBlob], fileName, { lastModified: new Date().getTime(), type: theBlob.type })
}

Output

screenshot

File {name: "fileName", lastModified: 1597081051454, lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time), webkitRelativePath: "", size: 601887, …}
lastModified: 1597081051454
lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time) {}
name: "fileName"
size: 601887
type: "image/png"
webkitRelativePath: ""
__proto__: File
Cowslip answered 10/8, 2020 at 17:33 Comment(0)
E
30

For me to work I had to explicitly provide the type although it is contained in the blob by doing so:

const file = new File([blob], 'untitled', { type: blob.type })
Ehling answered 19/11, 2019 at 16:50 Comment(0)
C
21

My modern variant:

function blob2file(blobData) {
  const fd = new FormData();
  fd.set('a', blobData, 'filename');
  return fd.get('a');
}
Columbine answered 13/2, 2018 at 9:56 Comment(3)
To add a filename to the resulting file use: fd.set('a', blobData, 'filename')Tolbooth
It fails in some IOS device when fd.setAnhanhalt
I had to add the file name with the extension to make it work right. Like: fd.set('a', blobData, 'filename.jpg')Tristan
H
6
var blob = new Blob(["Hello, world!"], { type: "text/plain;charset=utf-8" });

var file = new File([blob], "name.txt");

Now you can upload as .txt file

Hueyhuff answered 22/9, 2022 at 19:8 Comment(0)
A
1

This problem was bugging me for hours. I was using Nextjs and trying to convert canvas to an image file.

I used the other guy's solution but the created file was empty.

So if this is your problem you should mention the size property in the file object.

new File([Blob], `my_image${new Date()}.jpeg`, {
  type: "image/jpeg",
  lastModified: new Date(),
  size: 2,
});

Just add the key the value it's not important.

Abrahamsen answered 20/10, 2020 at 17:6 Comment(2)
size isn't a valid optionPressey
Not working bro !! , Blob is actually the object right ?Lath
C
-4

I have used FileSaver.js to save the blob as file.

This is the repo : https://github.com/eligrey/FileSaver.js/

Usage:

import { saveAs } from 'file-saver';

var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
saveAs(blob, "hello world.txt");

saveAs("https://httpbin.org/image", "image.jpg");
Cryptanalysis answered 7/11, 2020 at 10:36 Comment(2)
this dose not answer the questionPressey
he asked to convert a file not save a fileCowslip

© 2022 - 2024 — McMap. All rights reserved.