使用MemoryStream调用FaceAPI AddFaceToLargeFaceListAsync遇InvalidImageSize异常
问题解决:FaceAPI报InvalidImageSize的原因及修复
嘿,这个问题我之前也碰到过!你遇到的Image size is too small.(InvalidImageSize)异常,本质是MemoryStream的读取指针停在了流的末尾,FaceAPI拿到的其实是一个“空”的流,自然会报错说图片尺寸不对。
核心修复:重置流指针位置
当你从FTP下载数据写入MemoryStream后,流的当前位置是最后一个字节的下一位,这时候直接传给FaceAPI,服务会认为没有读取到任何有效数据。解决办法很简单:在调用FaceAPI之前,把流的指针重置到起始位置。
1. 优化你的GetFileStream方法
我帮你调整了方法,不仅添加了指针重置,还优化了资源释放(用using自动处理流资源,避免内存泄漏):
public MemoryStream GetFileStream(string filePath, string userName, string password) { Console.WriteLine($"getting file stream : {filePath}"); MemoryStream ftpStream = null; try { FtpWebRequest request = WebRequest.Create(filePath) as FtpWebRequest; request.Method = WebRequestMethods.Ftp.DownloadFile; request.Credentials = new NetworkCredential(userName, password); ftpStream = new MemoryStream(); // 用using自动释放WebResponse和responseStream using (WebResponse response = request.GetResponse()) using (Stream responseStream = response.GetResponseStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0) { ftpStream.Write(buffer, 0, bytesRead); } } // 关键:把流指针移到开头,这样FaceAPI才能读取到完整的图片数据 ftpStream.Seek(0, SeekOrigin.Begin); } catch (Exception ex) { Console.WriteLine($"getting file stream : {filePath} " + ex.ToString()); // 异常时记得释放流,避免内存泄漏 ftpStream?.Dispose(); ftpStream = null; } return ftpStream; }
2. 在调用FaceAPI的代码中双重确认
保险起见,在调用AddFaceToLargeFaceListAsync之前,再重置一次指针(虽然上面的方法已经处理了,但多一层保障没坏处):
using (MemoryStream fStream = ftpService.GetFileStream(imgPath, customerConfig.FTPUserName, customerConfig.FTPPassword)) { try { if (fStream != null) { Console.WriteLine("fStream Length : " + imgPath + " {" + fStream.Length + "}"); // 再次确认指针在起始位置 fStream.Seek(0, SeekOrigin.Begin); var faces = await faceServiceClient.AddFaceToLargeFaceListAsync(listId, fStream); if (!urlFaceID.ContainsKey(imgPath)) { urlFaceID.Add(imgPath, faces.PersistedFaceId.ToString()); } } } catch (FaceAPIException ex) { if (ex.ErrorCode.Equals("ConcurrentOperationConflict") || ex.ErrorCode.Equals("RateLimitExceeded")) { imageList.Add(imgPath); } else if (ex.ErrorMessage.Contains("more than 1 face in the image.")) { Console.WriteLine("more than 1 face in the image."); } if (!InvalidUrlFaceID.ContainsKey(imgPath)) { InvalidUrlFaceID.Add(imgPath, null); } } // 不用手动Close!using语句会自动调用Dispose释放流资源 }
额外排查建议
- 先确认FTP上的图片本身是有效的:可以把MemoryStream里的数据写入本地文件,看看能不能正常打开,验证流内容是否正确。
- 检查图片尺寸是否符合FaceAPI要求:FaceAPI要求图片最小尺寸是64x64像素,如果图片本身太小也会报这个错。
内容的提问来源于stack exchange,提问作者Wajdi Chamakhi
相关产品推荐
相关产品推荐

