Microsoft.ProjectOxford.Face.AddFaceToLargeFaceListAsync с FTP с помощью MemoryStream - PullRequest
0 голосов
/ 28 мая 2018

Я использую WS Microsoft FaceAPI.При использовании FileStream все работает хорошо, но мне приходится читать изображения с FTP, поэтому я использую MemoryStream.Я всегда заканчиваю этим исключением:

{Microsoft.ProjectOxford.Face.FaceAPIException: Image size is too small.(InvalidImageSize)

вот мой метод создания MemoryStream.Это правильно ??

 public MemoryStream GetFileStream(string filePath, string userName, string password)
    {

        Console.WriteLine($"getting file stream : {filePath}");
        MemoryStream ftpStream = null;
        try
        {
            var fileName = Guid.NewGuid().ToString();

            FtpWebRequest request = WebRequest.Create(filePath) as FtpWebRequest;
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.Credentials = new NetworkCredential(userName, password);

            ftpStream = new MemoryStream();
            WebResponse response = request.GetResponse();
            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);
            }
            responseStream.Close();

        }
        catch (Exception ex)
        {
            Console.WriteLine($"getting file stream : {filePath} " + ex.ToString());
        }
        return ftpStream;

    }

и вот задача, где я вызываю WS FaceAPI

  using (MemoryStream fStream = ftpService.GetFileStream(imgPath, customerConfig.FTPUserName, customerConfig.FTPPassword))
                        {
                            try
                            {
                                if (fStream != null)
                                {
                                    Console.WriteLine("fStream Length : " + imgPath + " {" + fStream.Length + "}");
                                    var faces = await faceServiceClient.AddFaceToLargeFaceListAsync(listId, fStream); //==>> GET ME The EXCEPTION
                                    if (fStream != null)
                                    {
                                        fStream.Close();
                                    }
                                    if (urlFaceID.ContainsKey(imgPath) == false)
                                        urlFaceID.Add(imgPath, faces.PersistedFaceId.ToString());
                                }

                            }
                            catch (FaceAPIException ex)
                            {

                                if (ex.ErrorCode.Equals("ConcurrentOperationConflict"))
                                {
                                    imageList.Add(imgPath);

                                }

                                else if (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) == false)
                                {
                                    InvalidUrlFaceID.Add(imgPath, null);
                                }

                            }
                            finally
                            {
                                if (fStream != null)
                                {
                                    fStream.Close();
                                }
                            }
                        }

Я не знаю, правильно ли я читаю MemoryStream.Я не могу найти никакого решения для этого, я надеюсь, что кто-то ответит.СПАСИБО всем

Спасибо

1 Ответ

0 голосов
/ 30 мая 2018

Это выглядит в основном правильно, но вы забываете, что указатели чтения и записи улучшаются для MemoryStream всякий раз, когда вы пишете.Другими словами, возвращаемое значение GetFileStream уже указывает на конец потока, как вы написали.Все, что вам нужно изменить, это «перемотать» поток перед возвратом.

public MemoryStream GetFileStream(string filePath, string userName, string password)
{
    Console.WriteLine($"getting file stream : {filePath}");
    MemoryStream ftpStream = null;
    try
    {
        var fileName = Guid.NewGuid().ToString();

        FtpWebRequest request = WebRequest.Create(filePath) as FtpWebRequest;
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential(userName, password);

        ftpStream = new MemoryStream();
        ...
        ftpStream.Position = 0; // <-- ADD THIS LINE
    }
    catch (Exception ex)
    {
        Console.WriteLine($"getting file stream : {filePath} " + ex.ToString());
    }

    return ftpStream;
}
...