亚马逊图像识别:错误InvalidImageFormatException:请求具有无效的图像格式

7
我正在尝试从 Node.Js 应用程序调用 AWS Rekognition 来比较人脸。当在 S3 存储桶上比较两个图像时,一切都很顺利,但是当我尝试上传来自客户端(React Native/Expo 应用程序)的本地图像以与存储在此存储桶中的另一张图像进行比较时,我收到了错误消息InvalidImageFormatException: Request has invalid image format
这张图片是一个250像素正方形的 JPEG 图片,并作为有效的 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 });
    });
  });
};
1个回答

8

问题已解决!

需要进行两个调整。首先,使用 encodeURIComponent 编码 sourceImg 文件:

const sourceImage = encodeURIComponent(sourceImg);

在服务器端,应该创建一个 Buffer,而不是发送 base64 字符串:

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

因此,发送给 AWS 的正文应为:

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

干得好!感谢您发布解决方案,这非常有用。 - p-syche
耶!在处理图片时有许多小问题和需要注意的地方。经过深入分析后,我对通过HTTP处理文件更加自信了。 - tirmey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接