开源免费的.NET图像即时处理的组件ImageProcessor

   承接之前的组件系列,这个组件系列旨在介绍.NET相关的组件,让你们能够在项目中有一个更好的选择,社区对于第三方插件的介绍仍是比较少的,不少博文的内容主要仍是介绍一些简单的操做(不少人都说博客园如今是“hello world”的水平,博文质量在降低,对于这一说法,我以为这个说法有些过头了,可能一些博文的确写的比较初级,可是不少博文的深刻仍是比较大,只是不多受人关注),这个组件系列主要在介绍一些功能的组件,附带该组件的核心对象介绍。web

   组件的介绍绝对不是一篇文章能够叙述完的,由于一个组件是通过开发者很长周期的开发,毫不是我这里一篇简单的博文就能够介绍完毕的,组件介绍的系列,通常会沿袭着组件背景介绍、组件使用介绍、核心对象介绍等等内容。若是对组件感兴趣,能够深刻的了解和学习。浏览器

   废话少说,进入正题。缓存

   咱们在项目中不少时候都会对文件进行处理,例如文件的上传下载等等。其中对图片的实时操做也会较多,在这里介绍一款用C#编写的轻量级库的集合,它容许你使用.NET 4.5+来动态地处理图像的组件,那就是ImageProcessor,用于图像的即时处理的.NET库。(组织的开源项目组,会通过第一个项目的磨合后,第二项目会开发一个.NET Core组件)安全

一.ImageProcessor组件概述

    ImageProcessor是用C#编写的轻量级库的集合,它容许你使用.NET 4.5+来动态地处理图像,包括两个主库ImageProcessor(用于桌面和应用程序使用)ImageProcessor.Web(ASP.NET构建的动态图像处理扩展),该组件快速,可扩展,易于使用,捆绑了一些很强大的功能,并且是彻底开源。该组件有两个部分,咱们今天将主要讲解ImageProcessor部分的内容,若是对另一个感兴趣,能够自行了解。服务器

   ImageProcessor.Web向项目添加了一个可配置的HttpModule,容许对图像文件进行即时处理。该模块还提供了一个基于文件和浏览器的缓存,能够处理数百万的图像,增长处理输出和节省宝贵的服务器内存。该组件的功能方法包括:调整大小,旋转,圆角,翻转,裁剪,水印,过滤器,饱和度,亮度,对比度,质量,格式,小插曲,高斯模糊,高斯锐化和透明度。网络

   ImageProcessor.Web的当前版本是4.8.2,能够下载源码和DLL文件(本人建议最好下载源码,好处就不在这里赘述)。性能

   ImageProcessor.WebImageProcessor的Web扩展,容许开发人员使用Url API的查询字符串参数做为指令执行图像操做。此过程的输出是高度优化的网络,以确保web项目较高的性能。安装ImageProcessor.Web时,默认状况下,Web.config中添加配置节点,以下节点。学习

<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web" /></httpModules>

    这容许库ImageProcessingModule拦截本地图像处理请求。ImageProcessor.Web是高度可配置的。能够将其余配置文件添加到解决方案中,以便从多个来源检索,处理和缓存图像。对于该组件的配置设置能够查看文档。优化

二.ImageProcessor组件操做概述

  介绍了组件的相关信息,在这里介绍一下该组件的操做实例。ImageFactory类提供了对给定图像执行各类操做功能的方法。它通过精心设计以防止在以高性能方式处理图像时一般发生的各类内存泄漏。这使其能够安全地在桌面和Web环境中使用。ImageFactory自动检测给定图像的正确文件类型,而且该类的API是流畅的,这容许您轻松地连接方法以提供所需的输出。例如,如下代码加载,调整大小,设置新格式并保存包含图像信息的MemoryStream。this

  public static void Image(string file)
        {
            if (string.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException(file);
            }
            byte[] photoBytes = System.IO.File.ReadAllBytes(file);
            // 检测格式
            ISupportedImageFormat format = new JpegFormat { Quality = 70 };
            Size size = new Size(150, 0);
            using (MemoryStream inStream = new MemoryStream(photoBytes))
            {
                using (MemoryStream outStream = new MemoryStream())
                {
                    // 使用重载初始化ImageFactory以保留EXIF元数据。
                    using (ImageFactory imageFactory = new ImageFactory(true))
                    {
                        // 加载,调整大小,设置格式和质量并保存图像。
                        imageFactory.Load(inStream)
                                    .Resize(size)
                                    .Format(format)
                                    .Save(outStream);
                        //对获取的imageFactory对象进行对应的操做
                    }
                   //对获取的数据流进行操做
                }
            }

   对于图片的操做,具体有较多的操做方式,具体的方法有以下的方法:

方法名称 方法操做说明
Reset 将当前图像重置为其原始加载状态
Alpha 更改当前图像的不透明度
AutoRotate  执行自动旋转以确保反映EXIF定义的旋转最终图像
BitDepth 改变当前图像的位深度
Brightness 更改当前图像的亮度
BackgroundColor 更改当前图像的背景颜色
Constrain 约束当前图像,调整其大小以适合给定的尺寸,同时保持其纵横比
Contrast 更改当前图像的对比度
Crop 将当前图像裁剪到给定的位置和大小
DetectEdges 检测当前图像中的边缘
Resolution 设置图像的分辨率
EntropyCrop 将图像修剪到最大熵的区域
Filter 将过滤器应用于当前图像
Flip 水平或垂直翻转当前图像
Gamma 调整给定图像的灰度(光强度)份量
GaussianBlur 使用高斯内核模糊当前图像
Hue 改变当前图像的色调,改变总体颜色
Halftone 将当前图像转换为该图像的CMYK半色调表示
Quality 改变当前图像的输出质量
ReplaceColor 替换当前图像中的颜色
Resize 将当前图像调整为给定尺寸
Rotate 将当前图像旋转给定角度

    以上只是列出了一些主要的操做方法,还有其余的方法这里就再也不介绍,有兴趣能够本身取实践。下面就介绍一下一些核心对象。

三.ImageProcessor核心对象解析

    解析来咱们具体了解一下核心的方法和属性,看看源码仍是有好处。

  1.ImageFactory.Load()

 public ImageFactory Load(string imagePath)
        {
            FileInfo fileInfo = new FileInfo(imagePath);
            if (fileInfo.Exists)
            {
                this.ImagePath = imagePath;
                using (FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
                {
                    ISupportedImageFormat format = FormatUtilities.GetFormat(fileStream);
                    if (format == null)
                    {
                        throw new ImageFormatException("Input stream is not a supported format.");
                    }
                    MemoryStream memoryStream = new MemoryStream();
                    fileStream.CopyTo(memoryStream);
                    memoryStream.Position = 0;
                    this.Image = format.Load(memoryStream);
                    this.CurrentBitDepth = Image.GetPixelFormatSize(this.Image.PixelFormat);
                    this.InputStream = memoryStream;
                    format.Quality = DefaultQuality;
                    format.IsIndexed = FormatUtilities.IsIndexed(this.Image);
                    this.backupFormat = format;
                    this.CurrentImageFormat = format;
                    foreach (PropertyItem propertyItem in this.Image.PropertyItems)
                    {
                        this.ExifPropertyItems[propertyItem.Id] = propertyItem;
                    }
                    this.backupExifPropertyItems = this.ExifPropertyItems;
                    IAnimatedImageFormat imageFormat = this.CurrentImageFormat as IAnimatedImageFormat;
                    if (imageFormat != null)
                    {
                        imageFormat.AnimationProcessMode = this.AnimationProcessMode;
                    }
                    Image formatted = this.Image.Copy(this.AnimationProcessMode);
                    this.Image.Dispose();
                    this.Image = formatted;
                    this.ShouldProcess = true;
                }
            }
            else
            {
                throw new FileNotFoundException(imagePath);
            }
            return this;
        }

   该方法用来加载要处理的图像的方法, 始终首先调用此方法。该方法具备4个重载版本,分别接收的参数为string,byte[],Image,Stream。FormatUtilities.GetFormat(fileStream)方法从给定流获取正确的ISupportedImageFormat。在对图片的数据流进行操做时,首先会复制图片的流数据。format.Load(memoryStream)将咱们的映像设置为内存流值。图片数据流进行一个操做后,会调用Image.Copy(this.AnimationProcessMode)确保图像是最有效的格式。

   2.ImageFactoryExtensions.AutoProcess() 

 internal static ImageFactory AutoProcess(this ImageFactory factory, IWebGraphicsProcessor[] graphicsProcessors)
        {
            if (factory.ShouldProcess)
            {
                foreach (IWebGraphicsProcessor graphicsProcessor in graphicsProcessors)
                {
                    factory.CurrentImageFormat.ApplyProcessor(graphicsProcessor.Processor.ProcessImage, factory);
                    IDisposable disposable = graphicsProcessor.Processor.DynamicParameter as IDisposable;
                    disposable?.Dispose();
                }
            }
            return factory;
        }

     ImageFactoryExtensions类是ImageFactory类的扩展类,主要是扩展Web项目。AutoProcess()方法基于添加到图像路径的任何查询字符串参数,自动处理图像文件。graphicsProcessors参数表示要应用的图形处理器阵列。graphicsProcessor.Processor.DynamicParameter as IDisposable打开动态参数并处理任何须要它的类型。

   3.ImageProcessingModule.SetHeaders()

 public static void SetHeaders(HttpContext context, int maxDays)
        {
            object responseTypeObject = context.Items[CachedResponseTypeKey];
            object dependencyFileObject = context.Items[CachedResponseFileDependency];
            string responseType = responseTypeObject as string;
            string[] dependencyFiles = dependencyFileObject as string[];
            SetHeaders(context, responseType, dependencyFiles, maxDays);
        }

     在Web扩展中,ImageProcessingModule类比较重要,处理Web应用程序中的任何图像请求。SetHeaders()方法使浏览器和服务器将输出保存在其缓存中,从而提升性能。该方法接受两个参数,context表示请求的http消息对象,HttpContext对象对内在服务器对象的引用。maxDays参数表示将图片存储在浏览器缓存中的最长天数。

四.总结

   说句实话,这位做者的编码风格是喜欢的,代码简介明了,没有那么多装逼的写法,不会为了使用一些写法,而去改变代码的可读性。对于这个组件系列,我会近可能的写一些,你们能够借此了解一些组件,须要深刻了解和使用的,能够本身查看源码,进行对应的扩展。写完这篇,已经凌晨两点了,为本身点个赞,不管写的怎样,以为本身仍是尽心了。

相关文章
相关标签/搜索