Amazon Rekogntion Image:错误 InvalidImageFormatException:请求的图像格式无效

Amazon Rekogntion Image: error InvalidImageFormatException: Request has invalid image format

我正在尝试比较从 Node.Js 应用程序调用 AWS Rekognition 的人脸。比较 S3 存储桶上的两张图片时,一切正常,但是当我尝试从客户端(React Native/Expo 应用程序)上传本地图片以与存储在此存储桶中的另一张图片进行比较时,出现错误 InvalidImageFormatException: Request has invalid image format.

这张图片是一个 jpeg 250px 正方形,作为有效的 base64 字符串发送(经过 atob 测试)。显然,它满足这里提出的要求:https://docs.aws.amazon.com/rekognition/latest/dg/limits.html.

下面是一些代码片段:

正在拍摄图像:

const takeImgHandler = async () => {
    const img = await ImagePicker.launchCameraAsync(getImgProps);
    editImg(img);
};

正在编辑图片:

const editImg = async img => {
   ...
    const actions = [
      { resize: { 250, 250 } },
    ];

    const saveOptions = {      
      base64: true,
    };

    const edited = await ImageManipulator.manipulateAsync(img.uri, actions, saveOptions);
    setState({ ...state, img: edited });    
};

设置对我的服务器的 detectFaces 调用:

// sourceImg is appState.img.base64
const compareImagesHandler = async sourceImg => {
    const targetImage = {
      S3Object: {
        Bucket: 'my-bucket-name',
        Name: 'image-name.jpg',
      },
    }; 

    const sourceImage = {
      Bytes: sourceImg,
};

const comparison = await ajax({ method: 'POST', url: `url-to-server-route`, data: { sourceImage, targetImage }});
    console.log('comparison: >>>>>> ', comparison);
    return comparison;
};

服务器控制器运行这个函数:

const awsConfig = () => {
  const config = new AWS.Config({
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    region: process.env.AWS_DEFAULT_REGION,
  });
  AWS.config.update(config);
};

const compareImages = async (SourceImage, TargetImage, cb) => {
  const client = new AWS.Rekognition();

  // Logging the base64 string to validate it, externally, just to make
     sure that it´s valid!
  console.log('sourceImag.Bytes: >>>>>> ', SourceImage.Bytes);

  const params = {
    SourceImage,
    TargetImage,
    SimilarityThreshold: 50,
  };

  client.compareFaces(params, (err, response) => {
    if (err) {
      console.log('err: >>>>>> ', err);
      return cb({ err });
    }

    if (!response.FaceMatches.length) {
      return cb({ err: 'Face not recongized' });
    }

    response.FaceMatches.forEach(data => {
      const position = data.Face.BoundingBox;
      const similarity = data.Similarity;
      console.log(`The face at: ${position.Left}, ${position.Top} matches with ${similarity} % confidence`);
      return cb({ success: data.Similarity });
    });
  });
};

已解决!

需要进行两项调整。首先,使用 encodeURIComponent:

sourceImg 文件进行编码

const sourceImage = encodeURIComponent(sourceImg);

在服务器上,我应该创建一个缓冲区,而不是发送 base64 字符串:

const imageBuffer = Buffer.from(decodeURIComponent(SourceImage), 'base64');

所以,发送到 AWS 的正文应该是:

const params = {    
    SourceImage: {
      Bytes: imageBuffer,
    }
    TargetImage,
    SimilarityThreshold: 50,
};