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

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

如果不回到数据库,我怎么做到这一点?

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

187555 次浏览

这样的事情可能会成功。

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


<img src="@imgSrc" />

正如在下面的评论中提到的,请使用以上知识武装的 虽然这可能会回答你的问题,但可能解决不了你的问题。根据您的问题,这可能是解决方案,但我不会完全排除访问数据库两次。

如果可以用 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);
}
}

在你看来:

<img ... src="@Model.ImageSource" />

如果希望显示图像,可以添加一个方法作为 helper 类或模型本身,并允许该方法将字节数组图像转换为 PNG 或 JPG 之类的图像格式,然后转换为 Base64字符串。一旦获得了这个值,就可以在视图中以下面的格式绑定 base64值

数据: image/[图像文件类型扩展名]; base64,[你的 base64字符串放在这里]

以上内容被分配给 img标记的 src属性。

唯一的问题是 base64字符串太长了。因此,我不建议在视图中显示多个模型。

如果图片不是那么大,如果有很好的机会,你会经常重复使用图片,如果你没有太多的图片,如果图片不是秘密的(意味着如果一个用户可能看到另一个人的图片,这没什么大不了的) ..。

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

您可以在 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");
}

这样做还有一个额外的好处(或者是一个拐杖?)在旧版本的浏览器中,内联图像在 IE7中无法工作(如果大于32kB,则为 IE8)。

这招对我很管用

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

我推荐一些沿着这些思路的东西,即使图像存在于您的模型中。

我意识到你正在寻求一种直接的方式来从视图中访问它,许多人已经回答了这个问题,并告诉了你这种方式的错误所在,所以这只是另一种方式,将加载图像在一个异步的方式为您,我认为是一个更好的方法。

样本模型:

[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.
}

控制器中的示例方法:

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


byte[] photoBack = item.InternalImage;


return File(photoBack, "image/png");
}

观景

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

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

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 + "' />");
}
}

那么你可以在任何视角下做这件事

@Html.Image(Model.ImgBytes)

这是我在一个项目中使用的 Manoj 答案的修改版本。只是更新了类、 html 属性和使用 TagBuilder。

    public static IHtmlString Image(this HtmlHelper helper, byte[] image, string imgclass,
object htmlAttributes = null)
{
var builder = new TagBuilder("img");
builder.MergeAttribute("class", imgclass);
builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));


var imageString = image != null ? Convert.ToBase64String(image) : "";
var img = string.Format("data:image/jpg;base64,{0}", imageString);
builder.MergeAttribute("src", img);


return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
}

然后可以按以下方式使用:

    @Html.Image(Model.Image, "img-cls", new { width="200", height="200" })

我已经在下面的答案中创建了一个 helper 方法,我很高兴这个 helper 可以提供尽可能多的帮助。

模特:

 public class Images
{
[Key]
public int ImagesId { get; set; }
[DisplayName("Image")]
public Byte[] Pic1 { get; set; }
}

帮手是:

public static IHtmlString GetBytes<TModel, TValue>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TValue>> expression, byte[] array, string Id)
{
TagBuilder tb = new TagBuilder("img");
tb.MergeAttribute("id", Id);
var base64 = Convert.ToBase64String(array);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
tb.MergeAttribute("src", imgSrc);
return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
}

视图正在接收一个: ICollection 对象,因此您需要在 foreach 语句的视图中使用它:

 @foreach (var item in Model)
@Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag")
}

你的数据库里需要一个字节[]。

Byte []位于 Person 对象中:

public class Person
{
public byte[] Image { get; set; }
}


你需要把你的 byte []转换成一个字符串:

String img = Convert.ToBase64String(person.Image);


接下来,在我的. cshtml 文件中,我的 Model 是一个 ViewModel:

 public String Image { get; set; }


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

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

“ data: image/图像文件扩展名; base64,{0} ,你的图像字符串

我希望它能帮助别人!