ASP.Net MVC: How to display a byte array image from model

C#asp.net MvcRazor

C# Problem Overview


I've a model with a byte array image file that I want to show on the page.

How can I do that without going back to the Database?

All the solutions that I see use an ActionResult to go back to the database to retrieve the image, but I already have the image on the model...

C# Solutions


Solution 1 - C#

Something like this may work...

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

<img src="@imgSrc" />

As mentioned in the comments below, please use the above armed with the knowledge that although this may answer your question it may not solve your problem. Depending on your problem this may be the solution but I wouldn't completely rule out accessing the database twice.

Solution 2 - C#

This worked for me

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

Solution 3 - C#

I recommend something along these lines, even if the image lives inside of your model.

I realize you are asking for a direct way to access it right from the view and many others have answered that and told you what is wrong with that approach so this is just another way that will load the image in an async fashion for you and I think is a better approach.

Sample Model:

[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.
}

Sample Method in the Controller:

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

    byte[] photoBack = item.InternalImage;

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

View

@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>

Solution 4 - C#

One way is to add this to a new c# class or HtmlExtensions class

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 + "' />");
    }
}

then you can do this in any view

@Html.Image(Model.ImgBytes)

Solution 5 - C#

If you can base-64 encode your bytes, you could try using the result as your image source. In your model you might add something like:

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);
    }
}

And in your view:

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

Solution 6 - C#

You need to have a byte[] in your DB.

My byte[] is in my Person object:

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


You need to convert your byte[] in a String. So, I have in my controller :

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


Next, in my .cshtml file, my Model is a ViewModel. This is what I have in :

 public String Image { get; set; }


I use it like this in my .cshtml file:

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

"data:image/image file extension;base64,{0}, your image String"

I wish it will help someone !

Solution 7 - C#

If the image isn't that big, and if there's a good chance you'll be re-using the image often, and if you don't have too many of them, and if the images are not secret (meaning it's no big deal if one user could potentially see another person's image)...

Lots of "if"s here, so there's a good chance this is a bad idea:

You can store the image bytes in Cache for a short time, and make an image tag pointed toward an action method, which in turn reads from the cache and spits out your image. This will allow the browser to cache the image appropriately.

// 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");
}

This has the added benefit (or is it a crutch?) of working in older browsers, where the inline images don't work in IE7 (or IE8 if larger than 32kB).

Solution 8 - C#

This is an modified version of Manoj's answer that I use on a project. Just updated to take a class, html attributes and use the 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));
    }

Which can be used then as follows:

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

Solution 9 - C#

If you want to present the image, add a method as a helper class or to the model itself and allow the method to convert the byte array image to a image format like PNG or JPG then convert to Base64 string. Once you have that, bind the base64 value on your view in the format

"data:image/[image file type extension];base64,[your base64 string goes here]"

The above is assigned to the img tag's src attribute.

The only issue I have with this is the base64 string being too long. So, I would not recommend it for multiple models being shown in a view.

Solution 10 - C#

I've created a helper method based in the asnwer below and I'm pretty glad that this helper can help as many as possible.

With a model:

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

The helper is:

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));
    }
    

The view is receiving a: ICollection object so you need to used it in the view in a foreach statement:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDK ALTView Question on Stackoverflow
Solution 1 - C#dav_iView Answer on Stackoverflow
Solution 2 - C#NoloMokgosiView Answer on Stackoverflow
Solution 3 - C#Louie BacajView Answer on Stackoverflow
Solution 4 - C#MojiView Answer on Stackoverflow
Solution 5 - C#CᴏʀʏView Answer on Stackoverflow
Solution 6 - C#ThorpeView Answer on Stackoverflow
Solution 7 - C#Joe EnosView Answer on Stackoverflow
Solution 8 - C#AlexHView Answer on Stackoverflow
Solution 9 - C#mitchView Answer on Stackoverflow
Solution 10 - C#Jose OrtegaView Answer on Stackoverflow