C# 使用WebImage从数据库字节字段渲染图像时出现问题

C# 使用WebImage从数据库字节字段渲染图像时出现问题,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我有一个asp.NETMVC5应用程序,带有一个存储照片的数据库。我正在尝试读取照片并调整其大小,以便在员工档案中显示 我对asp.net mvc和c都是新手# 我设置了以下控制器,但在img标签中使用指向控制器的链接时未显示图像 任何帮助都将不胜感激 public ActionResult Index(int id) { Staff staff = db.StaffList.Find(id); if (staff.Photo != null)

我有一个asp.NETMVC5应用程序,带有一个存储照片的数据库。我正在尝试读取照片并调整其大小,以便在员工档案中显示

我对asp.net mvc和c都是新手#

我设置了以下控制器,但在img标签中使用指向控制器的链接时未显示图像

任何帮助都将不胜感激

public ActionResult Index(int id)
    {
        Staff staff = db.StaffList.Find(id);
        if (staff.Photo != null)
        {
            var img = new WebImage(staff.Photo);
            img.Resize(100, 100, true, true);
            var imgBytes = img.GetBytes();

            return File(imgBytes, "image/" + img.ImageFormat);
        }
        else
        {
            return null;
        }
    }

环顾四周,人们似乎对WebImage类有很多不满,它有一些突出的bug。我决定使用名为ImageProcessor的nuget包,而不是尝试编写自己的包。这对我来说似乎相当低效,但我现在没有更好的答案,而且这没有被大量使用,所以我将继续这一步,继续前进

把它贴在这里,以防其他人也遇到类似的问题

    public ActionResult Index(int id, int? height, int? width)
    {
        int h = (height ?? 325);
        int w = (width ?? 325);

        Staff staff = db.StaffList.Find(id);
        if (staff == null)
        {
            return new HttpNotFoundResult();
        }
        if (staff.Photo != null)
        {
            Size size = new Size(w, h);
            byte[] rawImg;
            using (MemoryStream inStream = new MemoryStream(staff.Photo))
            {
                using (MemoryStream outStream = new MemoryStream())
                {
                    using (ImageFactory imageFactory = new ImageFactory())
                    {
                        imageFactory.Load(inStream)
                            .Constrain(size)
                            .Format(format)
                            .Save(outStream);
                    }
                    rawImg = outStream.ToArray();
                }
            }
            return new FileContentResult(rawImg, "image/jpeg");
        }
        else
        {
            return null;
        }
    }

因为你自己的答案使用了这个库,所以我要用这个来回答这个问题。免责声明。我也是图书馆的作者

使用ActionResult处理图像并不是最好的方法,因为它的效率非常低。它在管道中运行太晚,您将没有缓存

安装该软件包并实现自己版本的
IImageService
接口,以便为数据库中的图像提供服务,这样做会更好。(注意,除非您使用blob存储,否则将图像存储在db中也是不明智的)

通过实现
IImageService
接口,您可以使用库中带有特定前缀的url api来标识要使用的图像服务。例如,远程映像请求以
remote.axd
作为前缀,以告知IageProcessor.Web执行
RemoteImageService
实现

这样做的好处是缓存图像,以便后续请求从缓存返回,而不是在每次请求时重新处理

下面是
LocalFileImageService
的完整实现,这是库的默认服务。这应该可以作为如何实现您自己的服务的指南

namespace ImageProcessor.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading.Tasks;
    using System.Web;

    using ImageProcessor.Web.Helpers;

    /// <summary>
    /// The local file image service for retrieving images from the 
    /// file system.
    /// </summary>
    public class LocalFileImageService : IImageService
    {
        /// <summary>
        /// The prefix for the given implementation.
        /// </summary>
        private string prefix = string.Empty;

        /// <summary>
        /// Gets or sets the prefix for the given implementation.
        /// <remarks>
        /// This value is used as a prefix for any image requests 
        /// that should use this service.
        /// </remarks>
        /// </summary>
        public string Prefix
        {
            get
            {
                return this.prefix;
            }

            set
            {
                this.prefix = value;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the image service 
        /// requests files from
        /// the locally based file system.
        /// </summary>
        public bool IsFileLocalService
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Gets or sets any additional settings required by the service.
        /// </summary>
        public Dictionary<string, string> Settings { get; set; }

        /// <summary>
        /// Gets or sets the white list of <see cref="System.Uri"/>. 
        /// </summary>
        public Uri[] WhiteList { get; set; }

        /// <summary>
        /// Gets a value indicating whether the current request 
        /// passes sanitizing rules.
        /// </summary>
        /// <param name="path">
        /// The image path.
        /// </param>
        /// <returns>
        /// <c>True</c> if the request is valid; otherwise, <c>False</c>.
        /// </returns>
        public bool IsValidRequest(string path)
        {
            return ImageHelpers.IsValidImageExtension(path);
        }

        /// <summary>
        /// Gets the image using the given identifier.
        /// </summary>
        /// <param name="id">
        /// The value identifying the image to fetch.
        /// </param>
        /// <returns>
        /// The <see cref="System.Byte"/> array containing the image data.
        /// </returns>
        public async Task<byte[]> GetImage(object id)
        {
            string path = id.ToString();
            byte[] buffer;

            // Check to see if the file exists.
            // ReSharper disable once AssignNullToNotNullAttribute
            FileInfo fileInfo = new FileInfo(path);

            if (!fileInfo.Exists)
            {
                throw new HttpException(404, "No image exists at " + path);
            }

            using (FileStream file = new FileStream(path, 
                                           FileMode.Open, 
                                           FileAccess.Read, 
                                           FileShare.Read, 
                                           4096, 
                                           true))
            {
                buffer = new byte[file.Length];
                await file.ReadAsync(buffer, 0, (int)file.Length);
            }

            return buffer;
        }
    }
}
namespace ImageProcessor.Web.Services
{
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Threading.Tasks;
使用System.Web;
使用ImageProcessor.Web.Helpers;
/// 
///用于从中检索图像的本地文件映像服务
///文件系统。
/// 
公共类LocalFileImageService:IImageService
{
/// 
///给定实现的前缀。
/// 
私有字符串前缀=string.Empty;
/// 
///获取或设置给定实现的前缀。
/// 
///此值用作任何图像请求的前缀
///应该使用此服务。
/// 
/// 
公共字符串前缀
{
得到
{
返回此.prefix;
}
设置
{
this.prefix=值;
}
}
/// 
///获取一个值,该值指示图像服务
///从中请求文件
///基于本地的文件系统。
/// 
公共bool IsFileLocalService
{
得到
{
返回true;
}
}
/// 
///获取或设置服务所需的任何其他设置。
/// 
公共词典设置{get;set;}
/// 
///获取或设置的白名单。
/// 
公共Uri[]白名单{get;set;}
/// 
///获取一个值,该值指示当前请求
///通过消毒规则。
/// 
/// 
///图像路径。
/// 
/// 
///如果请求有效,则为True;否则为False。
/// 
公共bool IsValidRequest(字符串路径)
{
返回ImageHelpers.IsValidImageExtension(路径);
}
/// 
///使用给定标识符获取图像。
/// 
/// 
///标识要获取的图像的值。
/// 
/// 
///包含图像数据的数组。
/// 
公共异步任务GetImage(对象id)
{
字符串路径=id.ToString();
字节[]缓冲区;
//检查文件是否存在。
//ReSharper禁用一次分配NullToNotNullAttribute
FileInfo FileInfo=新的FileInfo(路径);
如果(!fileInfo.Exists)
{
抛出新的HttpException(404,“在”+路径上不存在映像);
}
使用(FileStream file=new FileStream(路径,
FileMode.Open,
FileAccess.Read,
文件共享,
4096, 
正确的)
{
buffer=新字节[file.Length];
wait file.ReadAsync(缓冲区,0,(int)file.Length);
}
返回缓冲区;
}
}
}

必须正确设置标记,以适当的大小显示标记。html/css比服务器对显示图像的大小有更大的影响。