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

   承接以前的组件系列,这个组件系列旨在介绍.NET相关的组件,让大家可以在项目中有一个更好的选择组件的介绍绝对不是一篇文章可以叙述完的,因为一个组件是经过开发者很长周期的开发,绝不是我这里一篇简单的博文就可以介绍完毕的,组件介绍的系列,一般会沿袭着组件背景介绍、组件使用介绍、核心对象介绍等等内容。如果对组件感兴趣,可以深入的了解和学习。

   废话少说,进入正题。

   我们在项目中很多时候都会对文件进行处理,例如文件的上传下载等等。其中对图片的实时操作也会较多,在这里介绍一款用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.Web是ImageProcessor的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。

  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参数表示将图片存储在浏览器缓存中的最长天数。

四.总结

    说句实话,这位作者的编码风格是喜欢的,代码简介明了,没有那么多装逼的写法,不会为了使用一些写法,而去改变代码的可读性。对于这个组件系列,我会近可能的写一些,大家可以借此了解一些组件,需要深入了解和使用的,可以自己查看源码,进行对应的扩展。写完这篇,已经凌晨两点了,为自己点个赞,无论写的怎样,觉得自己还是尽心了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏进步博客

[译]响应式图像

自从2010年Ethan Marcotte开始讨论响应式网页设计,开发者和设计师们竞相寻求处理响应式图片的方法。这的确是一个棘手的问题 ,因为我们对同一个网站在...

842
来自专栏yl 成长笔记

ps 替换背景以及调整尺寸

领导吩咐我修改她的图片背景,尺寸, 屁颠屁颠去弄,半小时后发现大学里学的 ps 忘差不多了,这里总结一下修改图片背景以及尺寸的基本操作。

623
来自专栏CNN

Tensorflow将模型导出为一个文件及接口设置

在上一篇文章中《Tensorflow加载预训练模型和保存模型》,我们学习到如何使用预训练的模型。但注意到,在上一篇文章中使用预训练模型,必须至少的要4个文件:

872
来自专栏量子位

简化深度学习实践流程:新鲜出炉的TensorFlow项目模板来了

林鳞 编译自 GitHub 量子位 出品 | 公众号 QbitAI 新的TensorFlow项目模板来了。 昨天,用户mrgemy95在Reddit上发帖,称这...

3574
来自专栏人工智能LeadAI

五分钟喝不完一杯咖啡,但五分钟可以带你入门TensorFlow

本文是《人人都能学人工智能-TensorFlow系列》文章的第一篇,这个系列会对TensorFlow的基础使用,SoftMax,交叉熵,Dropout,CNN,...

4259
来自专栏人人都是极客

4.训练模型之准备训练数据

终于要开始训练识别熊猫的模型了, 第一步是准备好训练数据,这里有三件事情要做: 收集一定数量的熊猫图片。 将图片中的熊猫用矩形框标注出来。 将原始图片和标注文件...

3738
来自专栏陈满iOS

看图学算法(一)算法基本概念篇

553
来自专栏算法+

快速均值模糊算法

前段时间在网上看到一个快速均值模糊算法,性能很不错。 源博客: http://www.lellansin.com/super-fast-blur-%E6%A8%...

3335
来自专栏C#

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

   承接以前的组件系列,这个组件系列旨在介绍.NET相关的组件,让大家可以在项目中有一个更好的选择,社区对于第三方插件的介绍还是比较少的,很多博文的内容主要还...

680
来自专栏大数据挖掘DT机器学习

利用word2vec对关键词进行聚类

按照一般的思路,可以用新闻ID向量来表示某个关键词,这就像广告推荐系统里面用用户访问类别向量来表示用户一样,然后就可以用kmeans的方法进行聚类了。不过对于新...

33110

扫码关注云+社区