MVC如何从模型中显示字节数组图像

DK *_*ALT 105 c# asp.net-mvc razor

我有一个模型,我想在页面上显示一个字节数组图像文件.

如何在不返回数据库的情况下执行此操作?

我看到的所有解决方案都使用ActionResult返回数据库来检索图像,但我已经在模型上有了图像......

dav*_*v_i 194

像这样的东西可能会起作用......

@{
    var base64 = Convert.ToBase64String(Model.ByteArray);
    var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
}

<img src="@imgSrc" />
Run Code Online (Sandbox Code Playgroud)

正如下面的评论所述,请使用上述武装,并知道虽然这可能会回答您的问题,但可能无法解决您的问题.根据您的问题,这可能是解决方案,但我不会完全排除访问数据库两次.

  • @dav_i减少*initial*请求的数量.在优化Web性能时,了解服务器,中间内容平台以及请求和处理信息的客户端的机制非常重要.我不想在评论中提到非常详细的内容,但我想强调需要真正理解使用这种技术的含义. (8认同)
  • 应该注意的是,这将在HTML中嵌入图像,并将绕过几种标准图像缓存技术. (5认同)
  • 这个问题的答案可能是正确的,但我认为我们试图解决的问题有一个缺陷。如果当前的问题是阻止两次调用数据库来获取数据,然后再调用一次来获取图像,我认为更好的解决方案是使用可以实现缓存的处理程序,以减少服务器上的总体负载。当您试图弄清楚为什么您的应用程序因尝试使用 Base64 编码将一个巨大文件转储到页面响应流而变得令人窒息时,您会希望自己能够更多地考虑更大的情况。 (2认同)
  • 太好了,我在模型上添加了一个方法以重新使用它:public string GetBase64(){var base64 = Convert.ToBase64String(ContentImage); 返回String.Format(“ data:image / gif; base64,{0}”,base64); } (2认同)

Nol*_*osi 36

这对我有用

<img src="data:image;base64,@System.Convert.ToBase64String(Model.CategoryPicture.Content)" width="80" height="80"/>     
Run Code Online (Sandbox Code Playgroud)

  • 您好,Chathz,我建议您在传递到视图之前验证控制器中的模型。如果 model 为 null,则传递默认图片 (2认同)

Lou*_*caj 26

即使图像存在于模型中,我也建议沿着这些线条进行操作.

我意识到你正在寻求直接从视图中访问它的方法,许多其他人已经回答了这个问题并告诉你这个方法有什么问题,所以这只是另一种方式,会以异步的方式为你和我加载图像认为是一种更好的方法.

样品型号:

[Bind(Exclude = "ID")]
public class Item
{
    [Key]
    [ScaffoldColumn(false)]
    public int ID { get; set; }

    public String Name { get; set; }

    public byte[] InternalImage { get; set; } //Stored as byte array in the database.
}
Run Code Online (Sandbox Code Playgroud)

控制器中的示例方法:

public async Task<ActionResult> RenderImage(int id)
{
    Item item = await db.Items.FindAsync(id);

    byte[] photoBack = item.InternalImage;

    return File(photoBack, "image/png");
}
Run Code Online (Sandbox Code Playgroud)

视图

@model YourNameSpace.Models.Item

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
<h4>Item</h4>
<hr />
<dl class="dl-horizontal">
    <img src="@Url.Action("RenderImage", new { id = Model.ID})" />
</dl>
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.Name)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.Name)
    </dd>
</dl>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 它应该是一个FileContentResult对象(https://msdn.microsoft.com/en-us/library/system.web.mvc.filecontentresult(v=vs.118).aspx) (3认同)
  • 什么是"返回文件(...)"?File不是静态类吗? (2认同)

Moj*_*oji 13

一种方法是将其添加到新的c#类或HtmlExtensions类

public static class HtmlExtensions
{
    public static MvcHtmlString Image(this HtmlHelper html, byte[] image)
    {
        var img = String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(image));
        return new MvcHtmlString("<img src='" + img + "' />");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在任何视图中执行此操作

@Html.Image(Model.ImgBytes)
Run Code Online (Sandbox Code Playgroud)


Cᴏʀ*_*ᴏʀʏ 9

如果您可以对字节进行base-64编码,则可以尝试将结果用作图像源.在您的模型中,您可能会添加以下内容:

public string ImageSource
{
    get
    {
        string mimeType = /* Get mime type somehow (e.g. "image/png") */;
        string base64 = Convert.ToBase64String(yourImageBytes);
        return string.Format("data:{0};base64,{1}", mimeType, base64);
    }
}
Run Code Online (Sandbox Code Playgroud)

在你看来:

<img ... src="@Model.ImageSource" />
Run Code Online (Sandbox Code Playgroud)


小智 6

您的数据库中需要有一个 byte[] 。

我的 byte[] 在我的 Person 对象中:

public class Person
{
    public byte[] Image { get; set; }
}
Run Code Online (Sandbox Code Playgroud)


您需要将 byte[] 转换为字符串。所以,我的控制器中有:

String img = Convert.ToBase64String(person.Image);
Run Code Online (Sandbox Code Playgroud)


接下来,在我的 .cshtml 文件中,我的模型是 ViewModel。这就是我所拥有的:

 public String Image { get; set; }
Run Code Online (Sandbox Code Playgroud)


我在 .cshtml 文件中这样使用它:

<img src="@String.Format("data:image/jpg;base64,{0}", Model.Image)" />
Run Code Online (Sandbox Code Playgroud)

“数据:图像/图像文件扩展名;base64,{0},您的图像字符串

我希望它能帮助别人!


Joe*_*nos 5

如果图像不是那么大,并且你很有可能经常重复使用图像,如果你没有太多的图像,并且图像不是秘密的(意味着它不大)处理,如果一个用户可能看到另一个人的图像)...

这里有很多"如果",所以很有可能这是一个坏主意:

您可以将图像字节存储Cache一段时间,并将图像标记指向一个操作方法,该操作方法又从缓存中读取并吐出图像.这将允许浏览器适当地缓存图像.

// In your original controller action
HttpContext.Cache.Add("image-" + model.Id, model.ImageBytes, null,
    Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1),
    CacheItemPriority.Normal, null);

// In your view:
<img src="@Url.Action("GetImage", "MyControllerName", new{fooId = Model.Id})">

// In your controller:
[OutputCache(VaryByParam = "fooId", Duration = 60)]
public ActionResult GetImage(int fooId) {
    // Make sure you check for null as appropriate, re-pull from DB, etc.
    return File((byte[])HttpContext.Cache["image-" + fooId], "image/gif");
}
Run Code Online (Sandbox Code Playgroud)

这在旧版浏览器中有额外的好处(或者它是一个拐杖?),其中内联图像在IE7中不起作用(或IE8,如果大于32kB).