字元畫軟體的四個關鍵技術 (轉)
字元畫的四個關鍵技術
第一個關鍵技術:漢字型檔讀取技術
使用漢字型檔技術可以做到和操作無關性,我們先了解一下點陣字型檔的基本原理
如下所示,下面是一個“字”的點陣圖,在16點陣字型檔中一個漢字為16x16點,每一行使用兩個位元組表示,如下面示例第一行的十六進位制為:0x02和0x00,所以,一個漢字在16點陣字型檔中需要佔用2x16個位元組,24點陣字型檔需要3x24個位元組,下面我們僅以16點陣字型檔為例,其他點陣類似。
██████ █████████
███████ ████████
██ ██
██ ██████████ ██
█ ██████████ ███
███ █████
█████████ ██████
████████ ███████
███████ █████ ██
█
███████ ████████
███████ ████████
███████ ████████
███████ ████████
█████ █ ████████
██████ █████████
下面的返回指定字串的字元畫文字
function Get16(const A,AForeground,ABackground:string):string;
function GetBit(const c,n:byte):integer;
begin
result:=(c shr n) and 1;
end;
var
iLen :integer;
iFileSize :integer;
s :string;
k,l,i,p :integer;
cw:array[0..31] of char;
qu_ma,wei_ma:integer;
File16 :file;
begin
iLen:=length(AWord);
AssignFile(File16,piProgramInfo.Path+'HZK16');
FileMode := fmOpenRead;
try
Reset(File16,1);
finally
FileMode:=fmOpenReadWrite;
end;
iFileSize:=FileSize(File16);
try
for l:=1 to iLen div 2 do
begin
k:=l*2-1;
// 如果不是漢字,往前進一位
while k<=iLen do
begin
if ByteType(AWord,k)=mbLeayte then break;
inc(k);
end;
if k>iLen then break;
if ((ord(AWord[k]) and $80)<>0) then
begin
qu_ma:=ord(AWord[k])-161;
wei_ma:=ord(AWord[k+1])-161;
if (94*qu_ma+wei_ma)*32+32>iFileSize then continue;
try
seek(File16,(94*qu_ma+wei_ma)*32);
except
myMessageBox('fseek call fail!');
exit;
end;
BlockRead(File16,cw,32);
for i:=0 to 15 do
begin
for p:=7 downto 0 do
begin
if GetBit(ord(cw[i*2]),p)=1 then s:=s+AForeground
else s:=s+ABackground;
end;
for p:=7 downto 0 do
begin
if GetBit(ord(cw[i*2+1]),p)=1 then s:=s+AForeground
else s:=s+ABackground;
end;
s:=s+#13#10;
end;
end;
end;
finally
CloseFile(File16);
end;
result:=s;
end;
第二個關鍵技術:使用系統字型檔進行轉換
其實使用系統字型檔是極為自由的方式,因為這樣我們完全不必關心字型檔的技術,這一切都交給系統好了,讓我們充分利用系統資源。
如果我們定義一個裝置,然後設定好裝置的各種屬性,包括寬度、高度、字型、顏色等,然後在上面繪製文字就可以了,要轉換為字元畫,只需要把裝置上的點陣資訊轉換為文字即可。
配合 CreateFontIndirect 函式,使用 DrawText 可以繪製豐富的文字效果。實現完整的字元畫效果
下面是十二號宋體的轉換結果
█████ ██████
█ █
████████ █
██ ███
██████ █████
█████ ██████
█
█████ ██████
█████ ██████
█████ ██████
███ ██████
████████████
下面是九號@黑體的轉換結果
████████████
██ ███ ████
██ ████ ████
██ █ ██ ████
██ █ █ ████
█ █ █
█ ██ ██ █
██ █ ██ ██ █
██ █ ██ ████
██ ████ ████
██ ███ ████
████████████
第三個關鍵技術:圖片轉換為文字
要把影像轉換為文字,這其中有一個很大的困難,就是文字沒有顏色,所以我們特別引進了一個概念:文字灰度,就是把不同字母在螢幕上顯示的大小排序,得到一張灰度表,用這個灰度表來轉換圖片,可以達到比較好的效果。
下面的函式可以把一個點陣圖轉換成文字,ABit 是點陣圖,AGray 是灰度
function ImageToText(ABit:TBitmap;const AGray:string):string;
var
x,y :integer;
s :string;
pColor :Longint;
R,G,B :byte;
iGray :integer;
sGrayPer :string;
iGrayLen :integer;
iIndex :integer;
begin
s:='';
sGrayPer:=AGray;
iGrayLen:=Length(sGrayPer);
for y:=0 to ABit.Height-1 do
begin
for x:=0 to ABit.Width-1 do
begin
pColor:=ABit.Canvas.Pixels[x,y];
R:=pColor and $FF;
G:=(pColor shr 8) and $FF;
B:=(pColor shr 16) and $FF;
iGray:=HiByte(R*77+G*151+B*28);
iIndex:=(iGray*iGrayLen div 255);
if iIndex<1 then iIndex:=1;
if iIndex>iGrayLen then iIndex:=iGrayLen;
s:=s+sGrayPer[iIndex];
end;
s:=s+Crlf;
end;
result:=s;
end;
這是一個常用且效果比較好的灰度:“MNHQ$OC?7>!":-';. ”
第四個關鍵技術:把文字轉換為影像
要把文字轉換為圖片,必須獲取兩個重要引數:轉換後的寬和高,要取得這兩個引數,我們可以使用 GetTextExtentPoint32 函式,該函式的定義如下:
function GetTextExtentPoint32(DC: HDC; Str: PChar; Count: Integer; var Size: TSize): BOOL;
DC 傳入裝置控制程式碼
Str 為文字內容
Count 為文字的長度(位元組)
Size 返回寬和高
在實際應用中,往往被轉換的文字有多行,且每一行的長度不定,
所以我們還需要在生成影像前進行一遍預掃,以便獲得完整的影像大小
下面演示了文字轉換為影像的程式碼
////////////////////////////////////////////////////////////////////////////////
// 功能 : 把文字轉換為點陣圖
// AOwner : 窗體引數
// AText : 要轉換的文字
// AFont : 文字的字型
// ABitmap : 轉換後的點陣圖
// 日期 : .12.15
////////////////////////////////////////////////////////////////////////////////
procedure TextToBitmap(AOwner:T;const AText:TStrings;AFont:TFont;ABitmap:TBitmap);
var
i :integer;
iWidth,iHeight :integer;
iCharHeight :integer;
s :string;
r :TRect;
size :TSize;
lblTemp :TLabel;
begin
iWidth:=0;
iHeight:=0;
lblTemp:=TLabel.Create(nil);
r.Top:=0;
try
lblTemp.Visible:=false;
lblTemp.Parent:=TWinControl(AOwner);
lblTemp.Font.Assign(AFont);
ABitmap.Canvas.Brush.Style:=bsClear;
ABitmap.Canvas.Pen.Color:=rgb(0,0,0);
ABitmap.Canvas.Brush.Color:=RGB(255,255,255);
ABitmap.Canvas.Font.Assign(AFont);
// 下面程式碼獲得文字的最大寬度和高度
for i:=0 to AText.Count-1 do
begin
s:=AText.Strings[i];
if s='' then s:=' ';
lblTemp.Caption:=s;
GetTextExtentPoint32(lblTemp.Canvas.Handle,pchar(lblTemp.Caption),lblTemp.GetTextLen,size);
if iWidth
end;
// 獲得一個字元的高度
GetTextExtentPoint32(lblTemp.Canvas.Handle,pchar(' '),length(' '),size);
iCharHeight:=size.cy;
ABitmap.Width:=iWidth;
ABitmap.Height:=iHeight;
for i:=0 to AText.Count-1 do
begin
s:=AText.Strings[i];
r.Left:=0;
r.Right:=ABitmap.Width;
r.Bottom:=r.Bottom+iCharHeight;
DrawText(ABitmap.Canvas.Handle,PChar(s),length(s),r,0);
r.Top:=r.Top+iCharHeight;
end;
finally
lblTemp.Free;
end;
end;
2003.12.15
凌麗軟體工作室
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-963395/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 建立快速響應軟體開發的四個關鍵 - Andy Hunt
- 技術管理的6個關鍵原則
- js視訊轉字元畫 —— 寫一個屬於自己的字元轉換器JS字元
- Java呼叫鏈跟蹤關鍵技術(四)SQL監控JavaSQL
- 醫院PACS系統虛擬內窺鏡(VE)實現的四個關鍵技術
- 域控軟體安全隔離關鍵技術剖析:MCU域 VS SOC域
- 現代資料架構的7個關鍵技術架構
- 25個關鍵技術點,帶你熟悉PythonPython
- 字元作畫,我用字元畫個冰墩墩字元
- 實現VR直播的關鍵技術VR
- 程式設計師轉AI工程師很難嗎?這6個技術是關鍵程式設計師AI工程師
- 技術沙龍|京東雲端到端多媒體關鍵技術揭秘
- 零信任安全的四個關鍵原則
- 5個關鍵詞回顧2022年個推技術實踐
- 人工智慧的關鍵技術有哪些人工智慧
- 圖片轉繪畫效和繪畫軟體
- 中國電信:軟體定義攝像機關鍵技術白皮書(附下載)
- 【北京/上海/廣州/重慶四地巡講】以軟體為核心的新架構下汽車電子關鍵技術研討會架構
- 聚焦LS-MIMO的四大層面,淺談5G關鍵技術
- 01-Python 圖片轉字元畫Python字元
- Java多執行緒乾貨系列—(四)volatile關鍵字| 掘金技術徵文Java執行緒
- 資料治理:資料整合的關鍵技術
- 改進DevSecOps框架的 5 大關鍵技術dev框架
- 技術分享:Linux多核並行程式設計關鍵技術Linux並行行程程式設計
- 特殊字元關鍵字篩選字元
- 語音技術——關鍵詞搜尋
- Qtum量子鏈關鍵技術解讀QT
- 2個最重要的非技術性的軟體開發技能
- 代理IP助力企業發展的四個關鍵
- 玩轉雲端 | 天翼雲物件儲存ZOS高可用的關鍵技術揭秘物件
- 面向OpenHarmony終端的密碼安全關鍵技術密碼
- 開發美顏SDK的關鍵技術有哪些?
- 都知道RFID技術,可你瞭解RFID的關鍵技術是哪些嗎?
- 軟體開發丨關於軟體重構的靈魂四問
- ChatGPT軟體技術棧解密ChatGPT解密
- 服裝erp軟體實施的關鍵因素
- 中國軟體企業的關鍵癥結
- 服務機器人關鍵技術(一)機器人
- BOSHIDA DC/AC電源模組:實現無縫電力轉換的關鍵技術