C#利用GDI+给图片添加文字(文字自适应矩形区域)

前言

这篇文章是 GDI+ 总结系列的第二篇,如果对 GDI+ 的基础使用不熟悉的朋友可以先看第一篇文章《C# 使用 GDI+ 画图》。

需求

需求是要做一个编辑文字的页面。用户在网页端写文字,文字区域是个矩形框,用户可以通过下方的拖动条调节文字大小。

如下图:

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

简单说就是知道文字的矩形区域,以及文字内容,要让文字内容根据矩形区域大小调整到适合的字体大小能比较合适地填满这个区域。

分析&思路

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 name="imgPath">图片路径</param>
/// <param name="locationLeftTop">左上角定位(x1,y1)</param>
/// <param name="locationRightBottom">右下角定位(x2,y2)</param>
/// <param name="text">文字内容</param>
/// <param name="fontName">字体名称</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();
 }
}

最终效果:

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • C# WinForm实现图片浏览器

    C#WinForm程序设计之图片浏览器,这次我们一起做一个图片查看器,这个图片查看器的原始图如下: 我们首先来介绍一下这个原始图的构成: 左边上面是一个 TextBox 和 一个 Button,分别用来显示当前路径以及返回上一个路径.左边下面是一个浏览文件的文件路径树状图(TreeView),用来显示当前路径下的文件和文件夹.右边是一个pictureBox,用来展示选中的图片. 接下来我们一步一步实现这个图片查看器! 首先大家应该看到了左边的TreeView上面已经有显示当前PC的所有路径信息,

  • C#实现上传下载图片

    本文实例为大家分享了C#实现上传下载图片的具体代码,供大家参考,具体内容如下 1.首先我们通过流来上传下载图片,所有操作只停留在流这一层 MemoryStream ms; //左侧按钮 private void button1_Click(object sender, EventArgs e) { ms = new MemoryStream(); Image bi =pictureBox1.Image; bi.Save(ms, pictureBox1.Image.RawFormat);//将图片

  • C#对图片进行马赛克处理可控制模糊程度的实现代码

    具体代码如下所示: using System.Drawing; using System.Drawing.Imaging; using System.Web.Mvc; namespace MVC2017_Sample.Controllers { public class DefaultController : Controller { public ActionResult Index() { //原图 Image img = Image.FromFile("c:\\1.jpg");

  • C#设置Word文档背景的三种方法(纯色/渐变/图片背景)

    Word是我们日常生活.学习和工作中必不可少的文档处理工具.精致美观的文档能给人带来阅读时视觉上的美感.在本篇文章中,将介绍如何使用组件Free Spire.Doc for .NET(社区版)给Word设置文档背景.下面的示例中,给Word添加背景分为三种情况来讲述,即添加纯色背景,渐变色背景和图片背景. 工具使用:下载安装控件Free Spire.Doc后,在项目程序中添加Spire.Doc.dll即可(该dll可在安装文件下Bin文件夹中获取) 一.添加纯色背景 using Spire.Do

  • C#图片查看器实现方法

    实现效果: 注意:using system.io; 往Form1上添加控件picturebox,再添加imagelist,并设置imagelist的imagesize大小 Form1.cs代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Te

  • C#二维码图片识别代码

    本文实例为大家分享了C#二维码图片识别的具体代码,供大家参考,具体内容如下 怎么用NuGet和怎么配置log4net就不介绍了,直接上代码(Visual Studio 2015 下的项目,用的.NET Framework 4.5.2). 其中QRDecodeConsoleApp.exe.config文件里配置图片路劲(默认为D:\我的文档\Pictures\二维码).图片类型(默认为*.png). 也支持在命令行里执行,exe后接图片路劲参数. 需要直接用的朋友,确认完QRDecodeDemo\

  • C#生成验证码图片的方法

    本文实例为大家分享了C#生成验证码图片的具体代码,供大家参考,具体内容如下 /// <summary> /// 生成验证码图片 /// </summary> /// <returns></returns> public byte[] GetVerifyCode() { int codeW = 80; int codeH = 40; int fontSize = 18; string chkCode = string.Empty; //颜色列表,用于验证码.噪

  • c#生成自定义图片方法代码实例

    本篇文章给大家带来的内容是关于c# 如何生成自定义图片?c# 生成自定义图片方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. using System.Drawing;using System.IO;using System.Drawing.Imaging;using System;namespace treads { /// <summary> /// 生成略缩图 /// </summary> public class Class2 { private Ima

  • C#利用GDI+给图片添加文字(文字自适应矩形区域)

    前言 这篇文章是 GDI+ 总结系列的第二篇,如果对 GDI+ 的基础使用不熟悉的朋友可以先看第一篇文章<C# 使用 GDI+ 画图>. 需求 需求是要做一个编辑文字的页面.用户在网页端写文字,文字区域是个矩形框,用户可以通过下方的拖动条调节文字大小. 如下图: 提交数据的时候前端传文字区域的左上角和右下角定位给后台.因为前端的字体大小单位与后端没什么关系,所以不能直接传字体大小,也就是后端要根据矩形区域以及文字内容来自己推算用什么样的字体大小合适. 简单说就是知道文字的矩形区域,以及文字内容

  • 用Python给二维码图片添加提示文字

    一.需求: 判断当前浏览器是否为微信,是的话挑起微信支付,不是的话,显示二维码图片并提示用户到微信中打开 二.效果图: 三.代码实现: 1. 判断是否微信 # toolbox.py from typing import Any class UserAgent: def __init__(self, user_agent: str = '', request: Any = None): if request is not None: try: user_agent = request.header

  • 如何利用python给图片添加半透明水印

    前言 本文主要给大家介绍了关于python图片添加半透明水印的相关资料,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 示例代码: # coding:utf-8 from PIL import Image, ImageDraw, ImageFont def add_text_to_image(image, text): font = ImageFont.truetype('C:\Windows\Fonts\STXINGKA.TTF', 36) # 添加背景 new_img = I

  • 微信小程序利用Canvas绘制图片和竖排文字详解

    前言 闲暇时间抽个空写了个三国杀武将手册的小程序,中间有个需求设计的是合成武将皮肤图.竖排的武将姓名.以及小程序码,然后提供保存图片到相册,最终让用户可以分享到朋友圈或其他平台.合成图片应该按照 Canvas 的文档来做都没什么问题,主要是有个竖排文字的需求,这里和大家分享一下. 正文 首先放一张最终保存到相册的图片吧~ 自我感觉良好,至少达到了我自己的预期吧~~~ 下面让我们一步一步来看看如何实现的吧. 整个图片分为三个部分: 武将图片 小程序码 武将文字信息 先来看一下 wxml 里面的代码

  • 一个不错的给图片添加说明文字的动态层的实现代码

    滑动说明文字 .slide_bg{border:#999999 3px solid;width:207px;height:106px;position:relative;overflow:hidden;float:left;margin-right:16px;margin-top:26px;} .slide_img{background-image:url(/jscss/demoimg/wall1.jpg);width:207px;height:106px;} .slide_txt{width:

  • C#利用GDI绘制常见图形和文字

    废话不多说,我们先来认识一下这个GDI+,看看它到底长什么样. GDI+:Graphics Device Interface Plus也就是图形设备接口,提供了各种丰富的图形图像处理功能;在C#.NET中,使用GDI+处理二维(2D)的图形和图像,使用DirectX处理三维(3D)的图形图像,图形图像处理用到的主要命名空间是System . Drawing:提供了对GDI+基本图形功能的访问,主要有Graphics类.Bitmap类.从Brush类继承的类.Font类.Icon类.Image类.

  • C#利用GDI+绘制旋转文字等效果实例

    本文实例讲述了C#利用GDI+绘制旋转文字等效果的方法,是非常实用的技巧.分享给大家供大家参考之用.具体如下: C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经过不少的计算过程.利用下面的类可以实现该功能. 具体实现代码如下: using System; using System.Collections.Generic; using System

  • Java实现给图片添加图片水印,文字水印及马赛克的方法示例

    本文实例讲述了Java实现给图片添加图片水印,文字水印及马赛克的方法.分享给大家供大家参考,具体如下: 可以在eclipse中新建个Utils类,把以下代码复制进去直接使用,以下方法实现单个或多个水印的添加 package com.rzxt.fyx.common.util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import

  • 如何利用Java在图片上添加文字水印效果

    目录 前言 [1]获取原图片对象 (1.1)读取本地图片 (1.2)读取网络图片 [2]创建画笔 [3]添加文字水印 [4]获取处理图片 [5]源代码 总结 前言 今天分享一个:通过Java代码,给图片添加文字. 比如下面这个图片,我们在左下角就添加了一个文字版的水印,那么这是如何实现的呢 ? [1]获取原图片对象 首先,第一步,肯定是要让我们的程序,拿到需要处理的图片. 我们程序获取图片的方式,通常有两种,一种是通过下载到本地,从本地读取:另外一种就是通过网络地址进行获取. (1.1)读取本地

  • php面向对象与面向过程两种方法给图片添加文字水印

    目前绝大多数PHP程序员使用面向过程的方式,因为解析WEB页面本身就非常"过程化"(从一个标签到另一个标签).在HTML中嵌入过程处理代码是很直接自然的作法,所以PHP程序员通常使用这种方式. 如果你是刚接触PHP,用面向过程的风格来书写代码很可能是你唯一的选择.但是如果你经常上PHP论坛和新闻组的话,你应该会看到有关"对象"的文章.你也可能看到过如何书写面向对象的PHP代码的教程.或者你也可能下载过一些现成的类库,并尝试着去实例化其中的对象和使用类方法--尽管你可

随机推荐