image url to file() object using js - javascript

For a registration module in my vue app I let users upload images in a form. I upload these images to my storage and save the download url of this photo in the registration. When editing a registration I need to get the photo's out of the storage which is simple since I got the url. But I need it to be a file() object. I have found ways to turn it into a blob but it needs to be a file. How can I do this?

It can be done by requesting a blob and generating a File object. It is necessary to specify the MIME type of the blob.
const urlToObject= async()=> {
const response = await fetch(image);
// here image is url/location of image
const blob = await response.blob();
const file = new File([blob], 'image.jpg', {type: blob.type});
console.log(file);
}

The ES6 way, with Promise:
const blobUrlToFile = (blobUrl:string): Promise<File> => new Promise((resolve) => {
fetch(blobUrl).then((res) => {
res.blob().then((blob) => {
// please change the file.extension with something more meaningful
// or create a utility function to parse from URL
const file = new File([blob], 'file.extension', {type: blob.type})
resolve(file)
})
})
})

Since you are letting the user upload a file, you already have the file as a File object.
But if you wanna convert it to a blob for making some edits and convert it back to a File object, you can use the File() constructor for converting a blob to a File.
const file = new File([blob], "imagename.png");
Also, notice that the File() constructor takes an array of blobs as argument and not a single blob.

Related

I am turning base64 string to its previous value(image) using blob and file but when sending to the server it says `unprocessable content`

I have following problem. I am saving image to local storage by converting it to string base 64 format via file reader.readAsDataUrl. it is stored properly. Now I want to send that image to the server. I am using fetch to fetch url and then blobing it to form a file. when i console.log i get same file as I got before converting to base 64 exept name is different. but when sending to the server that file object it returns unprocecable content. The image must be an image.
fr.readAsDataURL(value);
fr.addEventListener("load",() => {
// assigning freader value to state and refferencing it to `newVal`
// saving only happens inside `this` eventListener
try{
const newVal = generalInfo[iName][0] = fr.result;
// console.log(newVal)
setGeneralInfo({...generalInfo,newVal});
localStorage.setItem("generalP", JSON.stringify(generalInfo));
}
catch(e){
alert("photo sized more than 1mb cannot be uploaded");
// get back to current state values using LC
getFromLC();
}
})
and here is retrieving from local storage and turning it into file
const getSendingData = async () => {
//strip off the data uri prefix
// getting base64 string as data url
const response = await fetch(generalInfo.photo[0]);
const blob = await response.blob();
const file = new File([blob],'image',{type: blob.type});
// continue from here
console.log(file)
}

play a blob video file

imagine i have a video file and i want to build a blob URL from that file then play it in a html page, so far i tried this but i could not make it work ...
var files = URL.createObjectURL(new Blob([someVideoFile], {type: "video/mp4"}));
document.getElementById(videoId).setAttribute("src", files);//video tag id
document.getElementById(videoPlayer).load();//this is source tag id
document.getElementById(videoPlayer).play();//this is source tag id
it gives me a blob URL but wont play the video... am i doing something wrong? i am pretty new to electron so excuse me if my code is not good enough
i saw the similar questions mentioned in comments but they dont work for me as they dont work for others in those pages....
I know this is an old question, but it still deserves a working answer.
In order to play a video in the renderer context, you're on the right track: you can use a blob url and assign it as the video source. Except, a local filepath is not a valid url, which is why your current code doesn't work.
Unfortunately, in electron, currently there are only 3 ways to generate a blob from a file in the renderer context:
Have the user drag it into the window, and use the drag-and-drop API
Have the user select it via a file input: <input type="file">
Read the entire file with the 'fs' module, and generate a Blob from it
The third option (the only one without user input) can be done as long as nodeIntegration is enabled or if it is done in a non-sandboxed preloader. For accomplishing this via streaming vs. loading the entire file at once, the following module can be used:
// fileblob.js
const fs = require('fs');
// convert system file into blob
function fileToBlob(path, {bufferSize=64*1024, mimeType='aplication/octet-stream'}={}) {
return new Promise((resolve,reject) => {
// create incoming stream from file
const stream = fs.createReadStream(path, {highWaterMark:bufferSize});
// initialize empty blob
var blob = new Blob([], {type:mimeType});
stream.on('data', buffer => {
// append each chunk to blob by building new blob concatenating new chunk
blob = new Blob([blob, buffer], {type:mimeType});
});
stream.on('close', () => {
// resolve with resulting blob
resolve(blob);
});
});
}
// convert blob into system file
function blobToFile(blob,path, {bufferSize=64*1024}={}) {
return new Promise((resolve,reject) => {
// create outgoing stream to file
const stream = fs.createWriteStream(path);
stream.on('ready', async () => {
// iterate chunks at a time
for(let i=0; i<blob.size; i+=bufferSize) {
// read chunk
let slice = await blob.slice(i, i+bufferSize).arrayBuffer();
// write chunk
if(!stream.write(new Uint8Array(slice))) {
// wait for next drain event
await new Promise(resolve => stream.once('drain', resolve));
}
}
// close file and resolve
stream.on('close', () => resolve());
stream.close();
});
});
}
module.exports = {
fileToBlob,
blobToFile,
};
Then, in a preloader or the main context with nodeIntegration enabled, something like the following would load the file into a blob and use it for the video player:
const {fileToBlob} = require('./fileblob');
fileToBlob("E:/nodeJs/test/app/downloads/clips/test.mp4", {mimeType:"video/mp4"}).then(blob => {
var url = URL.createObjectURL(blob);
document.getElementById(videoId).setAttribute("src", url);
document.getElementById(videoPlayer).load();
document.getElementById(videoPlayer).play();
});
Again, unfortunately this is slow for large files. We're still waiting for a better solution from electron:
https://github.com/electron/electron/issues/749
https://github.com/electron/electron/issues/35629
Try
video.src = window.URL.createObjectURL(vid);
For more details please refer to this answer

Is there a way to convert a type of Blob image to a type of File in Javascript? [duplicate]

This question already has answers here:
How to convert Blob to File in JavaScript
(9 answers)
Closed 3 years ago.
I am using the ngx-image-cropper, https://www.npmjs.com/package/ngx-image-cropper, and need to programmatically set the default loaded image. The cropper provides an outlet to do so through the imageFileChanged API input. It requires a File type and any image I've attempted to pull in has been in Blob format.
Is there a way to convert a Blob to a File?
I haven't found any specific examples of someone doing this with this particular image cropper. I am open to using another one if this functionality is included and it's well supported.
I can successfully get a Blob image from our own server or a random api, I just haven't found a way to convert that to a File.
Is there an alternative to the HttpClientModule that would produce a different type?
The image cropper in its basic usage takes in an file and uses that in the cropping tool. Is there a way to do this programmatically?
I'm happy to provide any code, I just don't know what would help in this case.
Convert Only
let file = new File([blob], "name.extension");
If you are trying to download a blob and convert it to any file type, you do something like this. Since you said you are downloading and pulling an image.
Fetch Convert, Download, Extension
function download(url, filename) {
// Request
fetch(url, {
mode: 'no-cors' /*{mode:'cors'}*/
// Callback
}).then((transfer) => {
// Return blob
return transfer.blob();
// Return data
}).then((bytes) => {
// Create an element
let elm = document.createElement('a');
// Add blob data to element
elm.href = URL.createObjectURL(bytes);
// Download blob data with certain extension
elm.setAttribute('download', filename);
elm.click()
}).catch((error) => {
console.log(error);
})
}
download('http://BLOB', 'EXTENSION');
I think this is the convert function your looking for How to convert Blob to File in JavaScript
Typescript:
public convert = (blb: Blob, f:string): File => {
var b: any = blb;
b.lastModifiedDate = new Date();
b.name = f;
return <File>theBlob;
}
const Data = new Blob();
let file = Convert(Data, 'extension');
Turns out, this is a duplicate. This will help you out. Thanks to #Raymond for pointing me to that article.

JS: How to create a file of type image, from base64

I'm trying to convert png file, produced by https://html2canvas.hertzen.com/ to a blob file, that I'd send to API.
Code below produces such output that API does not throw 400, however the file is somehow corrupted.
Is there something wrong with the way I construct the blob?
const data = new FormData();
const [, binary] = image.toDataURL().split(',');
const blobFile = new Blob([window.atob(binary)], { type: 'image/png' });
data.append('attachments[]', blobFile, 'screenshot.png');
Alright, turns out canvas is already well equipped for translating itself to blob. All you have to do is use canvas.toBlob(cb) and you are ready to go.

Upload file (HTML5 canvas image → file) in javascript

Attempting to upload an image as a file per these instructions: https://github.com/graphcool-examples/react-graphql/blob/master/files-with-apollo/src/components/CreatePage.js#L48-L65
The above-referenced instructions work on mobile and desktop/laptop:
handleDrop(files) {
let data = new FormData()
data.append('data', person.avatar)
fetch('https://api.graph.cool/file/v1/___PROJECTID___', {
method: 'POST',
body: data
})
[...]
}
However, if instead of directly uploading an image, I want to crop it first. So I:
I save the file (using React) in the local state first,
Crop it,
Then upload it.
However, this process only seems to work on a desktop/laptop, but not on mobile. For mobile, an empty image is produced, with the error InvalidStateError (DOM Exception 11): The object is in an invalid state.
I wonder if it has to do with file storage limitations for mobile. Could a potential solution perhaps be to use FileReader?
Here’s the code that works on a desktop/laptop, but not on mobile:
handleDrop(files) {
// First save file to local state
this.setState({ file: file[0] })
}
// Image is then cropped, upon which handleCrop() is called
handleCrop() {
// This returns a HTMLCanvasElement, it can be made into a data URL or a blob, drawn on another canvas, or added to the DOM.
const image = this.refs.avatar.getImageScaledToCanvas().toDataURL()
// Custom DataURLtoBlob() function
const blob = DataURLtoBlob(image)
let file = new File([blob], 'avatar.png', {
lastModified: new Date(),
type: "image/png"
})
let data = new FormData()
data.append('data', file)
fetch('https://api.graph.cool/file/v1/___PROJECTID___', {
method: 'POST',
body: data
})
[...]
}
Found the solution. Don’t convert the blob back into a File. Instead, just upload the blob 😳
handleDrop(files) {
// First save file to local state
this.setState({ file: file[0] })
}
// Image is then cropped, upon which handleCrop() is called
handleCrop() {
// This returns a HTMLCanvasElement, it can be made into a data URL or a blob, drawn on another canvas, or added to the DOM.
const image = this.refs.avatar.getImageScaledToCanvas().toDataURL()
// Custom DataURLtoBlob() function
const blob = DataURLtoBlob(image)
let data = new FormData()
data.append('data', blob)
fetch('https://api.graph.cool/file/v1/___PROJECTID___', {
method: 'POST',
body: data
})
[...]
}

Categories

Resources