视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.NET Core利用skiasharp文字头像生成方法教程(基于docker发布)
2020-11-27 22:35:03 责编:小采
文档


一、问题背景

目前.NET Core下面针对于图像处理的库微软并没有集成,在.NET FrameWork下我们已经习惯使用System.Drawing类库做简单的图像处理,到了.NET Core下一脸懵逼的我,只能百度+谷歌看看有没啥解决方案,好在网上资料也多,.NET Core下的图像处理还是有些开源库的,我目前使用的其中一个:SkiaSharp,介绍反正大家自己网上找找都有,下面就用该库实现一个文字头像的小功能,话不多说了,来一起看看详细的介绍吧。

二、简单的设计要求

  • 对于输入的名字得解析(中文、英文)
  • 图片背景色随机会换
  • 文字要居中(废话,不居中不是丑爆了)
  • 三、具体实现

    1、解析姓名信息

     private String ResolveName(String imageText)
     {
     imageText.Replace("?", "").Replace(":", "").Replace("?", "").Replace("*", "").Replace("<", "").Replace(">", "").Replace(@"/", "").Replace(@"\", "").Replace(@"|", "").Replace("\"", "");//去除路径不支持的信息
     imageText = imageText.Trim(' ');//去除空格信息
     String temp2 = imageText.Substring(0, 1);//根据第一位的数据判断是走英文规则还是中文规则,都不是的话就是取前两位
     if (RegexLib.IsChineseCharacter(temp2))
     {
     //UserName = UserName.Trim(' ');
     if (imageText.Length > 2 & imageText.Length <= 3)
     {
     imageText = imageText.Substring(1, 2);
     }
     else if (imageText.Length >= 3)
     {
     imageText = imageText.Substring(imageText.Length - 2, 2);
     }
     }
     else if (RegexLib.IsEnglishCharacter(temp2))
     {
     String[] temp1 = imageText.Split(' ');
     if (temp1.Length == 2)
     {
     imageText = (temp1[0].Substring(0, 1) + temp1[1].Substring(0, 1)).ToUpper();
     }
     else
     {
     if (imageText.Length > 2)
     {
     imageText = imageText.Substring(0, 2).ToUpper();
     }
     }
     }
     else
     {
     if (imageText.Length > 2)
     {
     imageText = imageText.Substring(0, 2);
     }
     }
     imageName = imageText;
     return imageName;
     }

    2、根据文字生成图片

     public byte[] Create()
     {
     String name = imageName + ".jpg";
     SKBitmap bmp = new SKBitmap(128, 128);
     String str = imageName;
    
     using (SKCanvas canvas = new SKCanvas(bmp))
     {
     Random r = new Random();
     int num = r.Next(0, 9);
     canvas.DrawColor(colors[num]); // colors是图片背景颜色集合,这里代码就不贴出来了,随机找一个
     using (SKPaint sKPaint = new SKPaint())
     {
     sKPaint.Color = SKColors.White;//字体颜色
     sKPaint.TextSize = 39;//字体大小
     sKPaint.IsAntialias = true;//开启抗锯齿
     sKPaint.Typeface = SkiaSharp.SKTypeface.FromFamilyName("微软雅黑", SKTypefaceStyle.Bold);//字体
     SKRect size = new SKRect();
     sKPaint.MeasureText(str, ref size);//计算文字宽度以及高度
     float temp = (128 - size.Size.Width) / 2;
     float temp1 = (128 - size.Size.Height) / 2;
     canvas.DrawText(str, temp, temp1 - size.Top, sKPaint);//画文字
     }
     //保存成图片文件
     using (SKImage img = SKImage.FromBitmap(bmp))
     {
     using (SKData p = img.Encode(SKEncodedImageFormat.Jpeg, 100))
     {
     return p.ToArray();
     //using (var stream = File.Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "photoImage", name)))
     //{
     // stream.Write(p.ToArray(), 0, p.ToArray().Length);
     // return stream;
     //}
     }
     }
     }
     }

    我这边只是得到的是byte[]数组,如果需要转成stream或者保存成文件,方法都有,找找肯定都可以找到的,我就不放出来了,

    三、docker发布的坑

    坑1:IIS下可以,docker下报错的坑爹问题

    由于skiasharp在windows跟linux下使用的依赖库是不同的,如果都按照以前的方式部署,在docker里就会出现"The type initializer for 'SkiaSharp.SKImageInfo' threw an exception",原因是linux下skiasharp依赖libSkiaSharp.so,而如果系统中没有libSkiaSharp.so,就会报这个错,目前我最简单的操作就是找到这个文件扔在skiasharp的目录下,然后就可以了

    坑2:中文字体不识别

    由于docker内部没有中文字体,SO,当要输出中文的时候就狗带了,如下图,所及解决办法那也就是把字体拷贝到docker内部中去

      

    下面提供我自己使用的Dockerfile,具体Dockerfile怎么用,那就只能大家自己百度百度(ps:其实真实原因是我自己这方面也是弱鸡- -,怕误导大家),我的环境是CentOS7.3的环境

    #基于 `microsoft/dotnet:latest` 来构建我们的镜像
    FROM microsoft/dotnet:latest
    
    #拷贝项目publish文件夹中的所有文件到 docker容器中的publish文件夹中 
    COPY . /publish /publish/
    
    #ENV LANG C.UTF-8
    #ENV LANGUAGE C.UTF-8
    #ENV LC_ALL C.UTF-8
    COPY MSYH.TTC /usr/share/fonts/dejavu
    COPY MSYHL.TTC /usr/share/fonts/dejavu
    COPY MSYHBD.TTC /usr/share/fonts/dejavu
    
    #更换软件源为国内的软件源
    RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
     echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list && \
     echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list && \
     echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list && \
     echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
    #RUN apt-get update && apt-get install -y libfontconfig1 && apt-get install -y fontconfig
    RUN apt-get update && apt-get install -y fontconfig
    
    #设置工作目录为 `/publish` 文件夹,即容器启动默认的文件夹
    WORKDIR /publish
    
    #设置Docker容器对外暴露5000端口
    EXPOSE 5000
    
    #使用`dotnet WebApplication1.dll`来运行应用程序
    
    CMD ["dotnet", "WebApplication1.dll"]

    上张成功的图:

      

    最后DEMO地址

    四、总结

    docker是个好东西,只是我太弱鸡,大概需要花更多的时间去学习吧,程序员可能真的得活到老学到老!

    PS:以上的只是我自己摸索出来的,如果大家有更好的实现方式欢迎讨论,谢谢观看

    下载本文
    显示全文
    专题