ImageProcessor组件
ImageProcessor组件
开源免费的.NET图像即时处理的组件ImageProcessor
承接以前的组件系列,这个组件系列旨在介绍.NET相关的组件,让大家可以在项目中有一个更好的选择,社区对于第三方插件的介绍还是比较少的,很多博文的内容主要还是介绍一些简单的操作(很多人都说博客园现在是“hello world”的水平,博文质量在下降,对于这一说法,我觉得这个说法有些过头了,可能一些博文的确写的比较初级,但是很多博文的深入还是比较大,只是很少受人关注),这个组件系列主要在介绍一些功能的组件,附带该组件的核心对象介绍。
组件的介绍绝对不是一篇文章可以叙述完的,因为一个组件是经过开发者很长周期的开发,绝不是我这里一篇简单的博文就可以介绍完毕的,组件介绍的系列,一般会沿袭着组件背景介绍、组件使用介绍、核心对象介绍等等内容。如果对组件感兴趣,可以深入的了解和学习。
废话少说,进入正题。
我们在项目中很多时候都会对文件进行处理,例如文件的上传下载等等。其中对图片的实时操作也会较多,在这里介绍一款用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参数表示将图片存储在浏览器缓存中的最长天数。
四.总结
说句实话,这位作者的编码风格是喜欢的,代码简介明了,没有那么多装逼的写法,不会为了使用一些写法,而去改变代码的可读性。对于这个组件系列,我会近可能的写一些,大家可以借此了解一些组件,需要深入了解和使用的,可以自己查看源码,进行对应的扩展。写完这篇,已经凌晨两点了,为自己点个赞,无论写的怎样,觉得自己还是尽心了。
ImageProcessor组件的更多相关文章
- 开源免费的.NET图像即时处理的组件ImageProcessor
承接以前的组件系列,这个组件系列旨在介绍.NET相关的组件,让大家可以在项目中有一个更好的选择,社区对于第三方插件的介绍还是比较少的,很多博文的内容主要还是介绍一些简单的操作(很多人都说博客园现在是“ ...
- Open Source
资源来源于http://www.cnblogs.com/Leo_wl/category/246424.html RabbitMQ 安装与使用 摘要: RabbitMQ 安装与使用 前言 吃多了拉就是队 ...
- 使用ImageProcessor、CodeCarvings.Piczard组件生成缩略图和添加水印
技术栈: 1.ImageProcessor(专业图像处理,不能合成水印,NetCore中有它的升级版ImageSharp目前是预览包) 2.CodeCarvings.Piczard(缩略图,水印都能搞 ...
- ExtJS 4.2 评分组件
上一文章是扩展ExtJS自带的Date组件.在这里将创建一个评分组件. 目录 1. 介绍 2. 示例 3. 资源下载 1. 介绍 代码参考的是 Sencha Touch 2上的一个RatingStar ...
- react组件的生命周期
写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...
- react-router 组件式配置与对象式配置小区别
1. react-router 对象式配置 和 组件式配置 组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...
- Angular2入门系列教程3-多个组件,主从关系
上一篇 Angular2项目初体验-编写自己的第一个组件 好了,前面简单介绍了Angular2的基本开发,并且写了一个非常简单的组件,这篇文章我们将要学会编写多个组件并且有主从关系 现在,假设我们要做 ...
- Angular2入门系列教程2-项目初体验-编写自己的第一个组件
上一篇 使用Angular-cli搭建Angular2开发环境 Angular2采用组件的编写模式,或者说,Angular2必须使用组件编写,没有组件,你甚至不能将Angular2项目启动起来 紧接着 ...
- .NET Core 首例 Office 开源跨平台组件(NPOI Core)
前言 最近项目中,需要使用到 Excel 导出,找了一圈发现没有适用于 .NET Core的,不依赖Office和操作系统限制的 Office 组件,于是萌生了把 NPOI 适配并移植到 .NET C ...
随机推荐
- Python比较(关系)运算符
比较(关系)运算符 运 算 符 作 用 举 例 结 果 > 大于 'a'>'b' False < 小于 156<456 True == 等于 'c' ...
- Linux文件管理命令 cat
1.cat 命令:将文件内容连接后传送到标准输出或重定向到文件. 1)命令语法格式:cat [OPTION] [FILE]... 2)命令选项参数说明如下所示. -n(number):从第一行开始对文 ...
- windbg调试子进程
windbg 调试子进程 学习过程中遇到了一个从前未调试过的情景:我正在调试的进程通过CreateProcessW创建了一个子进程,我需要去了解子进程中发生的行为. 那么怎么去调试呢?OD 就有点麻烦 ...
- Java多线程(一) 什么是线程
声明:本系列大多是翻译自https://www.javatpoint.com,加上自己的增删改,尽力写的系统而通俗易懂,后文不再重复声明. 点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更 ...
- MySQL高级知识(六)——索引优化
前言:索引优化的目的主要是让索引不失效,本篇通过相关案例对索引优化进行讲解. 0.准备 创建经典的tb_emp表. DROP TABLE IF EXISTS `tb_emp`; CREATE TABL ...
- VMware中某个虚拟机卡死,单独关闭某个虚拟机的办法
在虚拟机中部署ceph时,其中一个虚拟机突然意外卡死,网络搜索到解决的办法,特此整理如下: 一.找到卡死虚拟机的安装目录,在安装目录下找到VMware这个文本文档 二.打开该文本文档,在文档中查找pi ...
- 小a的子序列 (线性dp)
思路:设dp[i][j]表示最大数为j,i为第i的位置的萌值.那么推导过程就是两种情况:1.第i位数不放数字,则结果就是dp[i-1][j]; 2.第i位放数字,则结果就是前面的萌值sum+dp[i- ...
- selenium之frame
https://blog.csdn.net/huilan_same/article/details/52200586
- Python:Day03 变量、字符编码
配置环境变量 右键计算机--->属性--->高级系统设置--->高级--->环境变量--->系统变量--->找到Path,双击编辑--->将程序的路径粘贴上去 ...
- 微信硬件平台(七) 设备控制控制面板-网页sokect-mqtt长连接
给微信硬件设备添加我们自己的控制面板. 主要问题: 1 要保证长连接,这样面板可以实时交互阴间设备,http一次性的连接模式通信不行. 面板必须是网页化的,网页就可以操作交互.不用APP和小程序. 2 ...