问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何利用windows自带的矢量字库提取字模

发布网友 发布时间:2022-04-20 04:32

我来回答

1个回答

热心网友 时间:2023-08-31 03:51

1  字体设置

  首先需要设置字体。Win32 SDK提供了用于字体选择的通用对话框,只需调用ChooseFont函数,其返回值为一个布尔值。具体定义为BOOL ChooseFont(LPCHOOSEFONT lpcf)。调用此函数后,弹出字体选择对话框,在此可以选择所需要的字体、字形、大小等参数。选择完毕后,如果点击了字体选择对话框上的确定键,此函数返回一个非零值;若点击的是取消键,则函数返回一个零值。调用此函数前,还要定义二个变量:

  CHOOSEFONT  cf;

  LOGFONT   logfont;

  CHOOSEFONT是有十多个字段的结构体,包含了ChooseFont函数用来初始化字体选择对话框的各种信息。LOGFONT也是一个结构体,包含14个字段,定义了字体的各种属性。当点击确定键后,系统通过LOGFONT结构返回选定的字体信息。返回的字体信息保存在CHOOSEFONT结构的lpLogFont字段指定的LOGFONT结构中。

  下面是调用ChooseFont函数的代码:

  

 //初始化CHOOSEFONT
  cf.lStructSize  =sizeof (CHOOSEFONT);
  cf.hwndOwner  =hwnd;  //当前窗口的句柄
  cf.hDC   =NULL;
  cf.lpLogFont  =&logfont;//系统返回的字体信息保存在此处
  cf.iPointSize  =0;
  cf.Flags   =CF_INITTOLOGFONTSTRUCT|CF_
  SCREENFONTS|CF_EFFECTS;
  cf.rgbColors  =0;
  cf.lCustData  =0;
  cf.lpfnHook  =NULL;
  cf.lpTemplateName =NULL;
  cf.hInstance  =NULL;
  cf.lpszStyle  =NULL;
  cf.nFontType  =0;
  cf.nSizeMin  =0;
  cf.nSizeMax  =0;
  ChooseFont(&cf);   //此函数调用后弹出字体选择通用对话框

  如果ChooseFont(&cf)函数返回非零值,则字体已经选定。选定的字体就保存在logfont变量中。接下来要做的就是创建选定的逻辑字体。可以调用CreateFontIndirect函数创建逻辑字体。CreateFontIndirect函数接受一个指向LOGFONT结构的指针,具体定义为HFONT CreateFontIndirect(CONST LOGFONT?鄢lplf)。代码如下:

   HFONT hNewFont=CreateFontIndirect(&logfont);

  至此字体创建就完成了。直接调用SeletObject函数就可以将创建的逻辑字体选入设备描述表。在位图转换里将使用SelectObject函数将hNewFont选入内存设备描述表。但还要注意一点,在程序结束前,必须调用DeleteObject(hNewFont)函数来释放字体句柄,避免内存泄漏。下面介绍文本转换为位图的具体实现过程。

2  位图转换

  此处以提取一个“婷”字的字模为例进行说明。首先需要定义如下变量:

  

static WCHAR          Hanzi[]=“婷”;
  static HBITMAP        hBitmap;
  static int              cxBitmap,cyBitmap;
  static HDC                      hdc,hdcMem;
  PAINTSTRUCT              ps;
  SIZE    size;

  cxBitmap、cyBitmap是所要创建的位图的大小,二者与GetTextExtentPoint32函数得到的文本大小一致,在此处即是“婷”字的大小。

  以下是将汉字文本转化为位图的具体方法,一般在WM_PAINT消息中处理。

  

case WM_PAINT:
  hdc=BeginPaint(hwnd,&ps);//得到当前窗口的设备句柄
  hdcMem=CreateCompatileDC(hdc);//创建一个内存设备描述表
  SelectObject(hdcMem,hNewFont);//将创建的字体选入内存设备描述表
  GetTextExtendPoint32W(hdcMem,Hanzi,1,&size);
                   //获取要显示的文本的大小
  cxBitmap  =size.cx.;
  cyBitmap  =size.cy;
  hBitmap  =CreateCompatileBitmap(hdc,cxBitmap,
  cyBitmap);           //创建一个位图句柄
  SelectObject(hdcMem, hbitmap);//将位图选进内存设备描述表
  TextOutW(hdcMem,0,0,Hanzi,1);//将汉字画在内存设备描述表的位图上
  BitBlt(hdc,0,0,cxBitmap,cyBitmap,hdcMem,0,0,SRC-
                 COPY);                         //将位图显示在窗口的客户区,用来观察显示的效果

   至此,汉字的点阵化过程就完成了,接下来就应该提取字模。

3  提取字模

  提取字模要用到的是GetPixel函数,定义为COLORREF GetPixel(HDC hdc,int nXPos,int nYPos)。此函数返回一个COLORREF类型的值,即nXPos、nYPos所指定的点的RGB值。位图的大小在前文已经确定,在此范围类将每个象素点扫描一次,根据返回的RGB值生成点阵码。因为Windows矢量字体有灰度等级,所以必须选择合适的RGB值,用来判断此点是否有效。白色的RGB值是FFFFFFH,深灰的是808080H,黑色的是000000H。可以选择深灰做为判断依据,当函数返回值小于808080H时,认为此点有效。下面是提取字模的函数,以字节为存储单位,从第一行第一个点开始扫描:

  

static Zimo[2048];//点阵码存在此数组中
  void GetZimo(HDC hdc,int nXPos,int nYPos)
  {
     int Hang,Lie;  //Hang为扫描的行数
     int temp,i,j,g;
     Hang=nYPos;
     Lie=nXPos;
     if(Lie % 8==0 ){
          Lie=Lie/8; //位图的宽度是8的整数倍,所以
             //只需要Lie/8个字节来存储字模
                     Temp=0;
   }
    else{
                             temp=Lie % 8;
       Lie=Lie/8+1;  //位图的宽度不是8的整数倍,
                //所以只需要Lie/8+1个字节来存储字模
    }
    memset(Zimo,0,2048);//将字模数组全置0
    for(i=0;i<Hang;i++){
        for(j=0;j<Lie;j++){
            if( (temp!=0) && (j==Lie-1) ){
                for(k=0;k<temp;k++){
                   g=(int)GetPixel(hdc,j*8+k,i);
                   if(g<0x00808080)
                      Zimo[i*Lie+j]+=(unsigned 
                   char)pow(2,7-k);
                              }
                             }
                             else{
                                      for(k=0;k<8;k++){
                                       g=(int)GetPixel(hdc,j*8+k,i);
                                    if(g<0x00808080)
                                      Zimo[i*Lie+j]+=(unsigned char)pow(2,7-k);
               }
            }
        }
     }
  }

  在WM_PAINT消息中,调用GetZimo(hdcMem,cxBit-

map,cyBitmap)即可得到汉字的字模。在程序的最后,还必须做些扫尾的工作:

   DeleteObject(hBitmap);//使用完后必须释放设备描述

              //表和位图句柄,避免内存泄漏

  DeleteObject(hNewFont);

  DeleteDC(hdcMem);

  EndPaint(hwnd,&ps);

  Return 0;       //WM_PAINT消息处理完后返回

4  输出结果

   以“婷”字为例,弹出字体选择对话框后,字体选新宋体、字形选常规、字号选小二。得出Hang=24,Lie=3,存储72个字节。字模为

00H,00H,00H,00H,00H,00H,06H,03H,00H,04H,01H,80H,04H,01H,0CH,04H,3EH,F0H,0CH,00H,00H,7FH,CFH,F8H,08H,88H,10H,08H,88H,10H,18H,8FH,F0H,10H,90H,04H,11H,BFH,FEH,11H,20H,04H,31H,60H,08H,21H,40H,18H,1FH,0FH,E0H,03H,01H,80H,05H,C1H,80H,0CH,C1H,80H,08H,01H,80H,10H,0DH,80H,20H,03H,00H,00H,00H,00H。

在纸上画出点阵码,正好是“婷”字,如图1所示。从cxBitmap和cyBitmap可以知道,“婷”字点阵大小是24×24。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
网络宣传文案心碎,句句获赞! 关于朋友圈上万人点赞转发的说说 人生看的很透彻的经典句子 超现实超扎心的说说大全2019最新 心脏血管堵塞吃什么食物 投资理财有什么前景 pp理财什么情况 P2P理财行业的前景如何? 中国目前的财富管理现状是什么情况? 呼吸皮沙发寿命多久 “皮沙发的呼吸寿命” 呼吸皮沙发寿命多久 怎样提取CMD界面的文字? windows有没有像苹果itext那种免费的截图识别文字... 如何用windows xp,将图片转换成文字 怎样从WIN7的安装光盘里面提取字体文件 win7可以任意复制文字的软件(图片中的文字,无法... win10系统最好用的图片转文字软件有哪些 如何提取Windows自带字体 如何从windows里面提取成ttf字体文件?windows、fo... 怎么使用Windows之中图片文字识别软件 如何获取其他windows窗口中选中的文字 windows10怎么复制文字 windows自带文字识别 怎样在一款软件中提取所有界面显示的文字? win7系统如何提取图片中的文字? win10怎么把图片里的字复制出来 魅族aicy纵览怎么用不了 win10 桌面和任务栏 每隔20秒自动刷新 win10易升总是强制升级怎么办 win10更新失败,错误代码:0x80004005,如何解决? win10所有的内置程序全部打不开,打开也是闪退 Win... 如何获取Windows里所有的字体名称 (不是字 从windows复制文字到linux虚拟机 魅族写信息左下角叠写怎么退出 台式电脑@怎么打上去 打印机的数据线连接到台式机,怎么打印? 台式机如何打开电脑? 台式电脑怎么连打印印机 怎么样用台式电脑接打电话? 台式电脑怎么打出连接号 如何设置台式机打印机 台式机怎么连接有WIFI功能的打印机 手机如何查找重复图 电脑里面找相同的图片怎么找? 怎么找跟自己相似的图片 如何将电脑上相似的图片最方便地找出来? 如何搜索相似图片 如何才能找到相似图片? 如何找相似的图片? 怎么根据图片找到另一张相似的图片 如何查图片的相似度