将 Expo-Camera 中的照片转换为 blob 以将其发送到 API

问题描述 投票:0回答:1

我正在使用 Expo 在 React Native 中创建一个移动应用程序。 我想从我在 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)
    }
  }

一旦我有了它,我就会转到我的ConfirmCameraScreen.js,但在那里我不对我的照片做任何事情,而是将其直接发送到我的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;

这里我只是使用本地存储的照片的 uri 调用函数 detectorAnimal() 。

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);
  }
}

这里我尝试调用 Inaturalist API (https://api.inaturalist.org/v2/docs/)

但是,它总是返回网络请求失败。
根据我的说法(但不确定),这是因为图像不是有效的斑点,但我尝试了很多不同的东西,但它从来没有工作,而从 Postaman 来看,它工作得很好。

编辑:
我更改了一些代码,而不是将图像转换为 blob,而是直接发送 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);
  }
}

我现在遇到错误 422

编辑结束

我尝试了几件事:

  • 我使用 axios 发出请求,但是,当 API 等待 multipart/form-data 时,它会将 Content-Type 设置为 x-www-form-encoded。它只是给了我更多关于错误的上下文,它是一个请求错误和配置错误(“_response”:“无法识别的 FormData 部分。”)
  • 我尝试使用图像的base64格式将其转换为blob...同样的问题
  • 我尝试缩小图像的大小...同样的问题 -我尝试使用新的 API 密钥...相同

在 Postman 和 Inaturalist API 上,使用相同的 API_key 一切都可以正常工作

react-native expo blob expo-camera
1个回答
0
投票
export const requestBlob = async (uri) => {
  return await new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onload = function () {
      resolve(xhr.response);
    };
    xhr.onerror = function () {
      reject(new Error("request failed"));
    };
    xhr.responseType = "blob";
    xhr.open("GET", uri, true);

    xhr.send(null);
  });
};
// This function uses the XML HTTP Request method to obtain the blob data from the image

这里是一个自定义钩子,用于使用 XMLHttpRequest 将 expo-camera 图像转换为 blob

import { requestBlob } from "./requestBlob";
const blob = await requestBlob(photo);
// Do what you want with blob

这是我用来处理来自展会相机的图像的

© www.soinside.com 2019 - 2024. All rights reserved.