2

The photos captured with the device are big. I want to upload them to my backend server after resizing them (scaling them) to more reasonable sizes (less than 800x800). I hoped to use ImageEditor module's coprImage() function, but running it with a large image results in a OutOfMemory exception. I assume that since the module tries to decode a large image and store it in memory, the app crashes.

What I need is the following:

Input

{
  width: 3100,
  height: 2500,
  uri: content://android/1 (some location in Android device)
}

Output

{
  width: 800,
  height: 650,
  uri: content://android/1/resized (some location in Android device)
}

Then I can grab this uri to send the picture to my backend server, and delete the resized photo from the device.

I assume that I will have to write a NativeModule so I can resize an image without loading a large decoded image into memory. React Native's Image component uses Fresco to handle resizing before rendering them, but I don't think it provides a way to resize an image and temporarily save it in fs.

Any help would be appreciated.

References:

  1. https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
  2. http://frescolib.org/docs/resizing-rotating.html
  3. https://facebook.github.io/react-native/docs/images.html
  4. Memory efficient image resize in Android
Community
  • 1
  • 1
Maximus S
  • 10,759
  • 19
  • 75
  • 154

5 Answers5

9

Expo library has an image manipulator that can resize and more:

import { ImageManipulator } from 'expo';

...

const manipResult = await ImageManipulator.manipulate(
    imageUri,
    [{ resize: { width: 640, height: 480 } }],
    { format: 'jpg' }
);

manipResult will return an object with the new uri, width and height.

Find it here: https://docs.expo.io/versions/latest/sdk/imagemanipulator.html

Goodmedalist
  • 357
  • 4
  • 8
3

In my app I use react-native-image-picker which works really well.

If you don't want to use it, have a look into this function source to see how resizing is done. Cheers.

Kamil Sarna
  • 5,993
  • 1
  • 32
  • 22
1

Did you try with react-native-image-resizer? For me it works pretty well, I'm using it with react-native-camera, it looks like this:

  fromCamera() {
    let newWidth = 800;
    let newHeight = 650;
    this.refs.camera.capture()
    .then((data) => {
      ImageResizer.createResizedImage(data.path, newWidth, newHeight, 'JPEG', 100, rotation)
      .then(uri => {
        // send to backend
      }
    })
  }

Original image is saving on device with uri: data.path, so there are no problems with memory.

jonzee
  • 1,600
  • 12
  • 20
0

Lets check out this. It will provide you detailed description about your issue for resizing and uploading to backend server.

Nilesh Kikani
  • 2,628
  • 21
  • 37
0

Incase If you want to send Base64 String you can check the code below

how to install and link with android please check this link

https://github.com/TBouder/react-native-asset-resize-to-base64

// this code is for resizing and pushing to array only

let images = [];
NativeModules.RNAssetResizeToBase64.assetToResizedBase64(
            response.uri,
            newWidth,
            newHeight,
            (err, base64) => {
              if (base64 != null) {
                const imgSources = { uri: base64 };
                this.setState({
                  image: this.state.image.concat(imgSources)
                });
                 this.state.image.map((item, index) => {
                  images.push(item);
                });
                if (err) {
                  console.log(err, "errors");
                }
              }
            }
          );
Sk Sunny
  • 71
  • 6