How to optimise an Image in React Native
43,307
Solution 1
https://github.com/bamlab/react-native-image-resizer provides an API to resize local images.
It allows you to specify:
- Max dimensions (whilst preserving aspect ratio) and;
- Output quality (for JPEG only)
API
import ImageResizer from 'react-native-image-resizer';
ImageResizer.createResizedImage(imageUri, newWidth, newHeight, compressFormat, quality).then((resizedImageUri) => {
// resizeImageUri is the URI of the new image that can now be displayed, uploaded...
}).catch((err) => {
// Oops, something went wrong. Check that the filename is correct and
// inspect err to get more details.
});
Solution 2
If you are using react-native-image-picker for uploading images, you can set maxWidth, maxHeight or quality of image for reducing the size.
const options = {
title: 'Select Picture',
storageOptions: {
skipBackup: true,
path: 'images',
},
maxWidth: 500,
maxHeight: 500,
quality: 0.5
};
ImagePicker.showImagePicker(options, resolve, reject);
Solution 3
You could use expo-image-manipulator:
import { manipulateAsync, SaveFormat } from 'expo-image-manipulator';
const compressImage = async (uri, format = SaveFormat.JPEG) => { // SaveFormat.PNG
const result = await manipulateAsync(
uri,
[{ resize: { width: 1200 } }],
{ compress: 0.7, format }
);
return { name: `${Date.now()}.${format}`, type: `image/${format}`, ...result };
// return: { name, type, width, height, uri }
};
Solution 4
My custom solution for image compression in react-native based on image size.
import * as ImageManipulator from 'expo-image-manipulator';
export default async function ImageCompress(image, { width, height }) {
const compressSizer = size => {
const MB = size / Math.pow(1024, 2);
if (Math.round(MB) === 0) return 1;
if (Math.round(MB) === 1) return 0.9;
if (Math.round(MB) === 2) return 0.8;
if (Math.round(MB) === 3) return 0.7;
if (Math.round(MB) === 4) return 0.6;
if (Math.round(MB) >= 5) return 0.5;
if (Math.round(MB) >= 10) return 0.4;
if (Math.round(MB) >= 15) return 0.3;
if (Math.round(MB) >= 20) return 0.2;
if (Math.round(MB) >= 25) return 0.1;
};
const imageManipulator = async (image, { width, height }) => {
const response = await fetch(image);
const blob = await response.blob();
const compress = compressSizer(blob.size);
let resize;
if (height === width) resize = { height: 480, width: 480 };
else if (height > width) resize = { height: 480 };
else resize = { width: 720 };
const compressedPhoto = await ImageManipulator.manipulateAsync(
image,
[{ resize }],
{
compress,
format: ImageManipulator.SaveFormat.JPEG,
},
);
return compressedPhoto.uri;
};
try {
return await imageManipulator(image, { width, height });
} catch (error) {
console.log(error);
}
}
Related videos on Youtube
Comments
-
Learner over 2 years
Photos captured via camera are too large for efficient upload and download in React native.
Is there an api or library to compress a PNG image file in React Native?
-
Ivan Chernykh almost 8 yearsi'm using this plugin: github.com/marcshilling/react-native-image-picker , it allows to set maximum desired quality, width , height etc.
-
Learner almost 8 yearsThanks @Cherniv. That plug-in is userful, but I wanted to embed the camera into my RN UI which is why I went for github.com/lwansbrough/react-native-camera.
-
-
Jujunol over 6 yearsThis library contains native code. If you're going to use it then you'll have to "eject" your app.
-
Afsara about 6 years@Learner any solution for iOS images captured from camera ?
-
user3480687 almost 3 yearsHow to use the place of compressFormat?
-
Ayush Kumar over 2 yearsThis is a great way of compressing images. Cool huh.
-
CrackerKSR over 2 years@user3480687 use 'PNG' or 'JPG' for compressFormat. check its index.d.ts file of module to know more about parameters