1

My backend accepts raw images & binary for the image upload (works in Postman), but on the React Native frontend I am using react-native-image-crop-picker to just get a uri for the image and so on.

I need to be able to send the image as its raw or binary form, rather than embed it in FormData.

I am using Axios for my requests.

How can I accomplish this?

Ryan Cocuzzo
  • 3,109
  • 7
  • 35
  • 64

4 Answers4

1

You can use following code with react-native-image-crop-picker library and axios library.

ImagePicker.openPicker({
      compressImageMaxWidth: 300,
      compressImageMaxHeight: 300,
      mediaType: 'photo',
      cropping: true,
    })
      .then(({ path, mime }) => {
        if (path) {
          const file = {
            uri: path,
            name: path,
            type: mime,
          };
          const body = new FormData();
          body.append('file', file);
          uploadImage(body);
        }
      })
      .catch((e) => {
        console.log(e.message);
      });

where uploadImage has following implementation

const uploadImage = (data) => {
  const payload = {
    baseURL: AppConfig.BASE_URL,
    url: '/image',
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 120000,
    data,
  }
  axios(payload);
}
Waqas Ahmed
  • 1,321
  • 1
  • 14
  • 23
0

With uri returned by react-native-image-crop-picker. Fetch image raw data (BLOB) as

const blob = await new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onload = function () {
      resolve(xhr.response);
    };
    xhr.onerror = function (e) {
      reject(new TypeError("Network request failed"));
    };
    xhr.responseType = "blob";
    xhr.open("GET", [IMG_URI_HERE], true);
    xhr.send(null);
  });

//  Your logic to upload BLOB  data to the server

  // We're done with the blob, close and release it
  blob.close();


Fiston Emmanuel
  • 4,242
  • 1
  • 8
  • 14
0

According to react-native-image-crop-picker you can get the base64-encoded string by setting includeBase64 to true in the request object.

includeBase64 -- bool (default false) -- When set to true, the image file content will be available as a base64-encoded string in the data property. Hint: To use this string as an image source, use it like: <Image source={{uri: data:${image.mime};base64,${image.data}}} />

ImagePicker.openCamera({
  width: 300,
  height: 400,
  cropping: true,
  includeBase64: true
}).then(image => {
  console.log(image.data);
});
knicholas
  • 520
  • 4
  • 10
0

Add the includeBase64: true parameter when starting the picker.

Afterwards, to send the image, you need to convert it in binary, see Convert base64 string to ArrayBuffer In my experience, @Yaan method worked, while atob didn't. Their function is listed on this github link: https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js

Usage looks like this: Base64Binary.decode(image.data)

For example, to PUT an image after picking it:

ImagePicker.openPicker({
  width: 300,
  height: 300,
  mediaType: 'photo',
  includeBase64: true,
  cropping: true,
}.then(image => {
  axios.put('YOUR-URL', Base64Binary.decode(image.data));
});
Fradow
  • 213
  • 1
  • 6