Font font); 这个方法返回的 SizeF 包含 Width 和 Height 属性

时间:2021-11-25 03:34:47

需求是要做一个编纂文字的页面。用户在网页端写文字,文字区域是个矩形框,用户可以通过下方的拖动条调治文字巨细。
如下图:

Font font); 这个方法返回的 SizeF 包含 Width 和 Height 属性

提交数据的时候前端传文字区域的左上角和右下角定位给后台。因为前真个字体巨细单位与后端没什么关系,所以不能直接传字体巨细,也就是后端要按照矩形区域以及文字内容来本身推算用什么样的字体巨细合适。

简单说就是知道文字的矩形区域,以及文字内容,要让文字内容按照矩形区域巨细调解到适合的字体巨细能对照合适地填满这个区域。

分析&思路

Graphics 类有个 MeasureString 要领,可以用来计算以当前字体写出来的文字会占据几多像素。
如下:

// // 摘要: // 丈量用指定的 System.Drawing.Font 绘制的指定字符串。 // // 参数: // text: // 要丈量的字符串。 // // font: // System.Drawing.Font,它界说字符串的文本格局。 // // 返回功效: // 此要领返回 System.Drawing.SizeF 布局,该布局暗示 text 参数指定的、使用 font 参数绘制的字符串的巨细,单位由 System.Drawing.Graphics.PageUnit // 属性指定。 // // 异常: // T:System.ArgumentException: // font 为 null。 public SizeF MeasureString(string text, Font font);

这个要领返回的 SizeF 包罗 Width 和 Height 属性,,读取这两个属性可以获取到文字内容所占的宽高(以像素为单位)。

// // 摘要: // 获取或设置此 System.Drawing.SizeF 布局的程度分量。 // // 返回功效: // 此 System.Drawing.SizeF 布局的程度分量,凡是以像素为单位进行器量。 public float Width { get; set; } // 摘要: // 获取或设置此 System.Drawing.SizeF 布局的垂直分量。 // // 返回功效: // 此 System.Drawing.SizeF 布局的垂直分量,凡是以像素为单位进行器量。 public float Height { get; set; }

于是我们可以先按照前端传过来的文字左上角与右下角定位,算出文字的矩形区域,然后预计一个字体巨细,再用 MeasureString 要领计算出估算的文字所占区域,对照和实际的文字区域巨细,大了则缩小字体,小了则增大字体。这样即可约莫找出合适的文字巨细。

具体实现

添加文字要领

/// <summary> /// 图片添加文字,文字巨细自适应 /// </summary> /// <param>图片路径</param> /// <param>左上角定位(x1,y1)</param> /// <param>右下角定位(x2,y2)</param> /// <param>文字内容</param> /// <param>字体名称</param> /// <returns>添加文字后的Bitmap东西</returns> public static Bitmap AddText(string imgPath, string locationLeftTop, string locationRightBottom, string text, string fontName = "华文行楷") { Image img = Image.FromFile(imgPath); int width = img.Width; int height = img.Height; Bitmap bmp = new Bitmap(width, height); Graphics graph = Graphics.FromImage(bmp); // 计算文字区域 // 左上角 string[] location = locationLeftTop.Split(‘,‘); float x1 = float.Parse(location[0]); float y1 = float.Parse(location[1]); // 右下角 location = locationRightBottom.Split(‘,‘); float x2 = float.Parse(location[0]); float y2 = float.Parse(location[1]); // 区域宽高 float fontWidth = x2 - x1; float fontHeight = y2 - y1; float fontSize = fontHeight; // 首次预计先用文字区域高度作为文字字体巨细,后面再做调解,单位为px Font font = new Font(fontName, fontSize, GraphicsUnit.Pixel); SizeF sf = graph.MeasureString(text, font); int times = 0; // 调解字体巨细以适应文字区域 if (sf.Width > fontWidth) { while (sf.Width > fontWidth) { fontSize -= 0.1f; font = new Font(fontName, fontSize, GraphicsUnit.Pixel); sf = graph.MeasureString(text, font); times++; } Console.WriteLine("一开始预计大了,最终字体巨细为{0},循环了{1}次", font.ToString(), times); } else if (sf.Width < fontWidth) { while (sf.Width < fontWidth) { fontSize += 0.1f; font = new Font(fontName, fontSize, GraphicsUnit.Pixel); sf = graph.MeasureString(text, font); times++; } Console.WriteLine("一开始预计小了,最终字体巨细为{0},循环了{1}次", font.ToString(), times); } // 最终的得出的字体所占区域一般不会恰好即是实际区域 // 所以按照两个区域的相差之处再把文字开始位置(左上角定位)稍微调解一下 x1 += (fontWidth - sf.Width) / 2; y1 += (fontHeight - sf.Height) / 2; graph.DrawImage(img, 0, 0, width, height); graph.DrawString(text, font, new SolidBrush(Color.Black), x1, y1); graph.Dispose(); img.Dispose(); return bmp; }

测试挪用

private static void Main(string[] args) { try { DrawingEntity drawing = new DrawingEntity(); Console.WriteLine("Start drawing ..."); System.Drawing.Bitmap bmp = drawing.AddText(@"D:\test\39585148.png", "177.75,63.84", "674.73, 141.6", "大海啊,全是浪"); bmp.Save(@"D:\test\output.png"); bmp.Dispose(); Console.WriteLine("Done!"); } catch (System.Exception ex) { Console.WriteLine("堕落了!!\n" + ex.ToString()); } finally { System.Console.WriteLine("\nPress any key to continue ..."); System.Console.ReadKey(); } }

最终效果:

Font font); 这个方法返回的 SizeF 包含 Width 和 Height 属性