在ASP中显示图像的不同方法.NET MVC以及何时使用哪种方法

本文关键字:方法 MVC NET 何时使 显示 ASP 显示图 图像 | 更新日期: 2023-09-27 18:16:09

我正在使用ASP建立一个网站。NET MVC4来上传/显示图像,并找到了一些如何显示图像的方法,主要如下-

1)将图像以文件的形式存储在服务器上,并使用相对路径在页面上显示。

 //ImageFile is a property which holds a path to the image in the model
 <img src="@item.ImageFile" />
 When the page is rendered, this becomes a path like - <img src="/Content/Images/Jellyfish.jpg" />      

2)将图像存储为字节数组并使用控制器操作检索-

//Use a controller action (GetImg) to get the URL of the image
<img src="@Url.Action("GetImg", "ViewPhotos", new { id = item.ID })" alt="Image" />  
When the page is rendered, this becomes a path like - <img src="/ViewPhotos/GetImg/4" alt="Image" />    

3)将图像存储为字节数组并直接在视图中检索-

//Directly re-construct the image in the view from the byte array (Image property of the model)
<img src="@String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(item.Image))" />  
When the page is rendered, this becomes a path like - <img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAgEA....<long string> .../>

我的问题是-

1) 1和2的区别是什么?

1直接提供文件的路径,2提供文件的URL。它们在后台是相同的还是一种方法比另一种更好?

我在这里检查过了,它说- Url。Action将构造动作的路径,返回url,而不是执行动作的结果。那么什么时候检索结果呢?

2)当3与1或2对应时是否会对性能产生影响?

3)当图像大小较小(小于1MB)或较大时,应使用哪种方法?

如果你能给我指出任何可以帮助的链接,我很高兴。谢谢。

代码-

//模型
public class Photo
{
  public int ID { get; set; }
  public string ImageFile { get; set; }
  public byte[] Image { get; set; }
  public string Caption { get; set; }
}

//控制器
public FileContentResult GetImg(int id)
{
    byte[] byteArray = db.Photos.Find(id).Image;
    if (byteArray != null)
    {
        return new FileContentResult(byteArray, "image/jpeg");
    }
    else
    {
         return null;
    }
}

//View (approach 2)

@model IEnumerable<MyPhotoLibrary.Models.Photo>
@foreach (var item in Model) {
<tr>
  <td>
    <img src="@Url.Action("GetImg", "ViewPhotos", new { id = item.ID })" alt="Image" />
  </td>
</tr>
}

//视图(这是方法3)

@model IEnumerable<MyPhotoLibrary.Models.Photo>
@foreach (var item in Model) {
<tr>
  <td>
    <img src="@String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(item.Image))" />
  </td>
</tr>
}

在ASP中显示图像的不同方法.NET MVC以及何时使用哪种方法

我最近自己查找了这个,并且看到了Microsoft的研究论文To BLOB Or Not To BLOB,其中比较了将文件(例如图像)作为二进制数据存储在数据库中的性能与传统文件系统的性能。

研究结果,大致总结:

  • 小文件(大小> 256KB)最好作为字节数组存储在数据库中(您的第二和第三个选项),可以从中快速检索并提供给用户。
  • 大文件(大小> 1MB左右)最好存储在文件系统中(您的第一选择),因为大文件会使大型数据库blob的吞吐量和碎片急剧恶化
  • 在256KB和1MB之间(大致;该范围是模糊的,取决于您的确切设置)性能取决于文件可能被编辑或覆盖的次数;一般来说,数据库在处理静态文件时性能更好,而文件系统在处理频繁更改的文件时能够更好地保持高吞吐量和低碎片。

选项之间的其他区别:

选项1要求应用程序对图像所在的文件夹具有读权限,如果用户正在上传或编辑图像,则应用程序还需要对该文件夹具有写权限。如果您使用的是共享主机(特别是廉价或免费的主机计划),或者如果您的系统管理员特别偏执,这可能会很棘手。

选项2需要从客户端调用更多的服务器来获取所有的数据;这可能看起来像一件坏事,但它确实将页面加载分解成可能实际上有所帮助的块-页面(没有图像)将在第一次调用时加载,然后图像将被单独请求,如果其中一个需要一段时间,或者有某种错误,那么页面的其余部分应该不受影响,这很好。正如jgauffin在评论中指出的那样,这个选项允许你为图片设置缓存,这样浏览器就可以通过只在图片发生变化时重新下载来节省带宽。

选项3要求客户端一次装载整批货物,这可能需要一些时间。它还将字节数组的处理转移到客户端,这对于智能手机或低端上网本等低功耗客户端可能是一个问题。如果您的图像很大,最好使用服务器的CPU能力来实际处理从字节数组到图像文件的转换。正如jgauffin在评论中指出的那样,这也不能很好地与缓存一起发挥作用——如果视图的HTML的任何部分发生变化,浏览器将不得不再次下载图像

同样,这可能与您的具体情况无关,但是通过单独的调用加载图像可以让您在这些操作中做其他事情,例如编写调试日志或在幕后做其他一些家务。

1)在服务器端的处理会更少,因为函数调用会更少。如果要呈现动作的输出,则需要调用HTML helper方法HTML。RenderAction或Html。这里有更多关于差异的操作

2) 2和3之间的区别在于,当您直接输入字节数组时,您到服务器的往返次数更少(DNS查找等),但在单个请求中需要下载更多数据。有些浏览器可能会并行下载内容(每个域名5-8个并行下载),所以如果你使用3个,你就会失去页面加载速度。更多关于并行下载的信息请点击这里和这里

,这导致我们选择3)如果你有小图片,3是最好的选择,因为客户端会请求更少的资源,页面会加载得更快,但如果你有大图片,你应该使用1。

我没有时间测试性能,但我将保留一些要点。

在方法1中,你确实只依赖于硬盘存储和性能来保存文件,以及你的web服务器提供静态文件的能力。

在方法2中,每次有请求时都生成字节流…存储和检索是DB驱动的(HDD当然起作用),如果不添加一些相关代码(可能只是一个属性OutputCache,但它可能更复杂),你就不能利用web服务器的本地缓存功能。

在方法3中,客户端只是渲染,您将图像与网页一起发送。这里的性能确实取决于浏览器,但请记住,如果图像非常大,它将花费一些时间来接收整个页面。

所以我通常更喜欢方法1,我只需要在数据库中存储一个映像路径,然后我可以从磁盘获取映像,让IIS做缓存,交付,优化等。

有很多正当的理由去方法2,这主要是如果你有一个分布式的web服务器架构,其中方法1意味着每个服务器必须在硬盘上保存图像的副本,而在数据库中的一个地方有一切意味着你可以检索图像,只要你想…也许可以实现一点缓存,以避免在每个请求中访问DB。

方法3实际上只适用于一次性使用的小图像。我说单次使用,因为你不希望使用它的图标和图像到处使用,这些应该保持静态,以便他们可以被客户端缓存。

希望这能帮助你做出更好的决定。

在类似于2的场景中,使用多个web服务器架构,在过去的工作中,我们采用混合解决方案:图像在DB上,但每个web服务器,在为图像点击404后的第一个请求,将从DB下载图像并指示客户端重试(这在某种程度上是一个非常原始的缓存实现)。