123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- using SkiaSharp;
- using System.Globalization;
- using System.IO;
- using System;
- namespace JiaZhiQuan.Common.Utils
- {
- /// <summary>
- /// 用户昵称生成图片工具类
- /// </summary>
- public static class UserAliasGenerateImageUtils
- {
- /// <summary>
- /// 绘制用户昵称图片,返回流(!!!流用完自己关)
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- public static Stream Generate(UserAliasGenerateDTO dto)
- {
- // 字符串内容
- string text = dto.Text;
- // 当前内容总宽度
- float textSumWidth = 0;
- int maxEmojiWidth = dto.FontSize + 20;
- using var bitmap = new SKBitmap(dto.Width, dto.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
- using var canvas = new SKCanvas(bitmap);
- // 创建绘图笔
- using var paint = new SKPaint()
- {
- Color = dto.FontColor,
- TextSize = dto.FontSize,
- // 抗锯齿
- IsAntialias = true,
- LcdRenderText = false,
- Style = SKPaintStyle.Fill,
- FilterQuality = SKFilterQuality.High
- };
- // 文字基于图片定位坐标
- float x = 0;
- float y = paint.TextSize;
- TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(text);
- while (enumerator.MoveNext())
- {
- string element = enumerator.GetTextElement();
- if (string.IsNullOrWhiteSpace(element))
- {
- // 如果是空格,直接计算下一次定位的x坐标即可,不需要绘制
- x += paint.MeasureText(element);
- continue;
- }
- // 判断文本元素的类型
- if (char.IsLetter(element[0]))
- {
- // 处理英文字符
- paint.Typeface = SKTypeface.FromFamilyName("Microsoft YaHei");
- }
- else if (char.IsDigit(element[0]))
- {
- // 处理数字字符
- paint.Typeface = SKTypeface.FromFamilyName("Microsoft YaHei");
- }
- else if (char.IsPunctuation(element[0]))
- {
- // 处理符号字符
- paint.Typeface = SKTypeface.FromFamilyName("Microsoft YaHei");
- }
- else
- {
- // 处理其他字符(如中文字符和 Emoji)
- if (CheckStringChineseUn(element))
- {
- paint.Typeface = SKTypeface.FromFamilyName("Microsoft YaHei");
- }
- else
- {
- paint.Typeface = SKTypeface.FromFamilyName("Segoe UI Emoji");
- }
- }
- // 计算字符的宽度
- float charWidth = paint.MeasureText(element) > maxEmojiWidth ? maxEmojiWidth : paint.MeasureText(element);
- textSumWidth += charWidth;
- // 判断当前是否超过最大宽度
- if (textSumWidth >= dto.MaxWidth)
- {
- // 多余的字符用省略号代替
- canvas.DrawText("...", x, y, paint);
- break;
- }
- // 绘制字符
- canvas.DrawText(element, x, y, paint);
- // 调整下一个字符的位置
- x += charWidth + dto.FontLeftMargin;
- }
- // 保存图像到文件
- using var image = SKImage.FromBitmap(bitmap);
- using var data = image.Encode(SKEncodedImageFormat.Png, 100);
- // 流不关闭,需要在外部关闭
- var stream = new MemoryStream();
- data.SaveTo(stream);
- // 替换为要保存的文件路径
- //string filePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "yug_test.png");
- //using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
- //{
- // // 将 MemoryStream 中的数据写入到文件流
- // stream.WriteTo(fileStream);
- //}
- return stream;
- }
- /// <summary>
- /// 检查字符串是否包含中文
- /// </summary>
- /// <param name="text"></param>
- /// <returns></returns>
- public static bool CheckStringChineseUn(string text)
- {
- bool res = false;
- foreach (char t in text)
- {
- if (t >= 0x4e00 && t <= 0x9fff)
- {
- res = true;
- break;
- }
- }
- return res;
- }
- }
- public class UserAliasGenerateDTO
- {
- /// <summary>
- /// 内容区域最大宽度
- /// </summary>
- public int MaxWidth { get; set; }
- /// <summary>
- /// 图片宽度
- /// </summary>
- public int Width { get; set; }
- /// <summary>
- /// 图片宽度
- /// </summary>
- public int Height { get; set; }
- /// <summary>
- /// 内容
- /// </summary>
- public string Text { get; set; }
- /// <summary>
- /// 字体大小
- /// </summary>
- public int FontSize { get; set; }
- /// <summary>
- /// 字体颜色
- /// </summary>
- public SKColor FontColor { get; set; }
- /// <summary>
- /// 文字左边距
- /// </summary>
- public int FontLeftMargin { get; set; } = 2;
- }
- }
|