【问题标题】:Optimize image for web (C# & ASP.NET MVC)优化 Web 图像(C# 和 ASP.NET MVC)
【发布时间】:2018-08-12 04:42:18
【问题描述】:

我正在寻找一种在 .NET 中有效地为网站准备大量图像的方法

图像通常是来自手机摄像头的大型、未经编辑、2-5MB 4000x8000 像素的怪物图像。

我想快速、尽可能高效地生成缩略图。 (不降低 CPU 速度)或用户性能。

我还得考虑缓存。

现代 CMS 系统正在使用您可以通过前端调用的图像预处理器。所以我也想做这样的东西,但是我自己的。因为就我而言,我不能在这里使用 CMS。

这是我的代码:我有一个来自 Helper 类的静态辅助方法。 每次我需要渲染图像时,我都会用剃刀调用它。

public static string GetImgThumbnail(string web_path, int _width = 0, int _height = 0)
{
        //Default parameters
        Image image;
        Image thumbnail;
        string thumb_url = "/img/noimg.png";

        try
        {
            // web_path example input "/images/helloworld.jpg"
            //system_path returns system path of Ogirinal image in the system f.e.: "C:\projects\websites\mysite\images\helloworld.jpg"
            string system_path = HttpContext.Current.Server.MapPath(web_path);
            image = Image.FromFile(system_path);

            //Original image dimensions
            int width = image.Width;
            int height = image.Height;

            //Get New image dimensions
            if(_height == 0)
            {
                if(_width == 0)
                {
                    _width = 700;
                }
                _height = (_width * height) / width;
            }

            if (_width == 0)
            {
                if (_height == 0)
                {
                    _height = 700;
                }
                _width = (_height * width) / height;
            }

            //Generate Thumbnail, passing in new dimensions
            thumbnail = image.GetThumbnailImage(_width, _height, null, IntPtr.Zero);

            //Find out how to call newly created thumbnail.
            //Original image example name = "/images/helloworld.jpg" thumbnail would be "/images/helloworld_thumb_700x250.jpg" or analogical with .png or JPEG etc...
            //Suffix should be "_thumb_{width}x{height}"
            string suffix = string.Format("_thumb_{0}x{1}", _width.ToString(),_height.ToString());

            var bigImgFilename = String.Format("{0}{1}",
                     Path.GetFileNameWithoutExtension(system_path), Path.GetExtension(system_path));

            var newImgFilename = String.Format("{0}{1}{2}",
                     Path.GetFileNameWithoutExtension(system_path), suffix, Path.GetExtension(system_path));

            //New system path of new Thumbnail example: "C:\projects\websites\mysite\images\helloworld_thumb_700x250.jpg"
            var newpath = system_path.Replace(bigImgFilename, newImgFilename);

            //Set new web path, expect this to be: "/images/helloworld_thumb_700x250.jpg"
            thumb_url = web_path.Replace(bigImgFilename, newImgFilename);

            //Check if file exists, no need to overrite if file exists.
            if (!File.Exists(newpath)) 
            { 
                thumbnail.Save(newpath);
            }

        }
        catch (Exception exc)
        {
            // If something goes wrong, just return backup image.
            thumb_url = "/img/noimg.png";
        }

        // return thumbnail 
        return thumb_url;
}

想听听一些提示/建议,或者我是否走在正确的道路上,或者我应该以不同的方式去做?

【问题讨论】:

  • 看看 ImageResizer 项目我不明白你的代码在计算宽度和高度时应该做什么,但第二组 ifs 不可能正确,因为它检查 _width 是否为 0 两次
  • 谢谢,这是一个错字,我更正了我的代码示例。
  • 离题但有一些实用的想法:您可以考虑像cloudimage.io 这样的云服务。一旦请求,他们将从您的位置下载图像,调整大小(可能的其他操作,如裁剪、应用过滤器、压缩)并返回缓存副本(从现在开始),一切只需更改 URL 即可。我知道,任何东西都可以编程,但这些服务有时会非常有用。

标签: c# asp.net-mvc image


【解决方案1】:

因此,在您的代码中,您首先计算缩略图。然后计算文件名并检查是否需要计算缩略图。

我会以不同的顺序做:

  1. 加载图像(因为您需要它来计算新文件名)
  2. 计算新文件名
  3. 检查文件是否已经存在
  4. 如果文件已经存在,请使用它
  5. 如果没有,则生成缩略图。

在代码中大致如下所示:

public static string GetImgThumbnail(string web_path, int _width = 0, int _height = 0)
{

    [...]
    string system_path = HttpContext.Current.Server.MapPath(web_path);
    image = Image.FromFile(system_path);

    // calculate new width and height
    [...]

    // calculate new filename
    [...]
        //New system path of new Thumbnail example: "C:\projects\websites\mysite\images\helloworld_thumb_700x250.jpg"
        var newpath = system_path.Replace(bigImgFilename, newImgFilename);

        //Set new web path, expect this to be: "/images/helloworld_thumb_700x250.jpg"
        thumb_url = web_path.Replace(bigImgFilename, newImgFilename);

        //Check if file exists, no need to overrite if file exists.
        if (!File.Exists(newpath)) 
        { 
            //Generate Thumbnail, passing in new dimensions
            thumbnail = image.GetThumbnailImage(_width, _height, null, IntPtr.Zero);
            thumbnail.Save(newpath);
        }

我的观点是:加载图像并计算大小不会使用太多资源。调整大小的部分对 CPU 来说是一个沉重的负担。因此,如果您仅在必要时转换图像,您将获得更快的响应。


您可以考虑以下几点:

每次需要渲染图像时,我都会用剃刀调用它。

这将在每个图像视图上生成一个缩略图。这是非常重的 CPU,很可能不是您想要的。考虑只创建一次缩略图,将其保存到磁盘并开始使用预渲染版本。

下一期:

//Check if file exists, no need to overrite if file exists.
if (!File.Exists(newpath)) 
{ 
    thumbnail.Save(newpath);
}

您首先计算缩略图,然后检查计算是否已经完成。应该是反过来的。

【讨论】:

  • 虽然这些观点可能是有效的,但这并不试图回答 OP 的问题。这应该是评论,而不是答案。
  • 嗨,rollstuhlfahrer,你有一些好的观点,完全同意这一点。但是首先调用 File.Exists() 的邮件问题是我需要获取 NewPath,并且只有在通过 OldPath(a.k.a)web_path 之后才能获取新路径。所以我需要先把它分解,然后我知道我需要寻找(或创建)它有什么扩展名的文件等等......因为用户可能会添加我完全没想到的 TIFF 文件格式。
  • 做了一些修改。我越来越近了吗?
  • @rollstuhlfahrer 您的回答在这种情况下非常有帮助,它确实解决了我的问题。对此表示衷心的感谢! :)
猜你喜欢
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 2012-05-11
  • 1970-01-01
  • 2014-06-05
  • 2017-01-18
相关资源
最近更新 更多