分享
 
 
 

字符画软件的四个关键技术

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

字符画软件的四个关键技术

第一个关键技术:汉字库读取技术

使用汉字库技术可以做到和操作系统无关性,我们先了解一下点阵字库的基本原理

如下所示,下面是一个“字”的点阵图,在16点阵字库中一个汉字为16x16点,每一行使用两个字节表示,如下面示例第一行的十六进制为:0x02和0x00,所以,一个汉字在16点阵字库中需要占用2x16个字节,24点阵字库需要3x24个字节,下面我们仅以16点阵字库为例,其他点阵类似。

███████████████

███████████████

████

██████████████

██████████████

████████

███████████████

███████████████

██████████████

███████████████

███████████████

███████████████

███████████████

██████████████

███████████████

下面的函数返回指定字符串的字符画文本

function Get16(const AWord,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)=mbLeadByte 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 : 转换后的位图对象

// 日期 : 2003.12.15

////////////////////////////////////////////////////////////////////////////////

procedure TextToBitmap(AOwner:TObject;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<size.cx then iWidth:=Size.cx;

iHeight:=iHeight+Size.cy;

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

凌丽软件工作室

http://wosens.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有