在.Net Core 2.1下使用SkiaSharp进行图片处理

栏目: ASP.NET · 发布时间: 6年前

内容简介:在.Net Core下,没有可以支持跨平台的Drawing类库,官网提供的Common.Drawing只能在Windows下使用,那么在.Net Core下该如何处理图片呢?其实有很多第三方提供了解决方案,而我比较喜欢用的是Mono团队提供的SkiaSharp,原因是稳定而且支持的也很好,性能上也还好。Skia是Google旗下的2D图形处理库,下面是援引百科中的词条:skia是个2D向量图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现。不仅用于Google Chrome浏览器,新兴的

在.Net Core下,没有可以支持跨平台的Drawing类库,官网提供的Common.Drawing只能在Windows下使用,那么在.Net Core下该如何处理图片呢?其实有很多第三方提供了解决方案,而我比较喜欢用的是Mono团队提供的SkiaSharp,原因是稳定而且支持的也很好,性能上也还好。

一、SkiaSharp是什么?

1.Skia介绍

Skia是Google旗下的2D图形处理库,下面是援引百科中的词条:

skia是个2D向量图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现。不仅用于Google Chrome浏览器,新兴的Android开放手机平台也采用skia作为绘图处理,搭配OpenGL/ES与特定的硬件特征,强化显示的效果。

Skia官网 中是这样介绍的:

Skia is an open source 2D graphics library which provides common APIs that work across a variety of hardware and software platforms. It serves as the graphics engine for Google Chrome and Chrome OS, Android, Mozilla Firefox and Firefox OS, and many other products.

2.SkiaSharp介绍

SkiaSharp故名思义,就是在.net下使用Skia API的库,是SkiaSharp是由mono团队开发并进行持续维护,至今已经多年了。目前的最新版本是1.60.3,当前支持.net下的:

  • .NET Standard 1.3

  • .NET Core

  • Tizen

  • Xamarin.Android

  • Xamarin.iOS

  • Xamarin.tvOS

  • Xamarin.watchOS

  • Xamarin.Mac

  • Windows Classic Desktop (Windows.Forms / WPF)

  • Windows UWP (Desktop / Mobile / Xbox / HoloLens)

SkiaSharp项目: https://github.com/mono/SkiaSharp

二、SkiaSharp的安装

可以通过nuget命令进行安装:

nuget install skiasharp

或者在要使用的项目下,打开nuget管理器,搜索skiasharp进行安装。

三、SkiaSharp的使用

1.生成缩略图

这里假设已经安装好SkiaSharp 1.60.3版本。

我们先把要缩略的原图加载到内存中:

using (var input = File.OpenRead($"{PlatformServices.Default.Application.ApplicationBasePath}wwwroot/{pic}"))

这里的变量 pic 是图片的相对路径。

之后实例化一个 SKManagedStream

using (var inputStream = new SKManagedStream(input))

最后,把 inputStream 加载到 SKBitmap 画布中

using (var original = SKBitmap.Decode(inputStream))

之后重新设置图片的尺寸,也就是完成缩略处理:

using (var resized = original
           .Resize(new SKImageInfo(width, height), SKBitmapResizeMethod.Lanczos3))
        {
            if (resized == null) return "";
            using (var image = SKImage.FromBitmap(resized))
            {
                using (var output =
                       File.OpenWrite($"{PlatformServices.Default.Application.ApplicationBasePath}wwwroot/{thumb_name}"))
                {
                    image.Encode(SKEncodedImageFormat.Png,quality)
                        .SaveTo(output);
                }
            }
        }

其中,变量 widthheight 分别为缩略图的宽度和高度, thumb_name 为缩略图要保存的文件名, quality 是质量,一般设置为75,或者是其他的自己觉得合适的值。

完整的例子:

using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
using SkiaSharp;

        public static string MakeThumb(string pic,string thumb_dir, int width, int height)
        {
            const int quality = 75; //质量为75%
            using (var input = File.OpenRead($"{PlatformServices.Default.Application.ApplicationBasePath}wwwroot/{pic}"))
            using (var inputStream = new SKManagedStream(input))
            using (var original = SKBitmap.Decode(inputStream))
            {
                string[] arr_pic = pic.Split('/');
                string filename = arr_pic[arr_pic.Length - 1];  //完整文件名
                string[] arr_filename = filename.Split('.');
                string ext = "";
                if (arr_filename.Length >= 2)
                {
                    ext = arr_filename[arr_filename.Length - 1];    //最后一个为扩展名
                }
                string thumb_name = $"{filename.Remove(filename.Length - ext.Length - 1)}-{width}x{height}.png";  //文件名,缩略图保存为png
                string save_dir = $"/attach/{thumb_dir}/thumb/{DateTime.Now.ToString("yyyy-MM-dd")}";
                string savepath = $"{PlatformServices.Default.Application.ApplicationBasePath}wwwroot{save_dir}";
                if (!Directory.Exists(savepath))
                {
                    Directory.CreateDirectory(savepath);
                }
                string thumb_file = $"{save_dir}/{thumb_name}";
                using (var resized = original
                   .Resize(new SKImageInfo(width, height), SKBitmapResizeMethod.Lanczos3))
                {
                    if (resized == null) return "";
                    using (var image = SKImage.FromBitmap(resized))
                    {
                        using (var output =
                               File.OpenWrite($"{savepath}/{thumb_name}"))
                        {
                            image.Encode(SKEncodedImageFormat.Png,quality)
                                .SaveTo(output);
                        }
                    }
                }
                return thumb_file;
            }
        }

2.把指定的字体打印到图片上

其实图片的文字水印、图片验证码都可以从这个例子上扩充出来。

首先还是要安装SkiaSharp,之后,实例化 SKImageInfo

var info = new SKImageInfo(width, height);

创建一个新的 SKSurface

using (var surface = SKSurface.Create(info))

设置画布背景透明:

var canvas = surface.Canvas;
canvas.Clear(SKColors.White);

设置 SKPaint 的参数

var paint = new SKPaint
        {
            Color = SKColors.Black,//颜色
            IsAntialias = true,//抗锯齿
            Style = SKPaintStyle.Fill,
            TextAlign = SKTextAlign.Center,//居中
            TextSize = 40F,//字号
            Typeface= SkiaSharp.SKTypeface.FromFile(fontpath, 0)//加载字体
        };

这里除了指定字体的路径之外,还可以使用 SkiaSharp.SKTypeface.FromFamilyName("微软雅黑",SKTypefaceStyle.Bold) 来通过字体名来设置要使用的字体;参数 fontpath 是字体的物理路径。

参数设置好之后,进行绘图:

var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize / 2);
canvas.DrawText(text, coord, paint);

最后,生成图片:

using (var image = surface.Snapshot())
using (var data = image.Encode(SKEncodedImageFormat.Png, 100))

一个简单的例子:

using SkiaSharp;
using System.Linq;
        public static byte[] CreateImage(string fontpath, string text,float font_size=100)
        {
            var info = new SKImageInfo(1100, 480);
            using (var surface = SKSurface.Create(info))
            {
                var canvas = surface.Canvas;
                canvas.Clear(SKColors.White);
                
                var paint = new SKPaint
                {
                    Color = SKColors.Black,
                    IsAntialias = true,
                    Style = SKPaintStyle.Fill,
                    TextAlign = SKTextAlign.Center,
                    TextSize = font_size,
                    Typeface= SkiaSharp.SKTypeface.FromFile(fontpath, 0)
                };
                var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize) / 2);
                canvas.DrawText(text, coord, paint);                
                using (var image = surface.Snapshot())
                using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
                {
                    return data.ToArray();
                }
            }
        }

这个是指定的文字内容使用指定的字体直接显示到空白图片上,但是不支持文字换行。我们下面的例子是对上面的进行改进,支持文字换行:

public static byte[] CreateImage(string fontpath, string text,float font_size=100)
{
    //支持文字多行
    List<string> list = text.Split('\n').ToList();
    list.RemoveAll(x => { return string.IsNullOrEmpty(x.Trim()); });    //删除空行
    list.Reverse(); //顺序反转
    float line_height = 1.5F;   //行距
    float height = 480;
    if (list.Count * line_height*font_size >= height)
    {
        height = list.Count * line_height * font_size;
    }
    var info = new SKImageInfo(1100, (int)height);
    using (var surface = SKSurface.Create(info))
    {
        var canvas = surface.Canvas;
        canvas.Clear(SKColors.White);
        
        var paint = new SKPaint
        {
            Color = SKColors.Black,
            IsAntialias = true,
            Style = SKPaintStyle.Fill,
            TextAlign = SKTextAlign.Center,
            TextSize = font_size,
            Typeface= SkiaSharp.SKTypeface.FromFile(fontpath, 0)
        };

        int i = 0;
        list.ForEach(x =>
        {
            var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize * (list.Count - i) - paint.TextSize * i * 1.5F) / 2);
            canvas.DrawText(x.Trim(), coord, paint);
            i++;
            
        });

        using (var image = surface.Snapshot())
        using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
        {
            return data.ToArray();
        }
    }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Maven实战

Maven实战

许晓斌 / 机械工业出版社 / 2010年12月 / 65.00元

你是否早已厌倦了日复一日的手工构建工作?你是否对各个项目风格迥异的构建系统感到恐惧?Maven——这一Java社区事实标准的项目管理工具,能帮你从琐碎的手工劳动中解脱出来,帮你规范整个组织的构建系统。不仅如此,它还有依赖管理、自动生成项目站点等超酷的特性,已经有无数的开源项目使用它来构建项目并促进团队交流,每天都有数以万计的开发者在访问中央仓库以获取他们需要的依赖。 本书内容全面而系统,Ma......一起来看看 《Maven实战》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试