Возможно ли, чтобы представление отображало WebImage без предварительного сохранения его в файл?

Я не совсем уверен, правильно ли я использую класс WebImage.

У меня есть контроллер, который извлекает фото и некоторую связанную информацию (комментарии, дату загрузки, имя файла) из базы данных. Я хочу вернуть частичное представление, содержащее эту информацию, и отобразить изображение вместе с дополнительной информацией.

Итак, я создал новый WebImage из массива байтов, но как мне его отобразить?

Согласно этой статье, это должно быть довольно просто

  1. Вам нужно работать с синтаксисом Razor и создать переменную, которая будет содержать изображение:
    @{ var myImage = WebImage("/Content/myImage.jpg") // Work with the image… }

  2. Затем, чтобы загрузить изображение на страницу, вы должны показать переменную, содержащую изображение, внутри HTML-тега <img/>:
    <img src="@myImage"/>

За исключением того, что это не работает, он просто выводит <img src="System.Web.Helpers.WebImage">, а вызов .Write не помогает.

Есть ли способ сделать это или мне нужно разделить действие на два разных действия: одно для возврата информации о фотографии, а другое для возврата самой фотографии?


person Brandon    schedule 20.07.2011    source источник


Ответы (7)


В любом случае это невозможно сделать в одном представлении бритвы... вам нужно создать отдельное действие для рендеринга изображения.

Тег img на странице будет делать ОТДЕЛЬНЫЙ http-вызов на сервер на основе URL-адреса, указанного в img src.

person Scrappydog    schedule 20.07.2011

Вы можете написать это на лету!

Вы просто не используете WebImage.Save(), как вы думаете, вместо этого вы используете WebImage.GetBytes().

В этом примере вы уже сохранили изображение в виде массива байтов в базе данных. Немного упростил его, чтобы обрабатывать только JPEG.

    /// <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.
        }
    }
person Klom Dark    schedule 19.02.2012

Попробуйте использовать URL-адреса данных для отображения изображения. Это позволит избежать временного сохранения изображения на диск и повторного HTTP-запроса для получения изображения. Вам просто нужно сделать один круговой обход, чтобы закодировать изображение в строке.

person Brian Chavez    schedule 24.11.2012
comment
Это должен быть ответ, это единственный ответ, который действительно отвечает на вопрос пользователей. - person ChrisFletcher; 14.10.2014

Я не верю, что помощник WebImage предоставляет возможность записи в поток. Из-за этого вам, вероятно, потребуется сохранить файл во временном месте (или в кэшируемом месте), а затем прочитать байты и записать изображение обратно как FileStreamResult, указав тип содержимого и данные.

person Matthew Abbott    schedule 20.07.2011

Вы можете преобразовать WebImage в закодированную строку Base64 и использовать в URL-адресе данных на странице. Использование холста HTML делает это довольно легко.

На стороне сервера генерируется строка Base64 и создается 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);

Используя синтаксис Razor, введите URL-адрес данных в код Javascript, который отображает изображение в браузере при загрузке страницы:

// 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';

Ниже приведена ссылка на пример приложения, в котором демонстрируется эта концепция, а также показано, как легко отображать диаграммы ASP.Net с помощью одной страницы Razor с использованием той же концепции.

https://github.com/webextant/webiimage

person brady321    schedule 02.10.2016
comment
Да, это работает для меня. Он не требует сохранения файла изображения, что я и искал, и это проще, чем подходы, сохраняющие копию. Чтобы отобразить его, я просто использовал: ‹img src=@dataUrl alt=image /› - person Zeek2; 29.01.2020

Я использовал подход @ Brady321 (спасибо;)), но мой код выглядит немного иначе (см. Ниже). Преимущество подхода Брейди в том, что файл не нужно сохранять на диск — просто загрузите и отобразите!

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);
    }
}

Часть загрузки и отображения файлов выглядит следующим образом:

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

Ключевая часть: <img src="@dataUrl" alt="image" />

person Zeek2    schedule 29.01.2020

Как и мой предыдущий ответ, основанный на ответе Brady321, у меня есть аналогичный альтернативный подход, который работает для проектов ASP.NET 4.7.2, которые не используют Razor/.cshtml. Это в VB.NET, но будет работать и в С#:

 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

HTML-код .aspx выглядит следующим образом (отсутствие параметра src вызывает предупреждение, но работает нормально):

                                          <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" />
person Zeek2    schedule 30.01.2020