2

I have a simple MVC 5 app using Northwind database. The view in question is displaying a list of categories from Categories table in Northwind. I have tried to render the byte array using an img tag but without success.

I have looked at MVC How to display a byte array image from model and tried using a custom html helper but even that did not work

Is there something I am missing in my approach when converting a byte[] to an image?

Tried following ( look at img tag for what I tried)

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CategoryName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            <img src="@String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(item.Picture))" />
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.CategoryID }) |
            @Html.ActionLink("Details", "Details", new { id=item.CategoryID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.CategoryID })
        </td>
    </tr>
}

EF Category class

public partial class Category
{
    public int CategoryID { get; set; }

    [Required]
    [StringLength(15)]
    public string CategoryName { get; set; }

    [Column(TypeName = "ntext")]
    public string Description { get; set; }

    [Column(TypeName = "image")]
    public byte[] Picture { get; set; }
}

Action method

  public class CategoriesController : Controller
  {
        private NorthwindDB db = new NorthwindDB();

        // GET: Categories
        public ActionResult Index()
        {
            return View(db.Categories.ToList());
        }
  }
Sunil
  • 20,653
  • 28
  • 112
  • 197

1 Answers1

4

I figured out that it is not easy the convert Nortwind image to format base64 string. I found a source. According to explanation, "Northwind images were created with Microsoft Access so they have a 78 byte OLE header". So, we should remove the headers. Firstly, modify Category entity.

public partial class Category
{
    public int CategoryID { get; set; }

    [Required]
    [StringLength(15)]
    public string CategoryName { get; set; }

    [Column(TypeName = "ntext")]
    public string Description { get; set; }

    [Column(TypeName = "image")]
    public byte[] Picture { get; set; }

    [NotMapped]
    public string Base64String
    {
        get
        {
            var base64Str = string.Empty;
            using (var ms = new MemoryStream())
            {
                int offset = 78;
                ms.Write(Picture, offset, Picture.Length - offset);
                var bmp = new System.Drawing.Bitmap(ms);
                using (var jpegms = new MemoryStream())
                {
                    bmp.Save(jpegms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    base64Str = Convert.ToBase64String(jpegms.ToArray());
                }
            }
            return base64Str;
        }
    }
}

And then put the Base64String property inside img attribute.

<img src="@String.Format("data:image/jpg;base64,{0}", item.Base64String)" />
lucky
  • 12,734
  • 4
  • 24
  • 46
  • It still does not work after I changed to your format. – Sunil Dec 07 '17 at 17:39
  • Would you share HTML output ? – lucky Dec 07 '17 at 17:45
  • You can see the detailed output in this video: https://www.screencast.com/t/kk7bYdnEpc – Sunil Dec 07 '17 at 17:51
  • I am using the standard Northwind database which comes pre-populated with data. If you have this database on your computer, then go to Categories table and the last column holds an `Image` data type of column. So, I am not saving any data but just retrieving it. – Sunil Dec 07 '17 at 18:03
  • So, you are ignoring the first 78 elements of byte[]? – Sunil Dec 07 '17 at 18:37
  • Yes, otherwise conversion is being failed. I tested, it works. – lucky Dec 07 '17 at 18:39
  • You are a genius. Thanks. I also could just use the following html but with an offset of 78: `` ` – Sunil Dec 07 '17 at 18:39
  • But how did you know that offset is 78? – Sunil Dec 07 '17 at 18:40
  • 1
    May be this image column was for Access database when originally created and never got changed when migrated to SQL Server! – Sunil Dec 07 '17 at 18:45
  • You're welcome. I found a source. https://www.developer.com/net/article.php/3818161/Displaying-and-Customizing-Images-from-a-Database.htm . According to explanation, "Northwind images were created with Microsoft Access so they have a 78 byte OLE header". I removed them. – lucky Dec 07 '17 at 18:46