Попытка получить байты из этой закодированной строки (изображение)

#.net #image #byte #decode #imagejpeg

Вопрос:

Я пытаюсь получить изображение из составной формы/данных в моем API .net core, но я просто не могу понять, какая кодировка используется для шифрования этих данных изображения. В принципе, мне нужно получить массив байтов (изображения), представленный внутри этой строки

но изображение не отображается.Странности, которые я получаю при чтении значения тела

и вот как я получаю эту закодированную строку:

  using (Stream responseStream = resposta.GetResponseStream())
 {
  var contentType = MediaTypeHeaderValue.Parse(response.ContentType);
  var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;

   for (MultipartReader smth = new(boundary, responseStream); ;)
   {
     try
     {
        MultipartSection section = await smth.ReadNextSectionAsync();

        if (section == null)
        break;

        string contentTypeFrame = section.ContentType;

        
        // Returns me the encoded string
        string bodyValue = await section.ReadAsStringAsync(); 
        if (bodyValue.ToLower().Contains("heartbeat"))
          continue;

       if (contentTypeFrame == "image/jpeg")
       {
         //Do something if it is an image
       }
    }

   catch (Exception ex) { }
  }
}
 

есть какие-нибудь идеи о том, как бы я попытался декодировать эту строку, чтобы получить байты изображения?

Комментарии:

1. section.ReadAsByteArrayAsync

2. В этом много ошибок. Во-первых, кодирование-это не шифрование, и чем дольше вы думаете, что они одинаковы, тем больше у вас будет проблем. Каждый раз, когда вы используете асинхронность, вы должны использовать await . Если ваш тип содержимого JPEG, то полезная нагрузка не является строкой, и попытка вызова ReadAsStringAsync не сработает. Также никогда не используйте catch (Exception ex) { } . Когда-либо.

3. Возможно, я неправильно выразился, это «тестовая среда», поэтому есть уловка без какой-либо обработки, также я на самом деле не использую try catch, для этого у меня есть программное обеспечение для посредников. Хотя вы точно не сказали мне, как я это сделал, вы были правы, моя проблема заключалась в том, что я пытался получить двоичные данные JPEG в виде строки. (кстати, это еще не все), но я выяснил, как правильно получить данные.

Ответ №1:

Я все понял.

после многих попыток я получил правильный фрагмент кода для обработки получения файлов из запросов «multipart/x-mixed-replace;», как только вы разберете его на раздел «Составные части» здесь:

 using (var httpResponse = (HttpWebResponse)request.GetResponse())
                using (Stream responseStream = httpResponse.GetResponseStream())
                {
                    MediaTypeHeaderValue contentType = MediaTypeHeaderValue
                        .Parse(request.ContentType);

                    string boundary = HeaderUtilities
                        .RemoveQuotes(contentType.Boundary).Value;

                    MultipartSection section;

                    for (MultipartReader smth = new(boundary, responseStream); ;)
                    {
                        section = await smth.ReadNextSectionAsync();

                        if (section is null) break;

                        var bytes = ConverteStreamToByteArray(section.Body);
                        
                        // Save or handle the Byte array
                    }
                }
 

OBS: Если вы действительно ищете байты содержимого, ни при каких обстоятельствах не используйте функцию readasstringasync (), это изменит тело содержимого. (В случае изображений он добавит в основной текст как тип содержимого, так и длину содержимого, и вы больше не сможете конвертировать его в jpg)

Теперь вам понадобится только эта функция, которую я написал, чтобы получить данные из основного потока раздела

  public static byte[] ConvertStreamToByteArray(Stream stream)
        {
            stream.Position = 0; 
            // for some reason the position aways starts at the last index, So make  
            // sure to set it to 0 here

            byte[] byteArray = new byte[16 * 1024];
            using (MemoryStream mStream = new())
            {
                int bit;
                while ((bit = stream.Read(byteArray, 0, byteArray.Length)) > 0)
                {
                    mStream.Write(byteArray, 0, bit);
                }
                return mStream.ToArray();
            }
        }