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

tir*_*mey 7 amazon-web-services node.js react-native amazon-rekognition

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

\n

该图像是 jpeg 250px 正方形,并作为有效的 base64 字符串发送(atob 测试)。显然,它满足此处提出的要求:https ://docs.aws.amazon.com/rekognition/latest/dg/limits.html 。

\n

下面是一些代码片段:

\n

捕获图像:

\n
const takeImgHandler = async () => {\n    const img = await ImagePicker.launchCameraAsync(getImgProps);\n    editImg(img);\n};\n
Run Code Online (Sandbox Code Playgroud)\n

编辑图像:

\n
const editImg = async img => {\n   ...\n    const actions = [\n      { resize: { 250, 250 } },\n    ];\n\n    const saveOptions = {      \n      base64: true,\n    };\n\n    const edited = await ImageManipulator.manipulateAsync(img.uri, actions, saveOptions);\n    setState({ ...state, img: edited });    \n};\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
// sourceImg is appState.img.base64\nconst compareImagesHandler = async sourceImg => {\n    const targetImage = {\n      S3Object: {\n        Bucket: \'my-bucket-name\',\n        Name: \'image-name.jpg\',\n      },\n    }; \n\n    const sourceImage = {\n      Bytes: sourceImg,\n};\n\nconst comparison = await ajax({ method: \'POST\', url: `url-to-server-route`, data: { sourceImage, targetImage }});\n    console.log(\'comparison: >>>>>> \', comparison);\n    return comparison;\n};\n
Run Code Online (Sandbox Code Playgroud)\n

服务器控制器运行此函数:

\n
const awsConfig = () => {\n  const config = new AWS.Config({\n    accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n    region: process.env.AWS_DEFAULT_REGION,\n  });\n  AWS.config.update(config);\n};\n\nconst compareImages = async (SourceImage, TargetImage, cb) => {\n  const client = new AWS.Rekognition();\n\n  // Logging the base64 string to validate it, externally, just to make\n     sure that it\xc2\xb4s valid!\n  console.log(\'sourceImag.Bytes: >>>>>> \', SourceImage.Bytes);\n\n  const params = {\n    SourceImage,\n    TargetImage,\n    SimilarityThreshold: 50,\n  };\n\n  client.compareFaces(params, (err, response) => {\n    if (err) {\n      console.log(\'err: >>>>>> \', err);\n      return cb({ err });\n    }\n\n    if (!response.FaceMatches.length) {\n      return cb({ err: \'Face not recongized\' });\n    }\n\n    response.FaceMatches.forEach(data => {\n      const position = data.Face.BoundingBox;\n      const similarity = data.Similarity;\n      console.log(`The face at: ${position.Left}, ${position.Top} matches with ${similarity} % confidence`);\n      return cb({ success: data.Similarity });\n    });\n  });\n};\n
Run Code Online (Sandbox Code Playgroud)\n

tir*_*mey 8

解决了!

需要进行两次调整。首先,使用以下命令sourceImg对文件进行编码encodeURIComponent

const sourceImage = encodeURIComponent(sourceImg);

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

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

因此,发送到 AWS 的正文应该是:

const params = {    
    SourceImage: {
      Bytes: imageBuffer,
    }
    TargetImage,
    SimilarityThreshold: 50,
};
Run Code Online (Sandbox Code Playgroud)