Transform photo from Expo-Camera into blob to send it to an API

38 Views Asked by At

I'm creating a mobile app in React Native using Expo. I want to catch picture from the mobile I'm doing in my CameraScreen.js

  async function handlePictureTaken() {
    console.log('Picture taken')
    try {
      const photo = await cameraRef.current.takePictureAsync({base64: true});
      await cameraRef.current.pausePreview();
      navigation.navigate('ConfirmPhoto', {photo: photo});
    }
    catch (error) {
      console.log(error)
    }
  }

Once I have it I therefore go to my ConfirmCameraScreen.js but there I don't do anything with my photo and send it directly to my ConfirmAnimalScreen.js

import { useState, useEffect } from 'react';
import { Text, View, Image } from 'react-native';

import { detectAnimal } from '../../util/animalIdentification';

function ConfirmAnimalScreen({ route }) {
  const [animal, setAnimal] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    detectAnimal(route.params.photo.uri)
      .then(data => {
        setAnimal(data);
      })
      .catch(err => {
        console.error(err);
        setError(err);
      });
  }, [route.params.photo.uri]);

  if (error) {
    return <Text>Error: {error.message}</Text>;
  }

  if (!animal) {
    return <Text>Loading...</Text>;
  }

  return (
    <View>
      <Text>ConfirmAnimalScreen</Text>
    </View>
  );
}

export default ConfirmAnimalScreen;

Here I just call the function detectAnimal() with the uri of my photo stored locally.

import { INATURALIST_API_KEY, INATURALIST_API_URL } from '@env'

export async function detectAnimal(photo) {

  console.log(photo)
  try {
    const response = await fetch(photo);
    const blob = await response.blob();

    const formData = new FormData();
    formData.append('image', blob);

    console.log('formData', formData);
    const url = `${INATURALIST_API_URL}computervision/score_image`;

    try {
      const animalResponse = await fetch(url, {
        method: 'POST',
        headers: {
          'Authorization': INATURALIST_API_KEY,
          'Accept': 'application/json',
        },
        body: formData,
      });
      console.log(`${animalResponse.status} ${animalResponse.statusText}`);
      return animalResponse.data;
    } catch (error) {
      console.error('Error:', error.message);
    }
  } catch (error) {
    console.error('Error:', error.message);
  }
}

Here I'm trying to call the Inaturalist API (https://api.inaturalist.org/v2/docs/)

However, it always return an Network request failed.
According to me (but not sure), it is because the image is not a valid blob, but I've tried a lot of differents stuffs and it never works while from Postaman it is working well.

EDIT:
I change a bit my code and instead of transforming my image into a blob I directly send the image.uri

export async function detectAnimal(photo) {
  console.log(photo)
  try {
    const formData = new FormData();
    formData.append('image', photo);

    console.log('formData', formData);
    const url = `${INATURALIST_API_URL}computervision/score_image`;

    try {
      const animalResponse = await fetch(url, {
        method: 'POST',
        headers: {
          'Authorization': INATURALIST_API_KEY,
          'Accept': 'application/json',
          'Content-Type': 'multipart/form-data',
        },
        body: formData,
      });
      console.log('animalResponse', animalResponse);
      return animalResponse.data;
    } catch (error) {
      console.error('Error:', error.errors[0].message);
      console.error('Error:', error.status);
    }
  } catch (error) {
    console.error('Error:', error.message);
  }
}

I now have an error 422

END OF EDIT

I've tried several things:

  • I made the request with axios, however, it puts the Content-Type to x-www-form-encoded while the API is waiting for multipart/form-data. It just gave me more context on the error, it is an request error and config error ("_response": "Unrecognized FormData part.")
  • I tried to use the base64 format of the image to transform it into a blob... Same problem
  • I tried to reduce the size of the image... same problem -I tried with a new API-key... same

On Postman and Inaturalist API everything work well with the same API_key

0

There are 0 best solutions below