标题：字符画
关键技术
第一个关键技术：汉字库读取技术使用汉字库技术可以做到和操作系统无关性，先了解一下点阵
  字符画字库的基本原理。如下所示，下面是一个“字”的点阵图，在16点阵字库中一个汉字为16x16点，每一行使用两个字节表示，如下面示例第一行的十六进制为：0x02和0x00，所以，一个汉字在16点阵字库中需要占用2x16个字节，24点阵字库需要3x24个字节，下面仅以16点阵字库为例，其他点阵类似。 ██████　█████████
███████　████████
██　██
██　██████████　██
█　██████████　███
███　█████
█████████　██████
████████　███████
███████　█████　██
█
███████　████████
███████　████████
███████　████████
███████　████████
█████　█　████████
██████　█████████
下面的函数返回指定字符串的字符画文本
functionGet16(constAWord,AForeground,ABackground:string):string;
functionGetBit(constc,n:byte):integer;
begin
result:=(cshrn)and1;
end;
var
iLen:integer;
iFileSize:integer;
s:string; 
  字符画k,l,i,p:integer;
cw:array[0..31]ofchar;
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
forl:=1toiLendiv2do
begin
k:=l*2-1;
//如果不是汉字，往前进一位
whilekiLenthenbreak;
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>iFileSizethencontinue;
try
seek(File16,(94*qu_ma+wei_ma)*32);
except
myMessageBox(fseekcallfail!);
exit;
end;  字符画BlockRead(File16,cw,32); fori:=0to15do
begin
forp:=7downto0do
begin
ifGetBit(ord(cw[i*2]),p)=1thens:=s+AForeground
elses:=s+ABackground;
end;
forp:=7downto0do
begin
ifGetBit(ord(cw[i*2+1]),p)=1thens:=s+AForeground
elses:=s+ABackground;
end;
s:=s+#13#10;
end;
end;
end;
finally
CloseFile(File16);
end;
result:=s;
end;第二个关键技术：使用系统字库进行转换其实使用系统字库是极为自由的方式，因为这样完全不必关心字库的技术，这一切都交给系统好了，充分利用系统资源。
如果定义一个设备，然后设定好设备的各种属性，包括宽度、高度、字体、颜色等，然后在上面绘制文本就可以了，要转换为字符画，只需要把设备上的点阵信息转换为文本即可。配合CreateFontIndirect函数，使用DrawText可以绘制丰富的文本效果。实现完整的字符画效果 下面是十二号宋体的转换结果： 
  字符画█████　██████
█　█
████████　█
██　███
██████　█████
█████　██████
█
█████　██████
█████　██████
█████　██████
███　██████
████████████ 下面是九号@黑体的转换结果：
████████████
██　███　████
██　████　████
██　█　██　████
██　█　█　████
█　█　█
█　██　██　█
██　█　██　██　█
██　█　██　████
██　████　████
██　███　████
████████████第三个关键技术：图片转换为文本要把图像转换为文本，这其中有一个很大的困难，就是文本没有颜色，所以特别引进了一个概念：文本灰度，就是把不同字母在屏幕上显示的大小排序，得到一张灰度表，用这个灰度表来转换图片，可以达到比较好的效果。
下面的函数可以把一个位图转换成文本，ABit是位图，AGray是灰度
functionImageToText(ABit:TBitmap;constAGray: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);
fory:=0toABit.Height-1do
begin
forx:=0toABit.Width-1do
begin
pColor:=ABit.Canvas.Pixels[x,y];
R:=pColorand$FF;
G:=(pColorshr8)and$FF;
B:=(pColorshr16)and$FF; iGray:=HiByte(R*77+G*151+B*28);
iIndex:=(iGray*iGrayLendiv255);
ifiIndexiGrayLentheniIndex:=iGrayLen;
s:=s+sGrayPer[iIndex];
end;
s:=s+Crlf;
end;
result:=s;
end;
这是一个常用且效果比较好的灰度：“MNHQ$OC?7>!:-;.”第四个关键技术：把文本转换为图像要把文本转换为图片，必须获取两个重要参数：转换后的宽  字符画和高，要取得这两个参数，我们可以使用GetTextExtentPoint32函数，该函数的定义如下：
functionGetTextExtentPoint32(DC:HDC;Str:PChar;Count:Integer;varSize:TSize):BOOL;
DC传入设备句柄
Str为文本内容
Count为文本的长度(字节)
Size返回宽和高
在实际应用中，往往被转换的文本有多行，且每一行的长度不定，
所以我们还需要在生成图像前进行一遍预扫，以便获得完整的图像大小 下面演示了文本转换为图像的代码
////////////////////////////////////////////////////////////////////////////////
//功能:把文本转换为位图
//AOwner:窗体参数
//AText:要转换的文本
//AFont:文本的字体
//ABitmap:转换后的位图对象
//日期:2003.12.15
////////////////////////////////////////////////////////////////////////////////
procedureTextToBitmap(AOwner:TObject;constAText: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);
//下面代码用户获得文本的最大宽度和高度
fori:=0toAText.Count-1do
begin
s:=AText.Strings[i];
ifs=thens:=;
lblTemp.Caption:=s;
GetTextExtentPoint32(lblTemp.Canvas.Handle,pchar(lblTemp.Caption),lblTemp.GetTextLen,size);
ifiWidth<size. cxtheniWidth:=Size. cx;
iHeight:=iHeight+Size. cy;
end;
//获得一个字符的高度
GetTextExtentPoint32(lblTemp.Canvas.Handle,pchar(),length(),size);
iCharHeight:=size. cy;
ABitmap.Width:=iWidth;
ABitmap.Height:=iHeight;
fori:=0toAText.Count-1do
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;
转换成字符画
图片转换成字符画，一幅SHE的字符画，由密密麻麻的字符组成，粉丝们真是疯狂得可以，一个字母一个字母地拼，不怕被整崩溃啊没想到，原来有一种专门将图片转换为字符的程序。 下面要介绍的就是一个专门的图片转换网站。找一张合适的图片，点击“浏览”，然后点Submit，这样就得到字符画了。如果想保存下来，接下来为这张图取一个名字（不支持中文），然后点Submit，进入另一个页面后点DownloadNow，你会得到一个txt格式的文件，刚才的字符画就保存其中了。另外，此页面还可以调整字符画的明暗并选择不同的字符（字符画上方）。点GotoMyPage，就会得到一个专门保存刚才字符画的页面。
字符画软件
小燕子字符画
软件大小：810KB
软件语言：简体中文
软件类别：国产软件/免费软件/文字处理
应用平台：Win9x/NT/2000/XP/2003
根据需要生成各种字符画，另外本软件最大的特点是可以在没有汉字支持的平台使用汉字，自动支持十六点阵汉字库，并且可以显示本机所有的汉字库，可以用来检测本机某一种字库是否包含所有标准汉字；也可以用来书写密文，比如用两个比较相似的字符生成一个字符画，在平常的字体下，人眼不能分辨具体的内容，如果要看时，只需将文字的字体变小即可；当然了，最大的功能是可以用她来写情书，哈哈！用特别的形式表达你特别的用心。程序特别增加了“转换图片”功能和“字符画创作工具”，使《小燕子字符画》更加实用。
搜狗拼音输入法，绚丽的表情，丰富的字符画，便利的英文输入法，搜狗拼音3.6有多个功能，其中包括字符画。搜狗3.6版的首词命中率、候选率比3.5版有所提高！CPU占用率指标有所降低！主要包括：
包括丰富的表情和字符画在内的快捷输入，如输入huhu，提供(～o～)~zZ；输入xin，提供❤；输入qingwa，提供
@..@
(\--/)
(.>__<.)
^^^^^^还有更多：♠♥♦♣☀☻☎♩♪♫♬……随你选择！
bug修正：修正了模糊音设置同步问题后恢复默认的bug。
【工具】Image2Html – 将图片转化为彩色字符画
网络特有浪漫
字符画，网络特有的浪漫。聊了一晚上都是一屏屏的文字也是一种乏味。隔着看不见的网络，全靠文字来表达一切似乎缺少了点什么。所以网虫们发明了用键盘上的符号来表情的方法，比如用“:-D”来表示高兴，一方面这个符号比打出具体的文字方便，而另一方面似乎也比纯粹的文字更直观一些。
有人说这个符号就像笑脸，说老实话，怎么看都有点牵强。不过如果你真觉得纯粹的文字不够有趣，这类简单的符号又不够形象的话，那么你还可以试试字符画在QQ中又被称为QQ图标，用字符的形式来构成一些有趣的图案，来表情达意，这是网虫们想到的绝妙点子。一个由字符组成的心形，或者一只用字符构成的史努比图案，让网友在纯粹的文字之外体会到一种网络特有的浪漫。又或者你想对网友的生日表达你的祝福，你是打一句“生日快乐”好呢，还是送出一份用字符构成的生日蛋糕更让对方开心呢？
答案是显而易见的。不过要玩转字符画，光是用QQ这个软件是不行的，在聊天的时候你也没时间设计一幅有趣的字符画出来。所以有人就开发了一个小程序为你提供丰富的字符画，你只要选中你喜欢的，双击一下就能自动地加到你的聊天输入框中，甚至自动发送。用法和上面提到的“表情”软件差不多。而这个软件就是QQ图形留言器。强烈建议你试用一下啦。不一样的特别的文字，不一般的特别的问候，自然是发送给那个特别的人啦。