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,
};
我正在尝试比较从 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,
};