I am using the expo-image-picker to get the image uri of a locally stored image. I want to use the expo-image-manipulator to resize the image prior to sending it to the backend but the expo imageManipulator will not take the uri from the expo image picker. These errors are happening while running in expo on an android emulator.
Here is the basic code getting the uri:
import * as ImagePicker from "expo-image-picker";
const selectImage = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
quality: 0.5,
});
if (!result.cancelled) onChangeImage(result.uri);
} catch (error) {
console.log("Error reading an image", error);
}
};
I can send this image directly to the backend and save it to my S3 just fine. When I console.log(uri), here is what I get:
file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FThredFit-59f4d533-f203-4efb-bcb0-6a5786d44584/ImagePicker/0ea74111-8677-4074-81af-5fbc1f0758d5.jpg
Now I try to enter this into the image resizer below (as imageUri):
import * as ImageManipulator from 'expo-image-manipulator';
const setSize = async (imageUri, width, height) => {
try {
const manipResult = await ImageManipulator.manipulateAsync(
imageUri,
[{ resize: { width: width, height: height } }],
{ format: 'jpeg' }
);
console.log(manipResult);
} catch (error) {
console.log("Error manipulating image: ", error);
}
};
and I get the following error on the android emulator:
abi38_0_0.com.facebook.react.bridge.ReadableNativeMap cannot be cast to java.lang.String
if I stringify the imageUrl first, then I get past this error but the resizer throws an error saying it can't decode the image:
[Error: Could not get decoded bitmap of "file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FThredFit-59f4d533-f203-4efb-bcb0-6a5786d44584/ImagePicker/0ea74111-8677-4074-81af-5fbc1f0758d5.jpg": java.lang.Exception: Loading bitmap failed]
It's hard to see exactly what is going on here because you didn't provide all of the relevant code. I suspect that the issue you encountered is around stringifying an object rather than getting the appropriate value off of it. Here's an example of ImagePicker and ImageManipulator integration: https://snack.expo.io/@brents/image-picker-and-manipulator
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';
import Constants from 'expo-constants';
export default function ImagePickerExample() {
const [image, setImage] = useState(null);
useEffect(() => {
(async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
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,
});
console.log(result);
if (result.cancelled) {
return;
}
const manipResult = await ImageManipulator.manipulateAsync(
result.localUri || result.uri,
[{ rotate: 90 }, { flip: ImageManipulator.FlipType.Vertical }],
{ compress: 1, format: ImageManipulator.SaveFormat.PNG }
);
setImage(manipResult.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 }} />}
</View>
);
}