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 包含 WidthHeight 属性,读取这两个属性可以获取到文字内容所占的宽高(以像素为单位)。

//
// 摘要:
//     获取或设置此 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();
    }
    }

最终效果:

原文地址:https://www.cnblogs.com/dandelion-drq/p/csharp_use_gdiplus_to_add_text.html

时间: 2024-08-09 06:31:13

C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域的相关文章

如何给gif图片添加文字?GIF图片添加文字教程

我们经常会在网上下载一下GIF动态图片,有时候我们想给我们下载的GIF动态图片添加文字,这时候该怎么操作,下面小编就来分享一下给GIF图片添加文字的教程给大家,供大家参考和学习,希望大家都是能够满意的. GIF格式可以存多幅彩色图像,如果把存于一个文件中的多幅图像数据逐幅读出并显示到屏幕上,就可构成一种最简单的动画. 迅捷GIF制作工具添加文字就是将我们添加进来GIF图片逐帧分解成若干张图片,然后我们批量的在这些图片上添加文字. 迅捷GIF制作工具http://www.xunjieshipin.

php 图片添加文字水印 以及 图片合成(微信快码传播)

1.图片添加文字水印: $bigImgPath = 'backgroud.png'; $img = imagecreatefromstring(file_get_contents($bigImgPath)); $font = 'msyhl.ttc';//字体 $black = imagecolorallocate($img, 0, 0, 0);//字体颜色 RGB $fontSize = 20; //字体大小 $circleSize = 60; //旋转角度 $left = 50; //左边距

php给图片添加文字水印方法汇总

在php中要给图片加水印我们需要给php安装GD库了,这里我们不介绍GD库安装,只介绍怎么利用php给图片添加文字水印的4种方法的汇总.有需要的小伙伴可以参考下. 1: 面向过程的编写方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 //指定图片路径 $src = '001.png'; //获取图片信息 $info = getimagesize($src); //获取图片扩展名 $type = image_type_to_ex

php图片添加文字水印方法汇总

方法一: <?php header("content-type:text/html;charset=utf-8"); //指定图片路径 $src = "img/a.png"; //获取图片信息 $info = getimagesize($src); //获取图片扩展名 $type = image_type_to_extension($info[2],false); // echo $type; // exit; //动态的把图片导入内存中 $fun = &qu

php给图片添加文字水印

PHP对图片的操作用到GD库,这里我们介绍如何给图片添加文字水印. 大致分为四步: 1.打开图片 2.操作图片 3.输出图片 4.销毁图片 下面我们上代码来具体讲解每步的实现过程: <?php /*打开图片*/ //1.配置图片路径 $src = "bg.jpg"; //2.获取图片信息 $info = getimagesize($src); //3.通过编号获取图像类型 $type = image_type_to_extension($info[2],false); //4.在

1viewer大图查看时如何给图片添加文字说明1

vue中图片预览缩略图,在点击缩略图时弹出大图,想在查看大图的时候,在图片上显示一段文字,用来图片说明,放在图片的左下角,如何显示?用data-content没有效果.应该用什么?<div v-viewer="options" class="images"><template v-for="item in imageList"><img :src="item.thumbnailPath" clas

如何使用CSS给图片添加双边框效果

如何使用CSS给图片添加双边框效果:建议:尽可能的手写代码,可以有效的提高学习效率和深度.给图片添加双边框也在实际使用中也有许多应用,可能并不频繁,在这里简单介绍一下如何实现此种效果,借以对CSS一些属性的应用加以熟练.先看一段代码实例: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="

使用CSS为图片添加边框的几种方法

css的应用十分广泛,即便用在图片的效果中也是方法多样,本文下面就介绍五种为图片添加特殊效果边框的CSS写法阴影效果 通过使用带有一些padding之的背景图来添加阴影效果. HTML <img class=”shadow” src=”sample.jpg” alt=”" /> CSS img.shadow { background: url(shadow-1000×1000.gif) no-repeat right bottom; padding: 5px 10px 10px 5p

Windows操作 - Photoshop为图片添加透明立体水印

原文地址:http://design.yesky.com/photoshop/252/2427752.shtml 本文我们介绍用Photoshop为图片添加透明立体水印的方法和技巧. 原图: 打开原图新建立一个图层,并且输入文字,如图所示: 设置图层样式: 设置填充: 拼合图层: