- SDK Version: “expo”: “~39.0.2”,
- Platforms(Android/iOS/web/all): Testing on iphone
I am trying to take an image from the image picker, save it locally (within the app, db, or filesystem, not in the camera roll.) Then load that image in an component. I have tinkered around a good bit without success. Here is a stackoverflow question I posted asking for help some time ago.
Most recently I have been trying to debug by making a dummy app with only that functionality.
Here is some code from that app.
app.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import ImagePickerExample from './image-picker'
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
<ImagePickerExample></ImagePickerExample>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
image-picker.js
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';
import * as FileSystem from 'expo-file-system';
const imgDir = FileSystem.documentDirectory + 'images/';
async function ensureDirExists() {
const dirInfo = await FileSystem.getInfoAsync(imgDir)
if (!dirInfo.exists) {
console.log('Gif directory doesn\'t exist, creating...');
await FileSystem.makeDirectoryAsync(imgDir, { intermediates: true });
}
}
ensureDirExists();
export default function ImagePickerExample() {
const [image, setImage] = useState(null);
useEffect(() => {
(async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestCameraRollPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
})();
}, []);
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
base64: true,
});
// console.log(result);
if (!result.cancelled) {
await FileSystem.writeAsStringAsync(
imgDir + `image.png`,
result.base64
);
setImage(result.uri);
}
};
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Pick an image from camera roll" onPress={pickImage} />
{image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
{image &&
<View style={{width: 100, height: 100, backgroundColor: 'blue'}}>
<Image style={{width: 50, height: 50}} source={{uri:`data:image/png;base64,${imgDir+'image.png'}`}}/>
</View>
}
</View>
);
}
Most of it is from the example in the documentation. The result I get from this code appears to store the binary of the image as a file, but doesn’t successfully render it as the source of the image component.