【问题标题】:.Net Core Image Manipulation (Crop & Resize) / File Handling.Net Core 图像处理(裁剪和调整大小)/文件处理
【发布时间】:2016-12-13 12:06:01
【问题描述】:

在过去的 5 个小时里,我一直在寻找一种可行的方法来完成对我来说似乎很容易的任务,如果它是我正在使用的 .NET 系列的早期版本:

  1. 上传图片
  2. 调整图片大小和裁剪图片
  3. 将新图片保存到目录中

我遇到了几个处于预发布阶段或未完成阶段的库。

有没有人在没有特别包含 System.Drawing 命名空间和/或为早期版本的 .NET 框架添加依赖项的情况下完成了上述任务?

2016 年 8 月 8 日更新

我最终使用了 System.Drawing 一些非常烦人和令人失望的东西。如果您正在开发一个成千上万的开发人员使用的软件,并且所有这些开发人员都依赖该软件的组件,我相信,一个人不能只是想出一个新版本,在会议期间“甜言蜜语”地展示它放弃你的公开演讲技巧,而不是在乎你的工作,一方面自豪地高度重视它,另一方面,去掉它最常用和最需要的部分。

我自己确实理解并非常兴奋地欣赏 .net 新时代的核心框架 - 从经典 asp 的第一天开始就成为忠实的 asp 开发人员 - 然而,对我来说,它只是一个不完整的产品,导致比起快乐,更多的是挫折和失望。当当今内容驱动的世界有数以百万计的网站,完全依赖内容管理时,你不能只是站出来说,“嘿,我有这个聪明,技术,更精简,更快等等等等”,但是错误,你会在“管理”您的内容方面存在一些问题..

不应忘记,尽管 MS(和我们)对这个新的核心框架感到非常兴奋,现在已经开源等,还有其他语言和框架正在做 MS 承诺做的事情, 很长一段时间了。

【问题讨论】:

  • 文档中对上传进行了很好的描述,但是 .NET Core 中没有开箱即用的图像库,但也许有一些 3rd 方库。考虑到 .NET Core 仅在几周前发布,大多数开发人员只是在 RTM 上线后才开始移植他们的项目
  • 你检查过我下面提到的JavaScriptService吗?
  • 我不想花时间找出替代方案。我很生气,因为我们不得不这样做..(我说的是另类,如果这是做“某事”的“新”方式,那么我很乐意学习它。)

标签: asp.net-core asp.net-core-mvc crop image-resizing image-manipulation


【解决方案1】:

2021 年更新:现在有 System.Drawing.Common - 官方端口,x 平台

https://www.nuget.org/packages/System.Drawing.Common/

【讨论】:

    【解决方案2】:

    使用 SkiSharp,它也在微软官方文档中: https://docs.microsoft.com/en-us/dotnet/api/skiasharp?view=skiasharp-1.68.0

    【讨论】:

      【解决方案3】:

      ImageSharp

      ImageSharp 是一种新的、功能齐全、完全托管的跨平台 2D 图形 API。

      ImageSharp 旨在实现图像处理的大众化,为您提供了一个非常强大但又非常简单的 API。

      System.Drawing 相比,我们已经能够开发出更灵活、更容易编写代码并且更不容易发生内存泄漏的东西。系统范围的进程锁已经一去不复返了; ImageSharp 图像是线程安全的,并且在 Web 环境中得到完全支持。

      根据 .Net Standard 1.1 构建 ImageSharp 可用于设备、云和嵌入式/IoT 场景。

      【讨论】:

      • ImageSharp 工作,但它太慢了 - 13 秒调整平均大小的图像...
      • 在调试中,32 位模式,因为该环境尚不支持 SIMD,您不必费心实际测试或联系我。你是在故意拖我的图书馆吗?
      • @JamesSouth 你有最新进展吗?我看到它仍然被标记为预发布。谢谢
      • @Simon_Weaver beta4,rc 目标为 2 个月,希望 v1 in 3。
      • 我已经实现了 ImageSharp,因此它可以在控制器操作中调整图像的大小,但是当在 标签中调用 URL 时,请求不会像它们一样缓存在浏览器中与静态文件。有没有办法让这些请求缓存,所以每次都不会下载调整大小的图像?或者有没有办法为imageresizing.net can之类的静态图像文件实现ImageSharp?
      【解决方案4】:

      .NET Core Image Processing 博文(2017 年 1 月 19 日)比较了 6 个库:

      • CoreCompat.System.Drawing
      • ImageSharp
      • Magick.NET(仅限 Win)
      • SkiaSharp
      • FreeImage-dotnet-core
      • MagicScaler

      2 月 26 日更新:帖子已更新,添加了两个新包

      【讨论】:

      • 使用 SkiaSharp。 CoreCompat 不是线程安全和不完整的,ImageSharp 太慢了,Magick.NET WinOnly,FreeImage 有错误,MagicScaler 只做 Image-Scaling。
      • Magick.NET 不只是 win,我在 aspcore 上使用它。
      • “ImageSharp 太慢了”...我们又来了。
      • Magick.NET 已准备好在 Linux 上使用!!并且易于使用...github.com/dlemstra/Magick.NET
      【解决方案5】:

      要完成@Hossam Barakat 的答案,您可以使用Microsoft ASP.NET Core JavaScript Services 在运行时从 .NET 代码调用任意 NPM 包,这意味着您可以选择任何提供图像缩放的 npm 包并调用它。
      该示例使用sharp 模块,该模块有很多依赖项。如果您像我一样喜欢使用纯 javascript 的jimp

      Startup.cs

      public class Startup
      {
       ...
          // This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
              // Enable Node Services
              services.AddNodeServices();
      ...
          }
      ...
      }
      

      ImageController.cs

      using System;
      using System.IO;
      using System.Linq;
      using System.Threading.Tasks;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.AspNetCore.Mvc;
      using Microsoft.AspNetCore.NodeServices;
      using Microsoft.AspNetCore.StaticFiles;
      using System.Security.Cryptography;
      using System.Text;
      
      namespace NodeServicesExamples.Controllers
      {
          public class ResizeImageController : Controller
          {
              private const int MaxDimension = 1000;
              private static string[] AllowedMimeTypes = new[] { "image/jpeg", "image/png", "image/gif" };
      
              private IHostingEnvironment _environment;
              private INodeServices _nodeServices;
      
              public ResizeImageController(IHostingEnvironment environment, INodeServices nodeServices)
              {
                  _environment = environment;
                  _nodeServices = nodeServices;
              }
      
              [Route("resize/{*imagePath}")]
              [ResponseCache(Duration = 3600)]
              public async Task<IActionResult> Index(string imagePath, double maxWidth, double maxHeight)
              {
                  // Validate incoming params
                  if (maxWidth < 0 || maxHeight < 0 || maxWidth > MaxDimension || maxHeight > MaxDimension
                      || (maxWidth + maxHeight) == 0)
                  {
                      return BadRequest("Invalid dimensions");
                  }
      
                  var mimeType = GetContentType(imagePath);
                  if (Array.IndexOf(AllowedMimeTypes, mimeType) < 0)
                  {
                      return BadRequest("Disallowed image format");
                  }
      
                  // Locate source image on disk
                  var fileInfo = _environment.WebRootFileProvider.GetFileInfo(imagePath);
                  if (!fileInfo.Exists)
                  {
                      return NotFound();
                  }
      
                  var eTag = GenerateETag(Encoding.UTF8.GetBytes($"{fileInfo.LastModified.ToString("s")}-{fileInfo.Length}"));
                  HttpContext.Response.Headers["ETag"] = eTag;
      
                  var match = HttpContext.Request.Headers["If-None-Match"].FirstOrDefault();
                  if (eTag == match)
                  {
                      return StatusCode(304);
                  }
      
                  // Invoke Node and pipe the result to the response
                  var imageStream = await _nodeServices.InvokeAsync<Stream>(
                      "./Node/resizeImage",
                      fileInfo.PhysicalPath,
                      mimeType,
                      maxWidth,
                      maxHeight);
      
                  return File(imageStream, mimeType, fileInfo.Name);
              }
      
              private string GetContentType(string path)
              {
                  string result;
                  return new FileExtensionContentTypeProvider().TryGetContentType(path, out result) ? result : null;
              }
      
              private string GenerateETag(byte[] data)
              {
                  string ret = string.Empty;
      
                  using (var md5 = MD5.Create())
                  {
                      var hash = md5.ComputeHash(data);
                      string hex = BitConverter.ToString(hash);
                      ret = hex.Replace("-", "");
                  }
      
                  return ret;
              }
      
          }
      }
      

      节点\resizeImage.js

      var jimp = require("jimp");
      
      module.exports = function (result, physicalPath, mimeType, maxWidth, maxHeight) {
          // Invoke the 'jimp' NPM module, and have it pipe the resulting image data back to .NET
          jimp.read(physicalPath).then(function (file) {
              var width = maxWidth || jimp.AUTO;
              var height = maxHeight || jimp.AUTO;
              file.resize(maxWidth, height)
                   .getBuffer(mimeType, function (err, buffer) {
                       var stream = result.stream;
                       stream.write(buffer);
                       stream.end();
                   });
          }).catch(function (err) {
              console.error(err);
          });
      };
      

      安装 jimp:npm install jimp --save

      【讨论】:

        【解决方案6】:

        简短的回答是否定的,还没有。大多数(如果不是全部)当前库都依赖于 System.Drawing。如果你现在需要这个,我会走那条路并添加 System.Drawing。

        .NET 团队目前正在研究 Core 1.0 堆栈中缺少的功能,但这一功能在他们的优先级列表中还不够高:Link

        这是一个值得关注的库,因为它们非常接近没有 System.Drawing 的可发布 API。 :ImageSharp

        【讨论】:

          【解决方案7】:

          您可以使用Microsoft ASP.NET Core JavaScript Services 在运行时从 .NET 代码调用任意 NPM 包,这意味着您可以选择任何提供图像缩放的 npm 包并调用它。

          以下示例显示如何使用 JavaScriptServices 调整图像大小 https://github.com/aspnet/JavaScriptServices/tree/dev/samples/misc/NodeServicesExamples

          希望有帮助

          【讨论】:

          • 在我看来,在官方图像处理库构建或移植到 .Net Core 之前,这是最好的答案,因为 Node 已经是 ASP.Net Core 项目设计实践的一部分前端资源。 Node 有大量用于图像处理的包。您甚至可以在 Node.js 中使用 OpenCv 进行面部识别。只需在 Node 中的静态 Js 文件中编写您的图像助手类,然后通过 JSS 从 Core 调用它。
          • 如果 .NET Core 运行并需要 NodeJS,它的表现如何?
          • @hossam barakat - 你对最好/最流行的图像处理 NPM 包有什么建议吗?
          • 顺便说一句。看起来在你写完之后他们实际上用图表示例替换了他们的图像示例代码 - 但这只是“连接器”的演示 - 这是调整大小的图像示例 github.com/aspnet/JavaScriptServices/blob/v1.0.x/samples/misc/…
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多