承接以前的組件系列,這個組件系列旨在介紹.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參數表示將圖片存儲在瀏覽器緩存中的最長天數。
四.總結
說句實話,這位作者的編碼風格是喜歡的,代碼簡介明了,沒有那么多裝逼的寫法,不會為了使用一些寫法,而去改變代碼的可讀性。對于這個組件系列,我會近可能的寫一些,大家可以借此了解一些組件,需要深入了解和使用的,可以自己查看源碼,進行對應的擴展。寫完這篇,已經凌晨兩點了,為自己點個贊,無論寫的怎樣,覺得自己還是盡心了。
文章列表