转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
字符画软件的四个关键技术         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1741 更新时间:2009/4/23 18:36:40

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

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

  使用汉字库技术可以做到和操作系统无关性,我们先了解一下点阵字库的基本原理
如下所示,下面是一个“字”的点阵图,在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>!":-'

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台