Hi,
I’m using ImagePicker to take photos and I ran into one issue: on android the width and height (aprox. 800px by 1100px) of the taken image appears to be the resolution of my phones screen (Moto G4). On iOS I get an image the seems to be more in check with the actuall sensor size (aprox. 3000px by 4000px).
Is there any way to control the output width and height of the taken image.
In my case I would love the image to be relatively small, and since React Native Image Resize is not working on Expo, it would be greate to have some level of control over the images.
Hi, unfortunately I don’t think there’s a way to make ImagePicker post-resize the image which was picked right now. That library just wraps the underlying iOS/Android API and returns the result without additional processing.
If you just want to display the image differently in your app you can use properties on the <Image /> component to set its width/height/resize mode.
ping @nikki in case there is some way to postprocess the image that I’m not aware of.
Thanks @ben for your reply!
I was afraid that it wouldn’t work with ImagePicker.
I tried some very hacky way to make it happen in some way by putting the image I took inside an <Image />, hiding that component outside of the viewport and then take a screenshot of the compontent using takeSnapshotAsync:
Thanks for pointing out the ImageEditor component @nikki, but doesn’t it just cut out a part of an image rather than resizing/scaling it down?
In the docs it says something about cropData as a parameter of cropImage() method, but doesn’t specify what cropData really is. I guess it takes an object, but I don’t know what parameters this object contains. Would be glad if you could help me there.
The only problem is that it will give you a file uri like rct-image-store://6 or you can use ImageStore to get the base64 uri for it. But there isn’t currently a way to save it to disk, but if you’re ok with uploading a base64 encoded image that will work for you.
indeed iOS only lets you crop to square, cc @nikki, this would be nice to support on iOS but I’m not sure if the native picker that we lean on supports it
here is a snippet of my function that i’m using right now:
The goal was to let the user pic a image of his choice, let the function check if it is vertical or not and resize it the right way (looking for ratio)
watch here for var wantedMaxSize
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: false
});
console.log(result);
if (!result.cancelled) {
var wantedMaxSize = 1280;
var rawheight = result.height;
var rawwidth = result.width;
var ratio = rawwidth / rawheight;
// check vertical or horizont
if(rawheight > rawwidth){
var wantedwidth = wantedMaxSize*ratio;
var wantedheight = wantedMaxSize;
}
else {
var wantedwidth = wantedMaxSize;
var wantedheight = wantedMaxSize/ratio;
}
let resizedUri = await new Promise((resolve, reject) => {
ImageEditor.cropImage(result.uri,
{
offset: { x: 0, y: 0 },
size: { width: result.width, height: result.height },
displaySize: { width: wantedwidth, height: wantedheight },
resizeMode: 'contain',
},
(uri) => resolve(uri),
() => reject(),
);
});
this.setState({
image: resizedUri
});
}
}
I thought i might also share my resolution to this issue, Thanks to @shuffgy’s code above, slightly modified to save a base64 string inside of a pouch db without android killing the sync process.
In addition, it also checks for the permission to access the camera roll as well, which is an often missed step.
_pickImage = async () => {
//prompt for camera permission
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status === 'granted') {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'Images',
allowsEditing: false
});
// console.log(result);
if (!result.cancelled) {
var wantedMaxSize = 1280;
var rawheight = result.height;
var rawwidth = result.width;
var ratio = rawwidth / rawheight;
// check vertical or horizont
if(rawheight > rawwidth){
var wantedwidth = wantedMaxSize*ratio;
var wantedheight = wantedMaxSize;
}
else {
var wantedwidth = wantedMaxSize;
var wantedheight = wantedMaxSize/ratio;
}
let resizedBase64 = await new Promise((resolve, reject) => {
ImageEditor.cropImage(result.uri,
{
offset: { x: 0, y: 0 },
size: { width: result.width, height: result.height },
displaySize: { width: wantedwidth, height: wantedheight },
resizeMode: 'contain',
},
(uri) => {
ImageStore.getBase64ForTag(uri,
(base64Data) => {
resolve('data:image/jpg'+ ';base64,' + base64Data);
},
(reason) => reject(reason));
},
() => reject());
});
console.log(resizedBase64);
//store resizedBase64 in db
}
}
}```