2012-08-22 32 views
1

在我的程序中,我需要生成一個位圖,其中包含從左到右放置的所有數字字符(0..9)以及其他幾個字符。如何在Windows窗體中使用精確的字符高度創建字體?

用戶將來自UI選擇:

  1. 所需的字體,並且以像素爲單位
  2. 所需的字符的高度。

所以我想創建一個位圖,然後從這個位圖中的圖形,然後將數字逐個繪製到這個位圖,然後將其保存到磁盤。

我在幾小時內無法弄清的: 如何創建一個正確大小的字體,以便數字「0」具有用戶給出的高度?我試着創建與本機CreateFont()通過P/Invoke(與正面/負面nHeight)的字體與String構造函數的所有參數,具有StringFormat屬性,與MeasureString/MeasureText/MeasureCharacterRanges。所有稱爲「大小」或「高度」的參數似乎都指示比「0」大得多的假想字符的大小。

我看過本着高度,EM高度,上升,下降等理論似乎有成爲該真正高度的字符沒有概念,沒有邊距和間距等

我再次問題:給定'0'字形的字體名稱和所需的像素高度,如何創建一個字體來繪製具有所需高度的字形?

我將不勝感激任何指導。

後編輯 關於我的項目的一些更多細節:這是一個帶有大顯示屏的嵌入式設備,我需要爲設計人員提供一種簡單方法來生成並嘗試他們喜歡的位圖字體。生成這種位圖字體的Windows工具對我來說似乎是一個很好的解決方案。

+0

基於GDI +的文本測量有點奇怪。研究普通的GDI API。關於垂直居中文本的其他一些問題可能會有所幫助。 – CodesInChaos

+1

系統字體系統將始終爲異常高或低字符保留空間。爲什麼不嘗試一個「測試和解決」循環?打印字符零,並以編程方式以像素爲單位測量其高度 - 例如檢查以確保水平至少有十行像素至少有一個位集。如果失敗,請將字體大小加1,然後重試直到成功。因爲會有一些重疊,所以不幸的是必須剪掉未使用的像素行。 –

+0

是的,我想到了這樣的事情,但我想保留這個作爲最後的解決方案。我正在尋找愚蠢的Paint程序,該程序以某種方式設法完成我所需要的操作(我告訴它「Arial 10」,它將文本繪製爲10像素高),我希望有一個清晰的程序化方法來實現這一點... – adigostin

回答

0

我相信你可以用這個Font Constructor來指定GraphicsUnit爲像素。然後它應該創建適當大小的字體。

添加測試代碼 - 根據您的情況進行相應的編輯,不要判斷風格,我只是想要一些可以粘貼到LINQPad中的東西並生成圖像。

using (var font = new Font("Arial",10,FontStyle.Regular, GraphicsUnit.Pixel)) 
using (var image = new Bitmap(30, 15)) 
using (var graphics = Graphics.FromImage(image)) 
{ 
    graphics.FillRectangle(Brushes.White, new Rectangle(0, 0, 30, 15)); 
    graphics.DrawString("Ay", font, Brushes.Black, 0, 0); 
    image.Save(@"E:\test.bmp", ImageFormat.Bmp); 
} 

由在字體的所有字符需要適合在這個範圍內,這意味着用伸和字母與字母伸像素設置的大小時,請記住。

+0

這是我嘗試的第一件事情之一。 我剛剛再次測試它:從Arial 10我得到一個'0',這是7像素高。 – adigostin

+0

這確實按預期工作。你只是嘗試了一個A,做一個'A'和一個'Y',你會發現這條線的總高度是10. – pstrjds

+0

謝謝你的示例,但這不是我所需要的。我需要的是在最初的問題。我會用另一種方式寫下來:如何計算傳遞給Font()構造函數的大小,以使給定字體的字形「0」(不是字符串「Ay」)具有給定的高度? 關於我的項目的更多細節:這是一個帶有大顯示屏的嵌入式設備,我需要爲設計人員提供一個簡單的方法來生成並嘗試他們喜歡的位圖字體。生成這種位圖的Windows工具對我來說似乎是一個很好的解決方案。 – adigostin

1

雖然我與之前發佈的內容並不遙遠,但實際上並不奏效。在我的頭上反對這個,我發現有趣的是,graphics.MeasureString(「M」,...)報告的高度遠遠大於graphics.MeasureString(「MM」,...)。在手動計算字體大小時,我發現第一個(與GetEMSize的響應相關)實際上是整行大小。最後,我意識到數字的實際字符大小不需要與任何度量關聯,無論是實數還是.net。