ImageSharp一个专注于NetCore平台图像处理的开源项目
今天大家分享的是一個(gè)專注于NetCore平臺(tái)圖像處理的開源項(xiàng)目,老實(shí)說為這篇文章取名字想了5分鐘,可能是詞窮亦或是想更好的表達(dá)出這款開源項(xiàng)目的作用;這個(gè)項(xiàng)目在圖像處理方面有很多功能,如:縮放,裁剪,繪畫,組合圖片等;今天主要講的是用她怎么來繪圖和生成驗(yàn)證碼的實(shí)際例子。
號(hào)外:近來淘寶服裝小店進(jìn)了批新貨,有需要購衣的朋友可以來看看,地址在文章最下方。
-
簡(jiǎn)單介紹ImageSharp
-
試試畫兩條線(實(shí)線和虛線)
-
生成個(gè)縮略圖
-
在圖片上畫字
-
制作一個(gè)驗(yàn)證碼圖片
-
結(jié)合RazorPage模板,展示驗(yàn)證碼圖片
簡(jiǎn)單介紹ImageSharp
ImageSharp是對(duì)NetCore平臺(tái)擴(kuò)展的一個(gè)圖像處理方案,在寫下本文為止它最新的nuget下載量為4,034次,作者團(tuán)隊(duì)最近一個(gè)月剛更新的包;沒錯(cuò)這里說最新是因?yàn)樗吧砗椭暗陌姹径己苁軞g迎下載量也超高;她的git項(xiàng)目地址:https://github.com/SixLabors/ImageSharp。如果您的項(xiàng)目和我一樣是2.0版本(2.0以前的略過),那么直接可以通過vs的nuget控制臺(tái)下載對(duì)應(yīng)的包,注意繪圖的話需要分別下載如下兩個(gè)包:
?Install-Package SixLabors.ImageSharp -Version?1.0.0-beta0001?
?Install-Package SixLabors.ImageSharp.Drawing -Version?1.0.0-beta0001?
ImageSharp用法有朋友之前寫過,不過都主要針對(duì)于之前的版本,本章主要用到的都是最新的,有部分寫法可能不相同。
試試畫兩條線(實(shí)線和虛線)
這里將用她來畫兩條直線并保存成圖片,主要起到一個(gè)介紹作用,先來看實(shí)線如下代碼:
?總要步驟我都備注上文字了,這里主要通過兩點(diǎn)一線來繪制圖形,Vector2對(duì)象值得注意就是C#二維坐標(biāo)(x,y)對(duì)象,其實(shí)除了Vector2還有Vector3(三維坐標(biāo))等,這對(duì)于做u3d的朋友來說不會(huì)陌生,老實(shí)說這個(gè)也是我在接觸u3d時(shí)候才知道有這個(gè)類的。下面來看效果圖:
由兩個(gè)兩點(diǎn)一線構(gòu)造的一個(gè)角,下面來看下虛線繪制:
//虛線using (Image<Rgba32> image = new Image<Rgba32>(500, 500)) //畫布大小 ? ? ? ? ? ?{image.Mutate(x => x.BackgroundColor(Rgba32.WhiteSmoke). ? //畫布背景 ? ? ? ? ? ? ? ? ? ? ? ? ? ?DrawLines(Pens.Dash(Rgba32.HotPink, 5), //字體大小new SixLabors.Primitives.PointF[]{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?new Vector2(10, 10), ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?new Vector2(200, 150), ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?new Vector2(50, 300)} //兩點(diǎn)一線坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ?));image.Save($"{path}/2.png"); //保存}步驟都差不多,只是調(diào)用了DrawLines的擴(kuò)展方法而已,其他線條例子就不多說了各位自行實(shí)驗(yàn)。
生成個(gè)縮略圖和在圖片上畫字
對(duì)于圖片類型的網(wǎng)站來說縮略圖是常見的,這里用ImageSharp生成縮略圖很簡(jiǎn)單,本實(shí)例用8.png做樣本來生成縮略圖8-1.png,直接看例子如下是netstandard 1.3+的例子:
//縮略圖using (Image<Rgba32> image = Image.Load($"{path}/8.png")){image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2));image.Save($"{path}/8-1.png");}為了更好的對(duì)比縮略圖和原圖的區(qū)別這里對(duì)接拿兩圖的屬性做對(duì)比如:
能很好的看出縮略圖文件大小和像素都減半了,實(shí)際縮略的時(shí)候不一定減半,這全由參數(shù)控制Resize(width,height);
畫字:在圖片上畫我們想要的字,其實(shí)類似于水印的一種需求,下面是在圖片上畫字的代碼:
//畫字 var install_Family = new FontCollection().Install(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/bak", "STKAITI.TTF") ? ? ? ? ? ? ? ?//@"C:\Windows\Fonts\STKAITI.TTF" ? //字體文件 ? ? ? ? ? ? ? ?); ? ? ? ? ? ?var font = new Font(install_Family, 50); //字體using (Image<Rgba32> image = Image.Load($"{path}/8.png")){image.Mutate(x => x.DrawText( ? ? ? ? ? ? ? ? ? ? ? ?"你們好,我是神牛", //文字內(nèi)容 ? ? ? ? ? ? ? ? ? ? ? ? font,Rgba32.HotPink, ? ? ? ? ? ? ? ? ? ? ? ? new Vector2(50, 150),TextGraphicsOptions.Default));image.Save($"{path}/8-2.png");}
這里用ImageSharp在圖片上畫字的時(shí)候需要注意:字體,因?yàn)閣indows系統(tǒng)自帶了字體問題這里以STKAITI.TTF字體文件為例,它存儲(chǔ)于?C:\Windows\Fonts\STKAITI.TTF?目錄,當(dāng)然您可以直接把它拷貝到我們項(xiàng)目中如下我這里的例子一樣做法(這里只測(cè)試了windows下可用,尚未測(cè)試linux下直接使用該字體文件是否可行);
制作一個(gè)驗(yàn)證碼圖片
下面我們將用她來畫一個(gè)驗(yàn)證碼類型的圖片,通常驗(yàn)證碼都有一些點(diǎn)和線來干擾,上面已經(jīng)有畫線例子了,這里展示怎么畫點(diǎn):
這里直接利用IImageProcessingContext<TPixel>擴(kuò)展方法Draw來繪制有規(guī)則的點(diǎn),如圖所示:
比較單調(diào),或許您們能做的更好看些;下面來做驗(yàn)證碼圖片,主要由:畫點(diǎn)+畫字=驗(yàn)證碼圖片,這里我封裝了一個(gè)方法直接生成驗(yàn)證碼圖片:
/// <summary>/// 畫點(diǎn)+畫字=驗(yàn)證碼圖片 ?/// </summary>/// <param name="content">驗(yàn)證碼</param>/// <param name="outImgPath">輸出圖片路徑</param>/// <param name="fontFilePath">字體文件</param>/// <param name="x">圖片寬度</param>/// <param name="y">圖片高度</param>public void GetValidCode( ? ? ? ? ? ? ? ? ? ?string content = "我是神牛", ? ? ? ? ? ? ? ? ? ?string outImgPath = "D:/F/學(xué)習(xí)/vs2017/netcore/Study.AspNetCore/WebApp02-1/wwwroot/images/10.png", ? ? ? ? ? ? ? ? ? ?string fontFilePath = @"D:\F\學(xué)習(xí)\vs2017\netcore\Study.AspNetCore\WebApp02-1\wwwroot\bak\STKAITI.TTF", ? ? ? ? ? ? ? ? ? ?int xx = 150, int yy = 25){ ? ? ? ? ? ?var dianWith = 1; //點(diǎn)寬度var xx_space = 10; //點(diǎn)與點(diǎn)之間x坐標(biāo)間隔var yy_space = 5; //y坐標(biāo)間隔var wenZiLen = content.Length; //文字長(zhǎng)度var maxX = xx / wenZiLen; //每個(gè)文字最大x寬度var prevWenZiX = 0; //前面一個(gè)文字的x坐標(biāo)var size = 16;//字體大小 ? ? ? ? ? ?//字體var install_Family = new FontCollection().Install(fontFilePath ? ? ? ? ? ? ?//@"C:\Windows\Fonts\STKAITI.TTF" ? //windows系統(tǒng)下字體文件 ? ? ? ? ? ? ?); ? ? ? ? ? ?var font = new Font(install_Family, size); //字體 ? ? ? ? ? ?//點(diǎn)坐標(biāo)var listPath = new List<IPath>(); ? ? ? ? ? ?for (int i = 0; i < xx / xx_space; i++){ ? ? ? ? ? ? ? ?for (int j = 0; j < yy / yy_space; j++){ ? ? ? ? ? ? ? ? ? ?var position = new Vector2(i * xx_space, j * yy_space); ? ? ? ? ? ? ? ? ? ?var linerLine = new LinearLineSegment(position, position); ? ? ? ? ? ? ? ? ? ?var shapesPath = new SixLabors.Shapes.Path(linerLine);listPath.Add(shapesPath);}} ? ? ? ? ? ?//畫圖using (Image<Rgba32> image = new Image<Rgba32>(xx, yy)) //畫布大小 ? ? ? ? ? ?{image.Mutate(x =>{ ? ? ? ? ? ? ? ? ? ?//畫點(diǎn)var imgProc = x.BackgroundColor(Rgba32.WhiteSmoke). //畫布背景 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Draw(Pens.Dot(Rgba32.HotPink, dianWith), ? //大小new SixLabors.Shapes.PathCollection(listPath) //坐標(biāo)集合 ? ? ? ? ? ? ? ? ? ? ? ? ?); ? ? ? ? ? ? ? ? ? ?//逐個(gè)畫字for (int i = 0; i < wenZiLen; i++){ ? ? ? ? ? ? ? ? ? ? ? ?//當(dāng)前的要輸出的字var nowWenZi = content.Substring(i, 1); ? ? ? ? ? ? ? ? ? ? ? ?//文字坐標(biāo)var wenXY = new Vector2(); ? ? ? ? ? ? ? ? ? ? ? ?var maxXX = prevWenZiX + (maxX - size);wenXY.X = new Random().Next(prevWenZiX, maxXX);wenXY.Y = new Random().Next(0, yy - size);prevWenZiX = Convert.ToInt32(Math.Floor(wenXY.X)) + size; ? ? ? ? ? ? ? ? ? ? ? ?//畫字 ? ? ? ? ? ? ? ? ? ? ? ?imgProc.DrawText(nowWenZi, ? //文字內(nèi)容 ? ? ? ? ? ? ? ? ? ? ? ? ? font,i % 2 > 0 ? Rgba32.HotPink : Rgba32.Red,wenXY,TextGraphicsOptions.Default);}}); ? ? ? ? ? ? ? ?//保存到圖片 ? ? ? ? ? ? ? ?image.Save(outImgPath);}}
通過簡(jiǎn)單的調(diào)用?GetValidCode("我是神牛");return?Page();?能得到如圖驗(yàn)證碼圖片的效果:
文字看起來好像在點(diǎn)的前面,不過沒關(guān)系只需要把畫點(diǎn)和畫字的先后順序修改下就行了,這里不貼圖了;
結(jié)合RazorPage模板,展示驗(yàn)證碼圖片
上面一節(jié)是生成了驗(yàn)證碼圖片,當(dāng)然實(shí)際場(chǎng)景中我們是不需要生成驗(yàn)證碼物理圖片的,只需要返回一個(gè)流或base64等方式輸出到web界面上就行了,我們可以來看看?Image<TPixel>?保存時(shí)候的擴(kuò)展方法:
好吧有點(diǎn)多,我們只需要明白她能轉(zhuǎn)base64,stream,保存為圖片等就行了;這里我們將用到?SaveAsPng(Stream)?方法,然后獲取他的byte[],如下代碼:
/// <summary>/// 畫點(diǎn)+畫字=驗(yàn)證碼byte[] ? ? ?? ?/// </summary>/// <param name="content">驗(yàn)證碼</param>/// <param name="outImgPath">輸出圖片路徑</param>/// <param name="fontFilePath">字體文件</param>/// <param name="x">圖片寬度</param>/// <param name="y">圖片高度</param>public byte[] GetValidCodeByte( ? ? ? ? ? ? ? ? ? ?string content = "我是神牛", ? ? ? ? ? ? ? ?
? ?string fontFilePath = @"D:\F\學(xué)習(xí)\vs2017\netcore\Study.AspNetCore\WebApp02-1\wwwroot\bak\STKAITI.TTF", ? ? ? ? ? ? ? ? ?
?int xx = 150, int yy = 25){ ? ? ? ? ? ?
var bb = default(byte[]); ? ? ? ?
? ?try{ ? ? ? ? ?
var dianWith = 1; //點(diǎn)寬度var xx_space = 10; //點(diǎn)與點(diǎn)之間x坐標(biāo)間隔var yy_space = 5; //y坐標(biāo)間隔var wenZiLen = content.Length; //文字長(zhǎng)度var maxX = xx / wenZiLen; //每個(gè)文字最大x寬度var prevWenZiX = 0; //前面一個(gè)文字的x坐標(biāo)var size = 16;//字體大小 ? ? ? ? ? ? ? ?//字體var install_Family = new FontCollection().Install(fontFilePath ? ? ? ? ? ? ? ? ?//@"C:\Windows\Fonts\STKAITI.TTF" ? //windows系統(tǒng)下字體文件 ? ? ? ? ? ? ? ? ?); ? ? ? ? ? ? ?
? ? ? ? ? ? ??var font = new Font(install_Family, size); //字體 ? ? ? ? ? ? ? ?//點(diǎn)坐標(biāo)var listPath = new List<IPath>(); ? ? ? ? ? ? ? ?for (int i = 0; i < xx / xx_space; i++){ ? ? ? ? ? ? ? ?
? ?for (int j = 0; j < yy / yy_space; j++){ ? ? ? ? ? ? ? ? ? ? ? ?
var position = new Vector2(i * xx_space, j * yy_space); ? ? ? ? ? ? ? ? ? ? ? ?var linerLine = new LinearLineSegment(position, position); ? ? ? ? ? ? ? ? ? ? ? ?var shapesPath = new SixLabors.Shapes.Path(linerLine);listPath.Add(shapesPath);}} ? ? ? ? ? ? ?
??//畫圖using (Image<Rgba32> image = new Image<Rgba32>(xx, yy)) //畫布大小 ? ? ? ? ? ? ? ?{image.Mutate(x =>{ ? ? ? ? ? ? ? ? ? ?
var imgProc = x; ? ? ? ? ? ? ? ? ? ? ? ?//逐個(gè)畫字for (int i = 0; i < wenZiLen; i++){ ? ? ? ? ? ? ? ? ? ?
? ? ? ?//當(dāng)前的要輸出的字var nowWenZi = content.Substring(i, 1); ? ? ? ? ? ? ? ? ? ? ? ?
? ?//文字坐標(biāo)var wenXY = new Vector2(); ? ? ? ? ? ? ? ? ? ? ? ? ? ?var maxXX = prevWenZiX + (maxX - size);wenXY.X = new Random().Next(prevWenZiX, maxXX);wenXY.Y = new Random().Next(0, yy - size);prevWenZiX = Convert.ToInt32(Math.Floor(wenXY.X)) + size; ? ? ? ? ? ? ? ? ? ? ? ? ? ?//畫字 ? ? ? ? ? ? ? ? ? ? ? ? ? ?imgProc.DrawText(nowWenZi, ? //文字內(nèi)容 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? font,i % 2 > 0 ? Rgba32.HotPink : Rgba32.Red,wenXY,TextGraphicsOptions.Default);} ? ? ? ? ? ? ? ?
? ? ? ?//畫點(diǎn) imgProc.BackgroundColor(Rgba32.WhiteSmoke). //畫布背景 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Draw(Pens.Dot(Rgba32.HotPink, dianWith), ? //大小new SixLabors.Shapes.PathCollection(listPath) //坐標(biāo)集合 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? );}); ? ? ? ? ? ? ? ? ? ?using (MemoryStream stream = new MemoryStream()){image.SaveAsPng(stream);bb = stream.GetBuffer();}}} ? ? ? ?
? ? ? ? ? ?catch (Exception ex){} ? ? ?
? ? ?return bb;}
該方法返回了一個(gè)byte[]數(shù)組,然后通過HttpGet方式請(qǐng)求Razor接口,前端就能夠獲取到這個(gè)驗(yàn)證碼圖片byte[]了;
? ?? ?/// </summary>/// <returns></returns>public FileResult OnGetValidCode(){ ? ? ? ? ? ?var codebb = GetValidCodeByte(DateTime.Now.ToString("mmssfff")); ? ? ? ? ? ?return File(codebb, "image/png");}
我們通過get請(qǐng)求獲取驗(yàn)證碼:?http://localhost:1120/login?handler=ValidCode?,然后得到如圖效果:
本篇內(nèi)容到此就結(jié)束了,如果對(duì)您有好的幫助,不妨點(diǎn)個(gè)“贊”;一起努力推動(dòng)NetCore發(fā)展吧,謝謝。
原文地址:?http://www.cnblogs.com/wangrudong003/p/7656842.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的ImageSharp一个专注于NetCore平台图像处理的开源项目的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新的.NET Framework聚焦于
- 下一篇: 2017中国开源年会(COSCon'17