3

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()

5
  • You'll probably want to create a helper to do that. Let me see if I can find the SO post that helped me a while back... Commented Aug 7, 2012 at 7:54
  • Have you checked these two questions? stackoverflow.com/questions/8474822/… and stackoverflow.com/questions/3490462/… Commented Aug 7, 2012 at 7:56
  • Okay, I finally got it to debug and I saw that 'm.Asset.Document' is null :-/ Commented Aug 7, 2012 at 8:02
  • It doesn't even debug. I can't set a debug point on GetImage()-- Is it so or the debug point does not reach GetImage? Commented Aug 7, 2012 at 8:09
  • This is what happened - stackoverflow.com/questions/2301216/… Commented Aug 7, 2012 at 8:10

3 Answers 3

3

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 );
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

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>

Comments

0

Finally got the code to debug and found out that m.Asset.Document was null!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.