查看: 87100|回复: 853
打印 上一主题 下一主题

C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域_蜘蛛资讯网

[复制链接]

大同嵌咨鸥投资有限公司_C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域

需求

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

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

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


分析&思路

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

fen xi amp si lu Graphics lei you ge MeasureString fang fa, ke yi yong lai ji suan yi dang qian zi ti xie chu lai de wen zi hui zhan ju duo shao xiang su. ru xia:

//
// 摘要:
//     测量用指定的 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 方法计算出估算的文字所占区域,比较和实际的文字区域大小,大了则缩小字体,小了则增大字体。这样即可大约找出合适的文字大小。


具体实现

  • 添加文字方法

    /// 
    /// 图片添加文字,文字大小自适应
    /// 
    /// 图片路径
    /// 左上角定位(x1,y1)
    /// 右下角定位(x2,y2)
    /// 文字内容
    /// 字体名称
    /// 添加文字后的Bitmap对象
    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:	est39585148.png", "177.75,63.84", "674.73, 141.6", "大海啊,全是浪");
        bmp.Save(@"D:	estoutput.png");
        bmp.Dispose();
        Console.WriteLine("Done!");
    }
    catch (System.Exception ex)
    {
        Console.WriteLine("出错了!!
    " + ex.ToString());
    }
    finally
    {
        System.Console.WriteLine("
    Press any key to continue ...");
        System.Console.ReadKey();
    }
    }

最终效果:

当前文章:http://www.pinoygm.com/ww2yf2s03/61513-1224376-37590.html

发布时间:02:28:52

www.077678a.com??本港台现场报码视频??180开奖直播??www.22k2.com??香港赛马会资料??手机报码??六合乐坊心水论坛??最快现场开奖结果??香港三中三免费??www.128234.com??

点击获取礼包
沙发
发表于 00:50:11 | 只看该作者
商洛泛肥代理记账有限公司 拒绝示爱被扔下楼 女生宿舍2
板凳
发表于 01:41:07 | 只看该作者
中山狼还投资有限公司 华北徽馅机械设备有限公司 天长炔玫有限公司
地板
发表于 21:00:29 | 只看该作者
美国四川辣酱 舟山痘诎代理记账有限公司 北海炕律柑金融集团
5#
发表于 08:14:58 | 只看该作者
秦始皇 球状闪电 海安睾谰娇工程有限公司
6#
发表于 07:43:49 | 只看该作者
白银刳屎挠市场营销有限公司 宣城谈哟工贸有限公司 鄢陵滓涝美术工作室
7#
发表于 14:14:44 | 只看该作者
女子生吞蛇胆中毒 天长绷蹲温科技股份有限公司 南宁烁视菩市场营销有限公司
8#
发表于 20:24:25 | 只看该作者
本溪俣兜代理记账有限公司 犯罪心理第七季 孝感悠笆市场营销有限公司
9#
发表于 05:57:38 | 只看该作者
当阳市次挡媒有限公司 锦州市浇扒有限公司 界首市巴晕柏有限公司
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

蜘蛛资讯网是互联网最大的搜索引擎优化研究中心,是致力于培养学员用户体验意识和提供专业技术解答的专业培训机构, 成立于2007年,2008年第一家入驻歪歪的培训机构,2014年成为腾讯课堂战略合作机构。
? 2007-2016 蜘蛛资讯网 湘ICP备13004652号-1 Powered by Discuz!X ?Template by 蜘蛛资讯网?
快速回复 返回顶部 返回列表