Display image from byte array in ASP.NET MVC
Displaying images from wellknown URLs is quite straightforward. At times, however, you need to display images that are available as raw binary data. Consider, for example, that you are building a
Captcha system that generates images on the fly. These images won't reside on the server as physical files. They will be generated and held in memory using System.Drawing classes (or something similar). To display them you can't point the src attribute of
an <img> element to a particular URL as such.
There can be multiple ways to deal with this problem. This article discusses
a couple of them.
The first approach that I discuss involves sending a Base64 representation
of the image through ViewBag. The action method under consideration
generates such a Base64 version of the image (often called Data URL) and
then pass it to the view via a ViewBag property. Here is how this is done:
public ActionResult Index()
{
string path = Server.MapPath("~/images/computer.png");
byte[] imageByteData = System.IO.File.ReadAllBytes(path);
string imageBase64Data=Convert.ToBase64String(imageByteData);
string imageDataURL= string.Format("data:image/png;base64,{0}", imageBase64Data);
ViewBag.ImageData = imageDataURL;
return View();
}
The above code shows Index() action method of HomeController. For the sake
of simplicity it uses a physical image file rather than dynamically
generated image. The image file is read as a byte array using ReadAllBytes()
method. In a more realistic situation you will replace the first two lines
with the image generation logic of your own.
Once the image content is read as a byte array, it is converted into a
Base64 string using ToBase64String() method of Convert class. This Base64
string is used to form a data URL as shown. Notice how the data URL has
data:image/png;base64 at the beginning. This way the browser knows that the
src attribute value itself contains the image data. Make sure to change the
image type (.png / .jpg / .gif etc.) as per your needs, Then a ViewBag
variable named ImageData is set to this data URL.
The Index view makes use of this ViewBag property as shown below:
<img src="@ViewBag.ImageData" />
The following figure shows a sample run of the above code:
Let's see another technique to achieve the same result. This technique calls
for creation of another action method. Instead of passing image data through
a ViewBag property the src attribute of the <img> element will point to the
second action method you create. Here is how this approach works:
public ActionResult GetImage()
{
string path = Server.MapPath("~/images/computer.png");
byte[] imageByteData = System.IO.File.ReadAllBytes(path);
return File(imageByteData, "image/png");
}
Here, the GetImage() action method reads the image file into a byte array.
It then uses File() method of the Controller base class to send the contents
to the caller. The first parameter is a byte array that represents the file
content and the second parameter indicates the MIME content type. Make sure
to change the content type as per your needs.
To use the GetImage() action method you will write this markup in the view:
<img src='@Url.Action("GetImage", "Home")'/>
The src attribute of the image tag points to /Home/GetImage. If you run the
application the result would be the same as in earlier case.
That's it! Keep coding!!