Получить изображения из базы данных сервера Mssql, хранящейся в двоичной форме - PullRequest
0 голосов
/ 03 июля 2019

Я сохранил файл jpeg в базе данных MSSql в двоичном формате. Теперь я не могу получить исходный файл изображения / файл jpeg. Кто-нибудь может мне помочь? Я использовал ASP.net core MVC для хранения данных в базе данных.

ASP.net Core 2.2
MSSQL 2008
Визуальная студия 2019

     [HttpGet]
      public IActionResult Index1()
     {
        var ab = _context.Movie.Select(a => a.File).Single();

        return View(ab);
     }

    // POST: api/Uploads
    [HttpPost]
       public IActionResult Post(Movie entity, IFormFile File)
      {
          using (var stream = new MemoryStream())
         {
            File.CopyTo(stream);
            entity.File = stream.ToArray();

        }

        _context.Movie.Add(entity);
        _context.SaveChanges();

        return Ok();
    }

 @model IEnumerable<FileUploads.Models.Movie>

@{
    ViewBag.Title = "Index1";
  }

 <h1>Index1</h1>
  <table>

    <tr>

      @foreach (var item in Model)
       {

          <td>

            @{ 


                var base64 = Convert.ToBase64String(item.File);
                var imgsrc = string.Format("data:image/jpeg;base64,{0}",  base64);
            }

            <img src='@imgsrc' style="max-height:100px;max-width:100px"/>
            }


</td>

        }

    </tr>

</table>
_________

Вот как у меня есть метод post, метод get и просмотр страницы.

Пожалуйста, помогите мне. Как получить исходное изображение в формате JPEG? Было бы полезно, если бы вы также могли показать мне страницу просмотра.

1 Ответ

0 голосов
/ 03 июля 2019

Неясно, в чем собственно проблема. Код у вас должен работать.

Однако, это не правильный подход, поэтому вместо того, чтобы тратить время на его отладку, вы должны просто сделать это правильно.

Проблема с использованием URI данных имеет две стороны:

  1. Вы в основном встраиваете изображение (и) в ответ HTML, что означает, что оно будет очень большим и потенциально может занять много времени для загрузки. Веб-браузер не может начать отображать страницу до тех пор, пока он не получит полный HTML-документ, поэтому чем больше этот документ, тем длиннее перед первой содержательной прорисовкой (т. Е. Вы будете смотреть на пустой экран). Одно изображение не может быть слишком плохим, но проблема становится экспоненциально хуже, чем больше вы добавляете таким образом. Ваш HTML-документ может иметь размер в мегабайтах, особенно с мобильными данными, что не очень хорошо.

  2. Base64 - неэффективная кодировка. Как следует из названия, каждый байт представлен комбинацией из 64 символов ASCII. Поскольку байт может кодировать 256 чисел, для представления каждого отдельного байта в изображении требуется до 4 символов (по 1-2 байта каждый). В случае, если неясно, это означает, что размер вашего изображения будет вынос . Достойная работа мельницы JPEG размером 50-60 КБ может стоить целых 240 КБ в кодировке Base64, что только раздражает, проблема размера страницы описана первой.

Короче говоря, правильный способ сделать это, чтобы подать изображение через действие. Например:

[HttpGet("movie-image/{movieId}")]
public async Task<IActionResult> MovieImage(int movieId)
{
    var movieImage = _context.Movie.Where(x => x.Id == movieId).Select(a => a.File).SingleOrDefault();
    if (movieImage == null)
        return NotFound();

    return File(movieImage, "image/jpeg");
}

Тогда, на ваш взгляд:

<img src="@Url.Action("MovieImage", new { movieId = item.Id })" />

Вы также можете подумать о добавлении некоторых заголовков кэша, чтобы браузер кэшировал изображение и загружал его из кэша вместо того, чтобы попадать на сервер каждый раз, когда он будет показан в будущем:

Response.Headers.Add(HeaderNames.CacheControl, $"max-age={TimeSpan.FromDays(365).TotalSeconds}");
return File(movieImage, "image/jpeg");

И, наконец, поскольку URL, который будет кэшироваться, привязан к идентификатору фильма, а не к физическому изображению, вы можете рассмотреть возможность использования Etags на тот случай, если вам нужно обновить изображение. Это немного сложнее, и не является строго необходимым. В худшем случае старое изображение может быть загружено из кэша, если пользователь уже загрузил его ранее.

Независимо от того, чтобы сгенерировать Etag, вам нужно сгенерировать хэш байтов изображения:

string checksum;
using (var sha256 = SHA256.Create())
{
    checksum = Convert.ToBase64String(sha256.ComputeHash(movieImage));
}

if (Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var etag && checksum == etag)
    return StatusCode((int)HttpStatusCode.NotModified);

Response.Headers.Add(HeaderNames.CacheControl, $"max-age={TimeSpan.FromDays(365).TotalSeconds}");
Response.Headers.Add(HeaderNames.Etag, checksum);
return File(movieImage, "image/jpeg");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...