MVC Как отобразить изображение байтового массива из модели

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

Как я могу это сделать, не возвращаясь в базу данных?

Все решения, которые я вижу, используют ActionResult для возврата к базе данных для извлечения изображения, но у меня уже есть изображение на модели...

Ответ 1

Что-то вроде этого может работать...

@{
    var base64 = Convert.ToBase64String(Model.ByteArray);
    var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
}

<img src="@imgSrc" />

Как уже упоминалось в комментариях ниже, используйте приведенное выше вооружение, зная, что хотя это может ответить на ваш вопрос, оно может не решить вашу проблему. В зависимости от вашей проблемы это может быть решением, но я бы не стал полностью исключать доступ к базе данных дважды.

Ответ 2

Это сработало для меня

<img src="data:image;base64,@System.Convert.ToBase64String(Model.CategoryPicture.Content)" width="80" height="80"/>     

Ответ 3

Я рекомендую что-то в этом направлении, даже если изображение живет внутри вашей модели.

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

Модель образца:

[Bind(Exclude = "ID")]
public class Item
{
    [Key]
    [ScaffoldColumn(false)]
    public int ID { get; set; }

    public String Name { get; set; }

    public byte[] InternalImage { get; set; } //Stored as byte array in the database.
}

Пример метода в контроллере:

public async Task<ActionResult> RenderImage(int id)
{
    Item item = await db.Items.FindAsync(id);

    byte[] photoBack = item.InternalImage;

    return File(photoBack, "image/png");
}

Просмотр

@model YourNameSpace.Models.Item

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
<h4>Item</h4>
<hr />
<dl class="dl-horizontal">
    <img src="@Url.Action("RenderImage", new { id = Model.ID})" />
</dl>
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.Name)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.Name)
    </dd>
</dl>
</div>

Ответ 4

Один из способов - добавить это в новый класс С# или класс HtmlExtensions

public static class HtmlExtensions
{
    public static MvcHtmlString Image(this HtmlHelper html, byte[] image)
    {
        var img = String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(image));
        return new MvcHtmlString("<img src='" + img + "' />");
    }
}

то вы можете сделать это в любом представлении

@Html.Image(Model.ImgBytes)

Ответ 5

Если вы можете кодировать байты base-64, вы можете попробовать использовать результат в качестве источника изображения. В вашей модели вы можете добавить что-то вроде:

public string ImageSource
{
    get
    {
        string mimeType = /* Get mime type somehow (e.g. "image/png") */;
        string base64 = Convert.ToBase64String(yourImageBytes);
        return string.Format("data:{0};base64,{1}", mimeType, base64);
    }
}

И на ваш взгляд:

<img ... src="@Model.ImageSource" />

Ответ 6

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

Множество "if" здесь, так что есть хороший шанс, это плохая идея:

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

// In your original controller action
HttpContext.Cache.Add("image-" + model.Id, model.ImageBytes, null,
    Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1),
    CacheItemPriority.Normal, null);

// In your view:
<img src="@Url.Action("GetImage", "MyControllerName", new{fooId = Model.Id})">

// In your controller:
[OutputCache(VaryByParam = "fooId", Duration = 60)]
public ActionResult GetImage(int fooId) {
    // Make sure you check for null as appropriate, re-pull from DB, etc.
    return File((byte[])HttpContext.Cache["image-" + fooId], "image/gif");
}

Это имеет дополнительное преимущество (или это костыль?) для работы в старых браузерах, где встроенные изображения не работают в IE7 (или IE8, если они больше 32 КБ).

Ответ 7

Если вы хотите представить изображение, добавьте метод в качестве вспомогательного класса или в саму модель и позвольте методу преобразовать образ массива байтов в формат изображения, например PNG или JPG, а затем преобразовать в строку Base64. После этого привяжите значение base64 на вашем представлении в формате

": image/ [расширение типа файла изображения]; base64, [ваша строка base64 идет здесь]"

Приведенный выше атрибут img тег src.

Единственная проблема, с которой я столкнулась, - это слишком длинная строка base64. Поэтому я бы не рекомендовал его для отображения нескольких моделей в представлении.

Ответ 8

Это модифицированная версия ответа Manoj, который я использую в проекте. Просто обновлен, чтобы взять атрибуты класса, html и использовать TagBuilder.

    public static IHtmlString Image(this HtmlHelper helper, byte[] image, string imgclass, 
                                     object htmlAttributes = null)
    {
        var builder = new TagBuilder("img");
        builder.MergeAttribute("class", imgclass);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        var imageString = image != null ? Convert.ToBase64String(image) : "";
        var img = string.Format("data:image/jpg;base64,{0}", imageString);
        builder.MergeAttribute("src", img);

        return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
    }

Что можно использовать тогда следующим образом:

    @Html.Image(Model.Image, "img-cls", new { width="200", height="200" })

Ответ 9

Я создал вспомогательный метод, основанный на asnwer ниже, и я очень рад, что этот помощник может помочь как можно больше.

С моделью:

 public class Images
 {
    [Key]
    public int ImagesId { get; set; }
    [DisplayName("Image")]
    public Byte[] Pic1 { get; set; }
  }

Помощник:

public static IHtmlString GetBytes<TModel, TValue>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TValue>> expression, byte[] array, string Id)
    {
        TagBuilder tb = new TagBuilder("img");
        tb.MergeAttribute("id", Id);
        var base64 = Convert.ToBase64String(array);
        var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
        tb.MergeAttribute("src", imgSrc);
        return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
    }

Вид получает объект ICollection, поэтому вам нужно использовать его в представлении в инструкции foreach:

 @foreach (var item in Model)
  @Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag")
}

Ответ 10

Вам нужно иметь байт [] в вашей БД.

Мой байт [] находится в объекте Person:

public class Person
{
    public byte[] Image { get; set; }
}


Вам нужно преобразовать ваш байт [] в строку. Итак, у меня в контроллере:

String img = Convert.ToBase64String(person.Image);


Затем в моем .cshtml файле моя модель представляет собой ViewModel. Это то, что у меня есть:

 public String Image { get; set; }


Я использую его так в файле .cshtml:

<img src="@String.Format("data:image/jpg;base64,{0}", Model.Image)" />

": изображение / расширение файла изображения; base64, {0}, ваше изображение Строка"

Я хочу, чтобы это помогло кому-то!