赞
踩
参考自:
解密大漠插件文字识别原理(带源码)
展示MFC部分源码:
文字识别原理在很多人面前已经不是什么秘密了,但是通过理解这些原理,我们可以更好的使用大漠插件文字识别功能
事情的起源是我异想天开的想用纯TC代替大漠插件进行文字识别,又懒得自己写一个字库制作工具,就想利用大漠综合工具制作的字库进行文字识别…
于是乎就开始探索大漠字库的奥秘…
402807FF801002$1$0.0.17$11
以上是一个1字的大漠字库信息,我们可以很明显的看到,信息字串用"$"符号,分为4个部分,下面我们就来一一分析这4个部分代表什么,有什么用
第一部分 402807FF801002 很明显是一个十六进制字符串
我们知道电脑显示图也好字也好,都是以像素颜色点来显示的.
那么一个字的组成,就是一个点阵的组合,如下图:
我们可以看到,这是一个二值化点阵,点阵只有两种色块(像素点)组成,黑色(字体色)和灰色(背景色)
大漠插件用1表示黑色(字体色),用0表示灰色(背景色),如下
对了千万不要被下面的数字所欺骗,要像图中一样的读法才能完美解析。
00100
11100
00100
00100
00100
00100
00100
00100
00100
00100
11111
以从上到下,从左到右的顺序排列
那么上面的点阵,就是:0100000000101000000001111111111110000000000100000000001
错误示范:
我们可以看到最后一组多加了一个0,这个0是怎么加的呢?
以字体点阵的最大宽度(例:5)除以4,余数是多少就加多少个0(例:5/4余1)
402807FF801002,我们可以看到字库的点阵信息就还原出来了
那么,字库信息的第一部分就是字体点阵的信息
这下把我两天来研究的解析大漠字库MFC/C++代码贡献给大家
代码:
int CFinndstrExDlg::GetDict(CString str_a) { CString str,str1; int strl = str_a.GetLength(); CString Dict1; //要操作字体的点阵 CString Neam; //要操作的字符名称 CString czs;//有效像数 CString chs;//竖排行数 int strlock = 0; for (UINT64 i = 0; i < strl; i++) { str1 = str_a.Mid(i, 1); if (str1=="$") { strlock++; } if (strlock==0 && str1 != "$") { Dict1 += str1; str1 = ""; } if (strlock == 1 && str1 != "$") { Neam += str1; str1 = ""; } if (strlock == 2&& str1!="$") { czs += str1; str1 = ""; } if (strlock == 3 && str1 != "$") { chs += str1; str1 = ""; } } if (Dict1.GetLength()<=0|| Neam.GetLength() <= 0|| czs.GetLength() <= 0|| chs.GetLength() <= 0) { return 0;//读取错误返回0 } //下面我们申请一个字库机构体 // 当然这个机构体要放到外面 //struct MyDict //{ // CString Dict; //要操作字体的点阵 // CString Neam; //要操作的字符名称 // int yxxs;//有效像数 // int spxs;//竖排行数 //}; Dict.Dict=(strToren(Dict1));//转换到二进制 Dict.Neam = Neam; //要找的字符名称 str = czs.Mid(4, czs.GetLength() - 1); Dict.yxxs = StrToInt(str);//字符转换到整数 Dict.spxs = StrToInt(chs);//这是竖排行数 return 1; }
第二部分 1 我们制作字库时定义的字
这个就不用再详细解释了吧,这是代表了字库点阵信息的字符,是我们在制作字库时,自己定义的(系统字库自动定义).如下图:
下面贴出部分图片转二值化的代码:
int redToGreen(COLORREF& c,CString color,float sim)//把图片二值化 { BYTE R = c;// GetRValue(c);//获取c中R的值 int c1 = StrToInt(color); //获取c1中RGB的值 BYTE R1 = c1;// GetRValue(c);//获取c中R的值 if (R>0) { if (R1>=R) { if ((R1-R)<=(R/ sim)) {R = 1;}else{ R = 0;} } else if (R1 <= R) { if ((R - R1) <= (R / sim)) {R = 1;} else{ R = 0;} } } else { return 0; } return R; }
以上代码还未经过测试,因为还没写完。
这东西必须写完才能测试。
本帅还编写了了一个:X64||X86通用汇编代码注入器!
下面贴出图片
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。