Reputation: 967
I've stored an image as a byte array, and now I need to display it back from a byte array.So I have an <img>
tag, and I've assigned the source of that tag at runtime to a method which will fetch the image.
View:
document.getElementById("Logo").setAttribute("src",'@Url.Action("GetImage","AdminLogoManager", new { id = Model.Asset.AssetID})');
<img id="Logo" />
Code in the Controller:
private List<LogoModel> LogoModelList
{
get
{
var logoModelList = GetLogoModelListFromSomewhere();
return logoModelList;
}
}
}
public FileContentResult GetImage(int id)
{
LogoModel m = LogoModelList.Find(p => p.Asset.AssetID == id);
return new FileContentResult(m.Asset.Document, "image/jpeg");
}
But it's not displaying the image. I checked on Chrome debugger, and it says: Server responded with an error of 500 (Internal Server Error) Can anyone help me get this to work?? I know that the LogoModelList is not null or empty, and that the ID is probably correct
PS: It doesn't even debug. I can't set a debug point on GetImage()
Upvotes: 3
Views: 2570
Reputation: 5341
Here's a method I created on my Controller using the built in WebImage class, adapted from this answer:
Asp.net MVC3 image thumbnail resize ideas
The good thing about WebImage is you can set the size of the image and also maintain aspect ratio:
using System.Web.Helpers;
public void GetImageThumbnailFromByteArray(int docId, int width, int height)
{
// Load image from database
var document = productRepository.Documents.SingleOrDefault(f => f.DocumentID == docId);
if (document == null || document.FileContent == null)
{
return;
}
// .FileContent is the image stored as a byte array
var image = document.FileContent;
// .Resize will resize the image on the fly using the passed in width and height.
// The 3rd and 4th params are preserveAspectRatio and preventEnlarge
// .Crop it to remove 1px border at top and left sides (bug in WebImage)
new WebImage(image)
.Resize(width, height, true, true)
.Crop(1, 1)
.Write();
// This will load a default image if no image available
// new WebImage(HostingEnvironment.MapPath(@"~/Content/images/myPic.png")).Write();
}
And in Razor:
<div>
<a title="Click to download" href="@Url.Action("Download", "Product", new {id = Model.DocumentID})">
<img style="border: solid; border-color: lightgrey; border-width: thin" src="@Url.Action("GetImageThumbnailFromByteArray", "Product", new {docId = Model.DocumentID, width = 250, height = 250})" alt=""/>
</a>
</div>
Upvotes: 2
Reputation: 967
Finally got the code to debug and found out that m.Asset.Document was null!
Upvotes: 0
Reputation: 21191
It bothers me that I can't find the original source for the code I'm adding here, but it works. It someone has a link to the original feel free to let me know or edit this answer if your reputation allows:
The helper:
public static class ImageResultHelper
{
public static ImageResult Image( this Controller controller, byte[] imageData, string mimeType )
{
return new ImageResult()
{
ImageData = imageData,
MimeType = mimeType
};
}
public static ImageResult Image( this Controller controller, byte[] imageData, string mimeType, HttpCacheability cacheability, DateTime expires, string eTag )
{
return new ImageResult()
{
ImageData = imageData,
MimeType = mimeType,
Cacheability = cacheability,
Expires = expires,
ETag = eTag
};
}
}
And the custom ActionResult
:
public class ImageResult : ActionResult
{
public ImageResult()
{
}
public byte[] ImageData { get; set; }
public string MimeType { get; set; }
public HttpCacheability Cacheability { get; set; }
public string ETag { get; set; }
public DateTime? Expires { get; set; }
public override void ExecuteResult( ControllerContext context )
{
if ( this.ImageData == null )
{
throw new ArgumentNullException( "ImageData" );
}
if ( string.IsNullOrEmpty( this.MimeType ) )
{
throw new ArgumentNullException( "MimeType" );
}
context.HttpContext.Response.ContentType = this.MimeType;
if ( !string.IsNullOrEmpty( this.ETag ) )
{
context.HttpContext.Response.Cache.SetETag( this.ETag );
}
if ( this.Expires.HasValue )
{
context.HttpContext.Response.Cache.SetCacheability( this.Cacheability );
context.HttpContext.Response.Cache.SetExpires( this.Expires.Value );
}
context.HttpContext.Response.OutputStream.Write( this.ImageData, 0, this.ImageData.Length );
}
}
Upvotes: 3