⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwpreview.cpp

📁 关于字符分割的程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			j = 0;
		}else{
			j = lTeam[i+1];
		}
		if (lTeam[i] != 0 &&( i ==0 || lTeam[i] != lTeam[i-1])) {
			k = i;
		}
		if (lTeam[i] != j && lTeam[i] !=0 ) {
			cr.left = 0 ;cr.top = k; cr.right = lWidth; cr.bottom = i;
			if (cr.Height()>5) {
			m_ListRect.AddTail(new CRect(cr));

			lit = new LineInfo();
			lit->Top = cr.top;lit->Bottom = cr.bottom;
			if (LinesInfoHead == NULL) {
				LinesInfoHead = LinesInfoRear = lit;
			}else{
				LinesInfoRear->next = lit;
				LinesInfoRear = lit;
			}
			}
		}
	}

	delete[] lCount;
	delete[] lTeam ;

	GlobalUnlock((HGLOBAL) hDib);

	pDoc->UpdateAllViews(NULL);
	
}


void CHwpreView::OnEgVprojectAll() 
{
	// TODO: Add your command handler code here
	HDIB hdibD = GetDocument()->GetHDIB2();
	
	HDIB hdib_backup =(HDIB) ::CopyHandle((HGLOBAL) hdibD);

	LPSTR hlpstr = (LPSTR) ::GlobalLock((HGLOBAL) hdibD);
	LPSTR hBits = ::FindDIBBits(hlpstr);
	LPBYTE hbitsD ;
	LONG lHeight = ::DIBHeight(hlpstr);
	LONG lWidth = ::DIBWidth(hlpstr);
	LONG m_lLineBytes = WIDTHBYTES( lWidth*8 );

	memset(hBits,(BYTE)255, lHeight * m_lLineBytes);
	
	int j ,k;
	int *lcount ;
	
	CRect cr;int i = 0 ; POSITION pst;
	if (!m_ListRect.IsEmpty()) {
		pst = m_ListRect.GetHeadPosition();
		do {
			cr = *((CRect * ) m_ListRect.GetAt(pst));

			lcount = new int[cr.Width()+1];
			::VprojectDIB2((LPSTR)hdib_backup,lcount,cr.left ,cr.top ,cr.right ,cr.bottom );
			for (k= cr.left;k<=cr.right;k++) {
				for (j= 1;j<=lcount[k-cr.left];j++) {
					hbitsD = (LPBYTE)hBits + m_lLineBytes * (lHeight -1 +j - cr.bottom) +k ;
					* hbitsD = 0;
				}
			}
			delete[] lcount;

			m_ListRect.GetNext(pst);
			i++;
		} while(i<m_ListRect.GetCount());
	}
	else{
		cr.left = cr.top = 0;cr.right = lWidth -1;
		cr.bottom = lHeight -1;
	}
	


	//GetDocument()->HDIBCOPYTOHDIB2();
	
	::GlobalUnlock((HGLOBAL) hdibD);
	::GlobalFree((HGLOBAL) hdib_backup);

	GetDocument()->UpdateAllViews(NULL);	
}

void CHwpreView::CPtrListToLineInfo()
{
	HDIB hdibD = GetDocument()->GetHDIB2();
	LPSTR hlpstr = (LPSTR) ::GlobalLock((HGLOBAL) hdibD);
	LONG lHeight = ::DIBHeight(hlpstr);
	LONG lWidth = ::DIBWidth(hlpstr);
	LONG m_lLineBytes = WIDTHBYTES( lWidth*8 );
	LineInfo * li , * lit;
	WordFragmentInfo * wfi;
	
	li = LinesInfoHead;
	while (li != NULL) {
		lit = li;
		li = li->next;
		delete lit;
	}
	LinesInfoHead = NULL;
	LinesInfoRear = NULL;
	LinesInfoLength = 0;

	CRect cr;int i = 0 ; POSITION pst;
	if (!m_ListRect.IsEmpty()) {
		pst = m_ListRect.GetHeadPosition();
		do {
			cr = *((CRect * ) m_ListRect.GetAt(pst));
			li = new LineInfo();
			li->Top = cr.top;
			li->Bottom = cr.bottom;
			if (li->Height_1()>this->maxLineHeight) {
				maxLineHeight = li->Height_1();
			}
			if (LinesInfoHead == NULL) {
				LinesInfoHead = LinesInfoRear = li;
			}else{
				LinesInfoRear->next = li;
				LinesInfoRear = li;
			}
			m_ListRect.GetNext(pst);
			i++; 
		} while(i<m_ListRect.GetCount());
		LinesInfoLength = i;
	}
	else{
		cr.left = cr.top = 0;cr.right = lWidth -1;
		cr.bottom = lHeight -1;
		li = new LineInfo();
		li->Top = cr.top;
		li->Bottom = cr.bottom;
		if (li->Height_1()>this->maxLineHeight) {
			maxLineHeight = li->Height_1();
		}
		if (LinesInfoHead == NULL) {
			LinesInfoHead = LinesInfoRear = li;
		}else{
			LinesInfoRear->next = li;
			LinesInfoRear = li;
		}		
		LinesInfoLength = 1;
	}	
	li = NULL;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		
		wfi = new WordFragmentInfo(li,0,lWidth -1);
		wfi->top = li->Top;wfi->bottom = li->Bottom;
		li->first = wfi;
		li->last = wfi;
	} while(li != LinesInfoRear);

	::GlobalUnlock((HGLOBAL) hdibD);

}

void CHwpreView::OnEgVword2() 
{
	// TODO: Add your command handler code here
	CDlgWordPara dwp;
	if (dwp.DoModal()!=IDOK) {
		return;
	}
	nudDensity = dwp.m_nudDensity;
	nudPunctuationWidth = dwp.m_nudPunctuationWidth;
	nudSpace = dwp.m_nudSpace;
	nudCharWidth = dwp.m_nudCharWidth;

	CPtrListToLineInfo();

	GetStaticsOfEachLine();   //像素统计
	SplitWords();             //字符拆分
	MergeFromRight();         //从右向左合并偏旁部首
	RemoveSpaces();           //删除每个切分字上下的空白区域
	RemoveExtraSplits();      //删除面积过小的切分区域
	DrawSplitResult();        //绘制结果

}

void CHwpreView::GetStaticsOfEachLine()
{
	HDIB hdibD = GetDocument()->GetHDIB2();
	
//	HDIB hdib_backup =(HDIB) ::CopyHandle((HGLOBAL) hdibD);

	LPSTR hlpstr = (LPSTR) ::GlobalLock((HGLOBAL) hdibD);
	LPSTR hBits = ::FindDIBBits(hlpstr);
//	LPBYTE hbitsD ;
	LONG lHeight = ::DIBHeight(hlpstr);
	LONG lWidth = ::DIBWidth(hlpstr);
	LONG m_lLineBytes = WIDTHBYTES( lWidth*8 );
	LineInfo * li;
//	WordFragmentInfo * wfi;
	
	li = NULL;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		
		li->DotsStatics = new int[lWidth];
		::VprojectDIB2((LPSTR)hdibD,li->DotsStatics,0,li->Top,lWidth-1,li->Bottom);
		::Smoth(li->DotsStatics,lWidth -1 ,5);
	} while(li != LinesInfoRear);
			
	::GlobalUnlock((HGLOBAL) hdibD);
//	::GlobalFree((HGLOBAL) hdib_backup);

}

void CHwpreView::SplitWords()
{
	LineInfo * li;
	WordFragmentInfo * wfi;
	int bound = -1;
	
	//		lblMessage.Text = "正在进行文字拆分迭代处理...";
	while(NeedMoreSplit() && bound <= maxLineHeight )
	{
		bound ++;
		
		li = NULL;
		do {
			if (li == NULL) {
				li = LinesInfoHead;
			}else{
				li = li->next;
			}
			wfi = li->first;
			do
			{
				if(wfi->Width_1() > (double)nudCharWidth * SplitScale)
					wfi = SplitWordFragment(wfi, bound);
				else
					wfi = wfi->next;
				
			}
			while(wfi != NULL);
		} while(li != LinesInfoRear);
		if(bound == 0)
			RemovePunctuations();
		
	}
}

BOOL CHwpreView::NeedMoreSplit()
{
	LineInfo * li;
	WordFragmentInfo * wfi;
	
	li = NULL;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		
		wfi = li->first;
		while (wfi !=NULL) {
			if (wfi->Width_1() > (double)nudCharWidth * SplitScale ) {
				return TRUE;
			}
			wfi = wfi->next;
		}
		
	} while(li != LinesInfoRear);
	
	return FALSE;
}

WordFragmentInfo * CHwpreView::SplitWordFragment(WordFragmentInfo *fragment, int bound)
{
	WordFragmentInfo * nextToProcess = fragment->next;
	LineInfo * parentLine = fragment->parentLine;
	int * DotsStatics = parentLine->DotsStatics;
	int begin = fragment->left;
	int end = fragment->right;
	int i;
	
	WordFragmentInfo * wfInfo = new WordFragmentInfo(parentLine), * first, * last;
	CPtrArray splitPoints ;
	BOOL beginFindSplitPoint = FALSE;
	
	for(i=begin; i<=end; i++)
	{
		if(!beginFindSplitPoint && DotsStatics[i] > bound)
		{
			wfInfo = new WordFragmentInfo(parentLine);
			wfInfo->left = i;
			wfInfo->top = parentLine->Top;
			wfInfo->bottom = parentLine->Bottom;
			beginFindSplitPoint = true;
		}
		
		if(beginFindSplitPoint && DotsStatics[i] <= bound)
		{
			wfInfo->right = i;
			splitPoints.Add(wfInfo);
			beginFindSplitPoint = false;
		}
		
		if(beginFindSplitPoint)
			wfInfo->blackDotsInArea += DotsStatics[i];
	}
	
	if(splitPoints.GetSize() == 0)
		return nextToProcess;
	
	//串成链表
	first = (WordFragmentInfo *)splitPoints[0];
	last = (WordFragmentInfo *)splitPoints[splitPoints.GetSize()-1];
	
	if(splitPoints.GetSize() > 1)
	{
		for(int i=0; i<splitPoints.GetSize()-1; i++)
		{
			((WordFragmentInfo*)splitPoints[i])->next = (WordFragmentInfo*)splitPoints[i+1];
			((WordFragmentInfo*)splitPoints[i+1])->prior = (WordFragmentInfo*)splitPoints[i];
		}
	}
	
	//替换掉原有Fragment
	if(fragment->prior == NULL && fragment->next == NULL)	//链表中唯一的一个元素
	{
		parentLine->first = first;
		parentLine->last = last;			
	}
	else if(fragment->prior == NULL)	//链表中的第一个元素
	{
		last->next = fragment->next;
		fragment->next->prior = last;
		parentLine->first = first;
	}
	else if(fragment->next == NULL)	//链表中的最后一个元素
	{
		fragment->prior->next = first;
		first->prior = fragment->prior;
		parentLine->last = last;
	}
	else	//链表中间的元素
	{
		fragment->prior->next = first;
		first->prior = fragment->prior;
		fragment->next->prior = last;
		last->next = fragment->next;
	}
	delete fragment;
	
	return nextToProcess;
}

void CHwpreView::RemovePunctuations()
{
	WordFragmentInfo * wfInfo , * wft;
	LineInfo * parentLine, * li;
	
	li = NULL;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		wfInfo = li->first;
		do
		{
			if(wfInfo->IsPunctuation((int)nudPunctuationWidth, (int)nudDensity))
			{
				parentLine = wfInfo->parentLine;
				
				//删除当前元素
				wft = wfInfo;
				if(wfInfo->prior == NULL && wfInfo->next == NULL)	//链表中唯一的一个元素
				{
					parentLine->first = NULL;
					parentLine->last = NULL;
					wfInfo = NULL;
					delete wft;
				}
				else if(wfInfo->prior == NULL)	//链表中的第一个元素
				{
					parentLine->first = wfInfo->next;
					wfInfo->next->prior = NULL;
					wfInfo = wfInfo->next;
					delete wft;
				}
				else if(wfInfo->next == NULL)	//链表中的最后一个元素
				{
					parentLine->last = wfInfo->prior;
					wfInfo->prior->next = NULL;
					wfInfo = NULL;
					delete wft;
				}
				else	//链表中间的元素
				{
					wfInfo->prior->next = wfInfo->next;
					wfInfo->next->prior = wfInfo->prior;
					wfInfo = wfInfo->next;
					delete wft;
				}					
			}
			else
				wfInfo = wfInfo->next;
		}
		while(wfInfo != NULL);
		
		
	} while(li !=LinesInfoRear);
	
}

void CHwpreView::MergeFromRight()
{
	WordFragmentInfo * wfInfo, * wft;
	
	//lblMessage.Text = "正在进行偏旁部首合并处理...";
	LineInfo * li;
	li = NULL;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		wfInfo = li->last;
		do
		{
			if(CanMerge(wfInfo, wfInfo->prior))
			{	
				wft = wfInfo->prior;
				wfInfo->left = wfInfo->prior->left;
				wfInfo->blackDotsInArea += wfInfo->prior->blackDotsInArea;
				wfInfo->prior = wfInfo->prior->prior;
				delete wft;
				if(wfInfo->prior != NULL)
					wfInfo->prior->next = wfInfo;
				else
					wfInfo->parentLine->first = wfInfo;
			}
			else
				wfInfo = wfInfo->prior;
		}
		while(wfInfo != NULL);
	} while(li !=LinesInfoRear);
}

BOOL CHwpreView::CanMerge(WordFragmentInfo *current, WordFragmentInfo *leftOne)
{
	if(leftOne == NULL)
		return false;
	
	//如果当前文字大于1.3平均字宽,放弃合并
	if(current->Width_1() >= (float)nudCharWidth * 1.3f)	
		return false;
	
	//如果两字距离大于指定域值并且合并后宽度太大,放弃合并
	if(current->left - leftOne->right > nudSpace && current->right - leftOne->left > (float)nudCharWidth * 1.2f)
		return false;
	
	//如果合并后字符宽度太大,放弃合并
	if(current->right - leftOne->left > (float)this->nudCharWidth * 1.33f)
		return false;
	
	return true;
}

void CHwpreView::RemoveSpaces()
{
	HDIB hdibD = GetDocument()->GetHDIB2();
	LPSTR hlpstr = (LPSTR) ::GlobalLock((HGLOBAL) hdibD);
	LONG lHeight = ::DIBHeight(hlpstr);
	LONG lWidth = ::DIBWidth(hlpstr);
	LONG m_lLineBytes = WIDTHBYTES( lWidth*8 );
	
	WordFragmentInfo * wfInfo;
	
	//lblMessage.Text = "正在去除多余的空隙...";
	int BlackDots = 0, t=0, b=0;
	
	//Bitmap bm = new Bitmap(this.spbSrc.ImageFileName);
	int * bm = new int[lHeight * lWidth];
	::DIBToIntArray(hlpstr,0,0,lWidth-1,lHeight-1,bm,lWidth,lHeight,ID_IMAGE_01);
	LineInfo * li;
	li = NULL;
	int x,y;
	do {
		if (li == NULL) {
			li = LinesInfoHead;
		}else{
			li = li->next;
		}
		wfInfo = li->first;
		do
		{
			BlackDots = 0;
			t = 0;
			b = 0;
			
			//去除上面空隙
			for(y=wfInfo->top; y<=wfInfo->bottom; y++)
			{
				for(x=wfInfo->left; x<wfInfo->right; x++)
					if(bm[x+ y* lWidth] == 1)
						BlackDots++;
					
					if(BlackDots == 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -