C#利用GDI+給圖片添加文字(文字自適應(yīng)矩形區(qū)域)
前言
這篇文章是 GDI+ 總結(jié)系列的第二篇,如果對(duì) GDI+ 的基礎(chǔ)使用不熟悉的朋友可以先看第一篇文章《C# 使用 GDI+ 畫圖》。
需求
需求是要做一個(gè)編輯文字的頁(yè)面。用戶在網(wǎng)頁(yè)端寫文字,文字區(qū)域是個(gè)矩形框,用戶可以通過下方的拖動(dòng)條調(diào)節(jié)文字大小。
如下圖:
提交數(shù)據(jù)的時(shí)候前端傳文字區(qū)域的左上角和右下角定位給后臺(tái)。因?yàn)榍岸说淖煮w大小單位與后端沒什么關(guān)系,所以不能直接傳字體大小,也就是后端要根據(jù)矩形區(qū)域以及文字內(nèi)容來自己推算用什么樣的字體大小合適。
簡(jiǎn)單說就是知道文字的矩形區(qū)域,以及文字內(nèi)容,要讓文字內(nèi)容根據(jù)矩形區(qū)域大小調(diào)整到適合的字體大小能比較合適地填滿這個(gè)區(qū)域。
分析&思路
Graphics 類有個(gè) MeasureString 方法,可以用來計(jì)算以當(dāng)前字體寫出來的文字會(huì)占據(jù)多少像素。
如下:
// // 摘要: // 測(cè)量用指定的 System.Drawing.Font 繪制的指定字符串。 // // 參數(shù): // text: // 要測(cè)量的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // 返回結(jié)果: // 此方法返回 System.Drawing.SizeF 結(jié)構(gòu),該結(jié)構(gòu)表示 text 參數(shù)指定的、使用 font 參數(shù)繪制的字符串的大小,單位由 System.Drawing.Graphics.PageUnit // 屬性指定。 // // 異常: // T:System.ArgumentException: // font 為 null。 public SizeF MeasureString(string text, Font font);
這個(gè)方法返回的 SizeF 包含 Width 和 Height 屬性,讀取這兩個(gè)屬性可以獲取到文字內(nèi)容所占的寬高(以像素為單位)。
//
// 摘要:
// 獲取或設(shè)置此 System.Drawing.SizeF 結(jié)構(gòu)的水平分量。
//
// 返回結(jié)果:
// 此 System.Drawing.SizeF 結(jié)構(gòu)的水平分量,通常以像素為單位進(jìn)行度量。
public float Width { get; set; }
// 摘要:
// 獲取或設(shè)置此 System.Drawing.SizeF 結(jié)構(gòu)的垂直分量。
//
// 返回結(jié)果:
// 此 System.Drawing.SizeF 結(jié)構(gòu)的垂直分量,通常以像素為單位進(jìn)行度量。
public float Height { get; set; }
于是我們可以先根據(jù)前端傳過來的文字左上角與右下角定位,算出文字的矩形區(qū)域,然后估計(jì)一個(gè)字體大小,再用 MeasureString 方法計(jì)算出估算的文字所占區(qū)域,比較和實(shí)際的文字區(qū)域大小,大了則縮小字體,小了則增大字體。這樣即可大約找出合適的文字大小。
具體實(shí)現(xiàn)
添加文字方法
/// <summary>
/// 圖片添加文字,文字大小自適應(yīng)
/// </summary>
/// <param name="imgPath">圖片路徑</param>
/// <param name="locationLeftTop">左上角定位(x1,y1)</param>
/// <param name="locationRightBottom">右下角定位(x2,y2)</param>
/// <param name="text">文字內(nèi)容</param>
/// <param name="fontName">字體名稱</param>
/// <returns>添加文字后的Bitmap對(duì)象</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);
// 計(jì)算文字區(qū)域
// 左上角
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]);
// 區(qū)域?qū)捀?
float fontWidth = x2 - x1;
float fontHeight = y2 - y1;
float fontSize = fontHeight; // 初次估計(jì)先用文字區(qū)域高度作為文字字體大小,后面再做調(diào)整,單位為px
Font font = new Font(fontName, fontSize, GraphicsUnit.Pixel);
SizeF sf = graph.MeasureString(text, font);
int times = 0;
// 調(diào)整字體大小以適應(yīng)文字區(qū)域
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("一開始估計(jì)大了,最終字體大小為{0},循環(huán)了{(lán)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("一開始估計(jì)小了,最終字體大小為{0},循環(huán)了{(lán)1}次", font.ToString(), times);
}
// 最終的得出的字體所占區(qū)域一般不會(huì)剛好等于實(shí)際區(qū)域
// 所以根據(jù)兩個(gè)區(qū)域的相差之處再把文字開始位置(左上角定位)稍微調(diào)整一下
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;
}
測(cè)試調(diào)用
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("出錯(cuò)了??!\n" + ex.ToString());
}
finally
{
System.Console.WriteLine("\nPress any key to continue ...");
System.Console.ReadKey();
}
}
最終效果:
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)我們的支持。
上一篇:C# winForm實(shí)現(xiàn)的氣泡提示窗口功能示例
欄 目:C#教程
本文標(biāo)題:C#利用GDI+給圖片添加文字(文字自適應(yīng)矩形區(qū)域)
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/5216.html
您可能感興趣的文章
- 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
- 01-10C#獲取動(dòng)態(tài)生成的CheckBox值
- 01-10C#圖片處理3種高級(jí)應(yīng)用
- 01-10C#連接數(shù)據(jù)庫(kù)的方法
- 01-10C#給圖片添加水印完整實(shí)例
- 01-10C#異步下載文件
- 01-10C# Console利用mspaint打開圖像并保存的方法
- 01-10C#利用delegate實(shí)現(xiàn)Javascript的each方法
- 01-10C#實(shí)現(xiàn)給圖片加水印的方法
- 01-10C#怎么給PDF添加背景圖片


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子


