📄 stddataobject.cpp
字号:
pp+=twodx_dy;
}
if(StdIsBlack(x,y))
{
if(flags=='B') count++; //如果当前标志为B,则继续计数
else{
flags='B'; //否则改变标志,并把数据存入;
BWArray[ArrNum++]=count;
count=1;
}
}
else {
if(flags=='W')count++;
else{
flags='W';
BWArray[ArrNum++]=count;
count=1;
}
}
num++;
}
}
else
{
while(x>xend?x>xend:x<xend)
{
if(x<600)
{
x++;
x--;
}
if(x>xend) x--;
else x++;
if(p<0)
p+=twody;
else{
if(yb>ya) y++;
else y--;
p+=twody_dx;
}
if(StdIsBlack(x,y))
{
if(flags=='B') count++; //如果当前标志为B,则继续计数
else{
flags='B'; //否则改变标志,并把数据存入;
BWArray[ArrNum++]=count;
count=1;
}
}
else {
if(flags=='W')count++;
else{
flags='W';
BWArray[ArrNum++]=count;
count=1;
}
}
num++;
}
}
BWArray[ArrNum]=count;
BWArray[ArrNum+1]='\0';
return ArrNum+1;
}
BOOL CStdDataObject::IsBarTail(Region* pReg)
{
Region tmpreg,reg;
UCHAR TailShape[]={7,1,1,3,1,1,1,2,1};
//此变量进行两个方向的判断
BOOL firstjudge=true;
UPOINT* PointArray;
UCHAR BWArray[1000];
//把原矩形化为可供判断的标准矩形
reg = *pReg;
tmpreg = reg;
if((reg.Top.x-reg.Left.x)*(reg.Top.x-reg.Left.x)+(reg.Left.y-reg.Top.y)*(reg.Left.y-reg.Top.y) >
(reg.Right.x-reg.Top.x)*(reg.Right.x-reg.Top.x)+(reg.Right.y-reg.Top.y)*(reg.Right.y-reg.Top.y))
{
tmpreg.Left=reg.Top;
tmpreg.Root=reg.Left;
tmpreg.Top=reg.Right;
tmpreg.Right=reg.Root;
}
loop:
if(!firstjudge)
{
//进行第二次判断时,改变方向
Region tmpreg1 = tmpreg;
tmpreg.Top = tmpreg1.Root;
tmpreg.Left = tmpreg1.Right;
tmpreg.Right = tmpreg1.Left;
tmpreg.Root = tmpreg1.Top;
}
//计算点的总数
int _height = (int)(sqrt((tmpreg.Left.x-tmpreg.Root.x)*(tmpreg.Left.x-tmpreg.Root.x)+
(tmpreg.Left.y-tmpreg.Root.y)*(tmpreg.Left.y-tmpreg.Root.y))+1.5);
//申请一空间以存入纵向的点(起始点)
PointArray = new UPOINT[_height];
int rheight = GetLineDataA(tmpreg.Left.x,tmpreg.Left.y,tmpreg.Root.x,tmpreg.Root.y,PointArray);
//确定dx,dy值
int tx=tmpreg.Top.x,ty=tmpreg.Top.y,lx=tmpreg.Left.x,ly=tmpreg.Left.y,z;
z=(tx>lx)?1:-1;
int dx=(int)((tx==lx)?0:(19*(tx-lx+z)/7+0.5));
z=(ty>ly)?1:-1;
int dy=(int)((ty==ly)?0:(19*(ty-ly+z)/7+0.5));
//申请空间以存放横向的点(一行数据),宽度为_width
int _width = (int)(sqrt(dx*dx+dy*dy)+1.5);
if(_width>1000) //如一条模宽度大于1000,则认为数据出错
{
delete PointArray;
return false;
}
int dj=(int)(rheight/JUDGETIMES+0.5);
if(dj<1) dj=1;
for(int i=rheight/(2*JUDGETIMES),rightnum=0;i<rheight;i+=dj)
{
//得到一行数据
UINT tx=PointArray[i].x+dx,ty=PointArray[i].y+dy;
if(tx<0) tx=0;
if(tx>dImageWidth-1) tx=dImageWidth-1;
if(ty<0) ty=0;
if(ty>dImageHeight-1) ty=dImageHeight-1;
int rwidth=GetLineDataB(PointArray[i].x,PointArray[i].y,tx,ty,BWArray);
//得到起始符位置
for(int k=0;k<rwidth;k++)
if(BWArray[k]>8) break;
//得出一个模块宽
double onewidth = (double)(BWArray[k]+1)/8;
rwidth=(rwidth>9?9:rwidth);
for(int j=k;j<rwidth;j++)
{
if(abs((int)(((double)BWArray[j]/onewidth)-TailShape[j-k]))>=1)
break;
}
if(j==rwidth&&rwidth>=9) rightnum++; //如果满足要求,则加一
if(rightnum > JUDGETIMES/2) break;
}
delete[] PointArray;
if(rightnum > JUDGETIMES/2) //如果正确的数据超过总判断数的1/2,则认为正确
{
*pReg = tmpreg;
return true;
}
else if(firstjudge)
{
firstjudge = false;
goto loop;
}
else
return false;
}
//把从点(xa,ya)到点(xb,yb)的直线段上所有的点均存入数组,并返回点的数目
UINT CStdDataObject::GetLineDataA(UINT xa, UINT ya, UINT xb, UINT yb, UPOINT* PointArray)
{
int num=0;
int dx=abs(xa-xb),dy=abs(ya-yb);
int p=2*dy-dx;
int pp=2*dx-dy;
int twody=2*dy,twody_dx=2*(dy-dx);
int twodx=2*dx,twodx_dy=2*(dx-dy);
int x,y,xend,yend;
x=xa;y=ya;
xend=xb;yend=yb;
PointArray[num].x=x;
PointArray[num].y=y;
num++;
if(dy>dx)
{
while(y>yend?y>yend:y<yend)
{
if(y>yend) y--;
else y++;
if(pp<0)
pp+=twodx;
else{
if(xb>xa) x++;
else x--;
pp+=twodx_dy;
}
PointArray[num].x=x;
PointArray[num].y=y;
num++;
}
}
else
{
while(x>xend?x>xend:x<xend)
{
if(x>xend) x--;
else x++;
if(p<0)
p+=twody;
else{
if(yb>ya) y++;
else y--;
p+=twody_dx;
}
PointArray[num].x=x;
PointArray[num].y=y;
num++;
}
}
return num-1;
}
//执行数据分析操作
//1.定义Cell,调用FindAllCell来找出所有匹配的区域,存入类成员RegionList;
//2.根据找出的每一个区域,进行判断
BOOL CStdDataObject::Act()
{
//定义Cell(8*8矩阵)
Cell m_cell;
CellItem CellItems[] = {{0,0},{1,0},{2,0},{3,0},{4,0},{5,0},{6,0},{7,0},
{0,7},{1,7},{2,7},{3,7},{4,7},{5,7},{6,7},{7,7},
{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},
{7,1},{7,2},{7,3},{7,4},{7,5},{7,6},{7,7}};
m_cell.CellArray=CellItems;
m_cell.CellItemCount=30;
//调用成员函数来找出所有包含m_cell的区域于RegionList中
CList<struct _Region,struct _Region &> RegionList;
FindAllCell(&m_cell,RegionList);
//判断是否有数据,如无则退出
if(RegionList.IsEmpty())
return false;
//遍历对列,找出条码起始,结束符,并删除无用数据顶
POSITION tmppos,pos;
Region tmpreg,reg; //用于临时存储变量
pos = RegionList.GetHeadPosition(); //得到对列头
do
{
reg = RegionList.GetAt(pos);
tmppos = pos; //保存对列指针
RegionList.GetNext(tmppos); //保存下一数据POSITION
if(IsBarHeader(®)) //判断是否为条码起始符
{
RegionList.GetAt(pos) = reg;
RegionList.GetAt(pos).RegionType='H'; //区域类型为HEADER
}
else if(IsBarTail(®)) //判断是否为条码结束符
{
RegionList.GetAt(pos) = reg;
RegionList.GetAt(pos).RegionType='T'; //区域类型为TAIL
}
else RegionList.RemoveAt(pos); //无效数据则删除
pos = tmppos;
}while(pos!=NULL);
//判断对列中是否有数据,如无则退出
if(RegionList.IsEmpty())
return false;
//再次遍历对列,找出相匹配的HEAD和TAIL,如匹配,则译出数据,并返回true
BOOL bHaveOneBar=false;
for(pos=RegionList.GetHeadPosition();pos!=NULL;RegionList.GetNext(pos))
{
reg = RegionList.GetAt(pos);
if(reg.RegionType == 'H')
{
for(tmppos=RegionList.GetHeadPosition();tmppos!=NULL;RegionList.GetNext(tmppos))
{
tmpreg = RegionList.GetAt(tmppos);
//查看两者是否匹配,如匹配,则返回数据于列表中
if(tmpreg.RegionType=='T'&&IsMatch(reg,tmpreg))
{
//如果已匹配,则设置标志为'O'
RegionList.GetAt(pos).RegionType = 'O';
RegionList.GetAt(tmppos).RegionType = 'O';
//得到一个数据后就返回true;
bHaveOneBar=true;
return true; //目前只处理一个图形数据
}
}
}
}
//删除数列
if(RegionList.GetCount() != 0)
RegionList.RemoveAll();
return bHaveOneBar;
}
//根据两区域的Top,Left,Right,Root的坐标以及由两者的组合区域是否为一矩阵
//来查看两区域(条码起始符/条码结束符)是否匹配
BOOL CStdDataObject::IsMatch(Region reg1, Region reg2)
{
Region reg;
int arraylen,tmp;
//合并两矩形
reg.Left = reg1.Left;
reg.Root = reg1.Root;
reg.Top = reg2.Top;
reg.Right = reg2.Right;
//判断组合区域是否为一矩阵
if(IsRect(reg))
{
CClientDC dc(((CMainFrame*)(AfxGetMainWnd()->GetActiveWindow()))->m_wndSplitter.GetPane(0,0));
dc.MoveTo(reg.Left.x,reg.Left.y);
dc.LineTo(reg.Top.x,reg.Top.y);
//计算纵向点的总数
int _height = (int)(sqrt((reg.Left.x-reg.Root.x)*(reg.Left.x-reg.Root.x)+
(reg.Left.y-reg.Root.y)*(reg.Left.y-reg.Root.y))+1.5);
//得到每一行的起始点坐标,PointArray用于存放此点数组
UPOINT* PointArray = new UPOINT[_height];
int rheight = GetLineDataA(reg.Left.x,reg.Left.y,reg.Root.x,reg.Root.y,PointArray);
//tx,ty为每一行的目标点坐标
//dx,dy为起始与目标点的坐标差
int tx=reg.Top.x,ty=reg.Top.y,lx=reg.Left.x,ly=reg.Left.y,z;
z=(tx>lx)?1:-1;
int dx=(tx==lx)?0:(tx-lx+z);
z=(ty>ly)?1:-1;
int dy=(ty==ly)?0:(ty-ly+z);
int _width = (int)(sqrt(dx*dx+dy*dy)+1.5);
//用于存放每一条/空的点数,经IsValidData判断后,存放每一条/空的模块数
UCHAR* BWArray = new UCHAR[_width];
//用于保存刚进行判断的数据,以防止存入两相同的行
UCHAR *tmpCurArray = new UCHAR[_width];
//对应条码的当前行
int CurrentRow=0;
//对条码的每一行进行判断
for(int i=0,rightnum=0;i<rheight;i++)
{
//得到一行数据
UINT tx=PointArray[i].x+dx,ty=PointArray[i].y+dy;
//进行有效性判断
if(tx<0) tx=0;
if(tx>dImageWidth-1) tx=dImageWidth-1;
if(ty<0) ty=0;
if(ty>dImageHeight-1) ty=dImageHeight-1;
int rwidth=GetLineDataB(PointArray[i].x,PointArray[i].y,tx,ty,BWArray);
//判断是否为正确数据,如是,则对其转换
if(IsValidData(BWArray,rwidth,CurrentRow))
{
i+=2;
//比较两行数据是否相同
tmp = strcmp((char*)BWArray,(char*)tmpCurArray);
if(tmp!=0)
{
if(BarDataList.GetCount() == 0)
arraylen = strlen((char*)BWArray);
if(arraylen == strlen((char*)BWArray))
{
//如不同,则存入对象的BarDataList中
UCHAR* tmparray = new UCHAR[rwidth];
memcpy(tmparray,BWArray,rwidth);
if(BarDataList.GetCount() == 0)
{
BarDataList.AddHead(tmparray);
arraylen = strlen((char*)tmparray);
}
else
BarDataList.AddTail(tmparray);
memcpy(tmpCurArray,BWArray,rwidth);
i+=2;
CurrentRow++;
}
}
}
else memset(tmpCurArray,0,_width);
}
delete[] PointArray;
delete[] BWArray;
delete[] tmpCurArray;
}
//根据列表是否为空,返回true/false
if(BarDataList.IsEmpty())
return false;
else
return true;
}
//判断数据是否有效
//入口:
//pStr---指向条/空信息串,每一个数据表示对应的条/空为多少点数
//len ---信息串长度
//返回:
// true:表示数据正确,pStr中的数据改为条/空的模块数(已不含条码起始和结束符)
// false:数据不符合
BOOL CStdDataObject::IsValidData(UCHAR *pStr, UINT len,int CurrentRow)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -