I'm trying to write some code to save photo data to a file.
I read in the photo data, which comes in as base64 string from react native (Expo), and then I decode it. I immediately write that decoded string to a file.
When I read that file that should contain all of the photo data, all I'm getting back are 4 characters when I expect many megabytes-worth of characters.
Does anybody know how to write this decoded base64 string to a file using Expo? Below is my code ...
const fileUri = `${directoryPath}/${today.getTime()}/${fileName}`;
// this reads us the base64 encoded image data
const imageString = await FileSystem.readAsStringAsync(
image.uri,
{ encoding: FileSystem.EncodingType.Base64 }
);
const fooString = Base64.decode(imageString);
// write the decoded photo data to a file
await FileSystem.writeAsStringAsync(fileUri, fooString);
// read back the file so we can make sure all the data was written
const blah = await FileSystem.readAsStringAsync(fileUri);
const photoInfo = await FileSystem.getInfoAsync(fileUri);
console.log({
fileUri,
fooStringLength: fooString.length,
blahLength: blah.length,
equals: blah === fooString,
photoInfo
});
You can see it's pretty straightforward, so I must be missing something? Below is the output of that console.log
...
Object {
"blahLength": 4,
"equals": false,
"fileUri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%40anonymous%2FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
"fooStringLength": 2953317,
"photoInfo": Object {
"exists": true,
"isDirectory": false,
"modificationTime": 1648511394.334474,
"size": 4415423,
"uri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%40anonymous%2FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
},
}
You can see the lengths don't match. Also, if I print out both fooString
and blah
, which are the before and after strings for comparison, the fooString
looks correct to me and how I expect it to look but the blah
is only like 4 characters worth of data. Below is the incorrect content of blah
string and the file ...
I modified an existing snack to show my situation. This snack gives the option to take a photo or select an existing photo. I put my code in the select an existing photo from the photo library handler. This snack shows that when I write my data to a file and then read it back the data does not match. Any ideas why?
https://snack.expo.dev/@rcoleils/camera
CodePudding user response:
What you're actually saving is the raw binary data that comes from the original file, then reading back. Problem is that it isn't really supported on Expo with writeAsStringAsync
and readAsStringAsync
, as it's not really a string but arbitrary binary data.
There is a bug report on this here: https://github.com/expo/expo/issues/2453. So far it has been ignored with the only workaround of saving the base64 representation of the original. While this could work, it renders the file useless for any other program, increases storage needs by 33% for it and requires special decoding before using.