天天看點

.NET Core使用skiasharp文字頭像生成方案(基于docker釋出)

一、問題背景

  目前.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内部中去

  

.NET Core使用skiasharp文字頭像生成方案(基于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"]      

 上張成功的圖:

.NET Core使用skiasharp文字頭像生成方案(基于docker釋出)

   最後DEMO位址

  libSkiaSharp.so位址

四、總結

  docker是個好東西,隻是我太弱雞,大概需要花更多的時間去學習吧,程式員可能真的得活到老學到老!

  PS:以上的隻是我自己摸索出來的,如果大家有更好的實作方式歡迎讨論,謝謝觀看

  最後熊本熊鎮随筆,該死的K8S,該死的docker!!!

.NET Core使用skiasharp文字頭像生成方案(基于docker釋出)

作者: Mango

出處: http://www.cnblogs.com/OMango/

關于自己:專注.Net桌面開發以及Web背景開發,開始接觸微服務、docker等網際網路相關(最近被網際網路架構搞的死去活來- -)

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結,如有問題, 可站内留言聯系.