Convert File to Blob in Dart Flutter - file

File sampleImage;
Future getImage() async {
var tempImage = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
sampleImage = tempImage;
});
}
void submitValues(){
Blob blob = new Blob(sampleImage);
}
I need to convert the File into Blob in flutter in order to save in the database, I can't find any reference to do so.

Ok, after further investigation i figured it out
void submitValues() async {
Blob blob = new Blob(await sampleImage.readAsBytes());
}
await needs to be added along with readAsBytes in order to convert the File type variable into Blob

Related

upload image file converted from html to s3

I have a piece of HTML which I converted into an image using html-to-image and now I need to upload that image file to s3.
What I get after conversion is base 64 url. I have my s3 setup on remote backend where I send files to the api route and it uploads it to s3 and returns the s3 url for the file.
How can I convert this base url to image obj and send it to the api?
Function to convert html to img:
htmlToImage.toPng(document.getElementById('my-node'))
.then(function (dataUrl) {
// do stuff with url
});
There is a pretty simple common function which converts image data url to a file object defined as following:
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type:mime });
}
// Usage in your case
htmlToImage.toPng(document.getElementById('my-node'))
.then(function (dataUrl) {
const yourFile = dataURLtoFile(dataUrl, 'yourImageName');
});

upload image to S3 presigned url using react-native-image-picker and axios

I am trying to get an presigned url image upload working correctly. Currently the upload succeeds when selecting an image from the IOS simulator, however when I actually try to view the file it seems the file is corrupted and will not open as an image. I suspect it has something to do with my FormData but not sure.
export async function receiptUpload(file) {
const date = new Date();
const headers = await getAWSHeaders();
const presignUrl = await request.post(
urls.fileUpload.presignUpload,
{file_name: `${date.getTime()}.jpg`},
{headers}
)
.then(res => res.data);
const formData = new FormData();
formData.append('file', {
name: `${date.getTime()}.jpg`,
uri: file.uri,
type: file.type
});
const fileUpload = presignUrl.presignUrl && await request.put(
presignUrl.presignUrl,
formData
)
.then(res => res.status === 200);
}
I have tried from other fixes to change the file uri like so...
Platform.OS === 'android' ? file.uri : file.uri.replace('file://', '');
however this does not seem to work either.
I did this just recently in my current project and the following code is a working example for my use case. I didn't need to convert to a blob either though I am uploading to AWS S3 so if you are uploading elsewhere that may be the issue.
export const uploadMedia = async (fileData, s3Data, setUploadProgress = () => {}) => {
let sendData = { ...fileData };
sendData.data.type = sendData.type;
let formData = new FormData();
formData.append('key', s3Data.s3Key);
formData.append('Content-Type', fileData.type);
formData.append('AWSAccessKeyId', s3Data.awsAccessKey);
formData.append('acl', 'public-read');
formData.append('policy', s3Data.s3Policy);
formData.append('signature', s3Data.s3Signature);
formData.append('file', sendData.data);
return axios({
method: 'POST',
url: `https://${s3Data.s3Bucket}.s3.amazonaws.com/`,
data: formData,
onUploadProgress: progressEvent => {
let percentCompleted = Math.floor((progressEvent.loaded * 100) / progressEvent.total)
setUploadProgress(percentCompleted);
}
})
}
I would first check to see where the issue is occurring. After uploading can you view it on whatever storage service you are trying to upload it to. If so it's something on React Native side. If it doesn't ever get uploaded to the location you know its an error in your upload process. Might help you track the exact location of the error.
I had to do this recently for a project. I believe the data is a base64 string when coming directly from the file input. So the issue is your are uploading a base64 string not the image by simply passing the data field. I had to process it before uploading to the signed URL with the following method.
private dataUriToBlob(dataUri) {
const binary = atob(dataUri.split(',')[1]);
const array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: 'image/jpeg' });
}
This answer fixed it for me: How can I upload image directly on Amazon S3 in React Native?
I had tried uploading with axios and fetch with FormData. The download went through but the image file was not readable, even when downloaded to my Mac from the S3 console:
The file "yourfile.jpg" could not be opened. It may be damaged or use a file format that Preview doesn’t recognize.
Only after trying to upload with XHR with the correct Content-Type header did it work. Your signedUrl should be correct as well, which seems to be the case if the download goes through.

React Native File-Conversion

I'm trying to convert an audio file into a Base64String to upload to a server.
For certain reasons, I want to do this on the phone before I upload this. I'm using React Native inside the Expo kit.
My file structure looks like this:
let uriParts = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append('file', {
uri,
name: `file.${fileType}`,
type: `audio/${fileType}`,
});
Assume we have the uri and it's a .wav audio file
I was able to do this conversion with a NodeJS server with multer doing the heavy lifting.
It would give a buffer to the route and then I could convert the buffer to a base64 string and then send it to another server to process the buffer.
Any idea how can get this done on React Native or purely on the frontend?
Thanks!
You can use FileReader class.
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
Or you can send as a blob (It is not base64).
Use https://github.com/wkh237/react-native-fetch-blob library

Save Recorded Audio to Local Directory -ReactJS

I am recording an audio through browser and storing it as a blob using react-mic library, I need to change the blob audio file to mp3/ogg/wav file and store it in local directory using ReactJS.
Blob example:
{blob: Blob(5899), startTime: 1518600546820, stopTime: 1518600547833, options: {audioBitsPerSecond :128000, mimeType:"audio/mpeg"},
blobURL: "blob:http://localhost:3000/3ac81ece-237f-4265-8225-6653b2beb0bc"}
Here I am storing a blob in a state,
onStop = (recordedBlob) => {
this.setState({
blobMain: recordedBlob
})
}
instead of a blob I wanted to store a mp3/ogg/wav file. And use the state for api response.
I tried using Filereader() to convert the blob to ArrayBuffer and convert it as a mp3/ogg/wave file.
onStop = (recordedBlob) => {
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function() {
arrayBuffer = this.result;
};
fileReader.readAsArrayBuffer(recordedBlob);
this.setState({
blobMain: fileReader
})
}
But I get an error as:
TypeError: Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.

How to upload audio file to Firebase Storage?

I'm trying to upload audio file to Firebase Storage in my Ionic2 project.
First I recorded a audio file using Media plugin (Cordova plugin), and this file is playing well. From the Android storage and from the media plugin method (this.media.play()...;).
Second I need to push the recorded file to Firebase Storage.
this is my code:
let storageRef = firebase.storage().ref();
let metadata = {
contentType: 'audio/mp3',
};
let filePath = `${this.file.externalDataDirectory}`+`${this.fileName}`;
const voiceRef = storageRef.child(`voices/${this.fileName}`);
var blob = new Blob([filePath], {type: 'audio/mp3'});
voiceRef.put(blob);
After reading the Firebase doc, I can push blob to Firebase.
The file is successfully pushed to Firebase Storage with empty data (95 Byte).
this is screenshot:
The problem isn't a Firebase issue
My problem is solved by using the File cordova plugin method (readAsDataURL()) and the putString(fileBase64,firebase.storage.StringFormat.DATA_URL) method.
First, I create a file reference:
let filePath = "this.file.externalDataDirectory" + "this.fileName";
Then I transform the file to a base64 string by using the readAsDataURL method that returns a promise containing the file as a string base64. Also, I push the file to Firebase using the putString method that has two parameters the File that returned by the readAsDataURL and the second is firebase.storage.StringFormat.DATA_URL.
My Final code:
let storageRef = firebase.storage().ref();
let metadata = {
contentType: 'audio/mp3',
};
let filePath = `${this.file.externalDataDirectory}` + `${this.fileName}`;
this.file.readAsDataURL(this.file.externalDataDirectory, this.fileName).then((file) => {
let voiceRef = storageRef.child(`voices/${this.fileName}`).putString(file, firebase.storage.StringFormat.DATA_URL);
voiceRef.on(firebase.storage.TaskEvent.STATE_CHANGED, (snapshot) => {
console.log("uploading");
}, (e) => {
reject(e);
console.log(JSON.stringify(e, null, 2));
}, () => {
var downloadURL = voiceRef.snapshot.downloadURL;
resolve(downloadURL);
});
});
That's working fine for me.
Thanks.

Resources