Is it possible for a view to display a WebImage without saving it to a file first?
Asked Answered
A

7

7

I'm not really sure if I'm using the WebImage class correctly.

I have a controller that pulls a photo and some related information (comments, upload date, file name) from the database. I want to return a partial view that contains this information, and display the image along with the extra info.

So I created a new WebImage from the byte array, but how do I display it?

According to this article it should be pretty simple

  1. You need to work with Razor syntax and create a variable that will contain the image:
    @{ var myImage = WebImage("/Content/myImage.jpg") // Work with the image… }

  2. Then, in order to load the image in the page, you have to show the variable that contains the image inside an HTML <img/> tag:
    <img src="@myImage"/>

Except that doesn't work, it just outputs <img src="System.Web.Helpers.WebImage"> and calling .Write doesn't help.

Is there any way to do this or do I need to split up my action into two different actions, one to return the photo information and one to return the photo itself?

Areopagus answered 20/7, 2011 at 17:2 Comment(0)
M
5

There isn't anyway to do it in a single razor view... you need to create a seperate action to render the image.

The img tag on the page is going to make a SEPERATE http call to the server based on the url provided in the img src.

Mitziemitzl answered 20/7, 2011 at 17:12 Comment(0)
I
9

You can write it out on the fly!

You just don't use WebImage.Save() like you'd think, instead you use WebImage.GetBytes().

In this example, you've already saved an image as a byte array to the database. Simplified it a bit to only handle jpegs.

    /// <summary>
    /// Reference this in HTML as <img src="/Photo/WatermarkedImage/{ID}" />
    /// Simplistic example supporting only jpeg images.
    /// </summary>
    /// <param name="ID">Photo ID</param>
    public ActionResult WatermarkedImage(Guid ID)
    {
        // Attempt to fetch the photo record from the database using Entity Framework 4.2.
        var photo = db.Photos.Find(ID);

        if (photo != null) // Found the indicated photo record.
        {
            // Create WebImage from photo data.
            // Should have 'using System.Web.Helpers' but just to make it clear...
            var wi = new System.Web.Helpers.WebImage(photo.Data); 

            // Apply the watermark.
            wi.AddImageWatermark(Server.MapPath("~/Content/Images/Watermark.png"), 
                                 opacity: 75, 
                                 horizontalAlign: "Center", 
                                 verticalAlign: "Bottom");

            // Extract byte array.
            var image = wi.GetBytes("image/jpeg");

            // Return byte array as jpeg.
            return File(image, "image/jpeg");
        }
        else // Did not find a record with passed ID.
        {
            return null; // 'Missing image' icon will display on browser.
        }
    }
Intermixture answered 19/2, 2012 at 1:44 Comment(0)
M
5

There isn't anyway to do it in a single razor view... you need to create a seperate action to render the image.

The img tag on the page is going to make a SEPERATE http call to the server based on the url provided in the img src.

Mitziemitzl answered 20/7, 2011 at 17:12 Comment(0)
H
4

Try using Data URLs to display the image. This will avoid temporarily saving the image to disk and a second HTTP request to fetch the image. You'll just need to do one round trip to encode the image inline.

Hahn answered 24/11, 2012 at 12:15 Comment(1)
This should be the answer, it's the only answer that actually answers the users questionSuperload
T
2

I don't believe the WebImage helper provides the ability to write to a stream. Because of that, you'll likely need to save the file to a temp location (or a cacheable location) and then read the bytes, and write the image back as a FileStreamResult specifying the content type and the data.

Tranquillity answered 20/7, 2011 at 17:17 Comment(0)
P
2

You can convert WebImage into Base64 encoded string and use in a Data URL on the page. Using an HTML canvas makes this pretty easy to accomplish.

Server side generate the Base64 string and create the data url

// C# Razor code
WebImage myWebImage;
// you need to now set the WebImage object in your code
string imagebase64string = Convert.ToBase64String(myWebImage.GetBytes());
string dataUrl = string.Format("data:image/jpeg;base64,{0}", imagebase64string);

Using Razor syntax inject the data url into the Javascript code which renders the image in the browser when the page loads:

// Javascript Code
var myCanvas = document.getElementById('my-image-canvas');
var imageCtx = myCanvas.getContext('2d');
var myImage = new Image;
myImage.onload = function () {
   imageCtx.drawImage(myImage, 0, 0);
}
myImage.src = '@dataUrl';

Below is link to a sample application that demonstrates this concept as well as shows how to easily render ASP.Net charts using a single Razor page using the same concept.

https://github.com/webextant/webimage

Platinumblond answered 2/10, 2016 at 19:13 Comment(1)
Yes, this works for me. It does not require the image file to be saved, which is what I was looking for and it simpler than approaches which save a copy. To display it, I simply used: <img src="@dataUrl" alt="image" />Kedron
K
0

I used @Brady321's approach (thanks ;) ) but my code looks a little different (see below). The advantage of Brady's approach is that the file does not need to be saved to disk - just uploaded and displayed!

WebImage photo = null;
var dataUrl = "";

if (IsPost)
{
    photo = WebImage.GetImageFromRequest();
    if (photo != null)
    {
        string imagebase64string = Convert.ToBase64String(photo.GetBytes());
        dataUrl = string.Format("data:image/jpeg;base64,{0}", imagebase64string);
    }
}

The file upload and display part looks like this:

<div class="col-md-4">
    <h2>Display Image on the Fly</h2>
    <h1>Displaying an Image On the Fly</h1>

    <form action="" method="post" enctype="multipart/form-data">
        <fieldset>
            <legend> Upload Image </legend>
            <label for="Image">Image</label>
            <input type="file" name="Image" />
            <br />
            <input type="submit" value="Upload" />
        </fieldset>
    </form>
    <h1>Uploaded Image</h1>
    @if (dataUrl != "")
    {
    <div class="result">

        <img src="@dataUrl" alt="image" />

    </div>
    }
</div>

The key part being: <img src="@dataUrl" alt="image" />

Kedron answered 29/1, 2020 at 9:26 Comment(0)
K
0

As well as my earlier answer, based on Brady321's answer, I have a similar alternative approach that works for ASP.NET 4.7.2 projects that do not use Razor/.cshtml. This is in VB.NET but would work in C# too:

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            . . .
            If IsPostBack Then
                ' A postback
                Dim dataURL As String
                Dim photo As System.Web.Helpers.WebImage
                photo = System.Web.Helpers.WebImage.GetImageFromRequest()
                If (photo IsNot Nothing) Then
                    Dim imagebase64string As String
                    imagebase64string = Convert.ToBase64String(photo.GetBytes())
                    dataURL = String.Format("data:image/jpeg;base64,{0}", imagebase64string)
                    UploadedImage.Src = dataURL
                End If


            . . .
   End Sub

THe .aspx HTML looks like this (the lack of src parameter causes a warning but works fine):

                                          <form action="" method="post" enctype="multipart/form-data">
                                            <fieldset>
                                                <legend> Upload Image </legend>
                                                <label for="Image">Image</label>
                                                <input type="file" name="Image"  />
                                                <br />
                                                <input type="submit" value="Upload" id="Submit" onsubmit="UploadFile2" runat="server" />
                                            </fieldset>
                                        </form>
                                      <h1>Uploaded Images</h1>

                                      <img  alt="image" id="UploadedImage" runat="server" />
Kedron answered 30/1, 2020 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.