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

📄 image.cpp

📁 这是树上的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	for ( i=0;i<nMaxMarkValue;i++ )
	{	
		vMarkMap[i].nOriginalMark=i+1;
		vMarkMap[i].nMappingMark=i+1;
	}

	POSITION posInnerElem; //InnerList中元素的位置
	int nMin;              //InnerList中最小值
	int nIndex=0;

	posExElem=exList.GetHeadPosition();
	/* while循环实现了如下功能:找到每个等价组中最小的标记值,
	然后将映射向量中nMappingMark设定为其所在等价组的最小的标记值。*/
	while ( posExElem )
	{	
		pInnerList=(CPtrList *)exList.GetAt(posExElem);
		nMin=(int)pInnerList->GetHead();
		posInnerElem=pInnerList->GetHeadPosition();
		pInnerList->GetNext(posInnerElem);

		while ( posInnerElem )
		{
			if ( (int)pInnerList->GetAt(posInnerElem)<nMin )
			{	
				nMin=(int)pInnerList->GetAt(posInnerElem);
			}
			pInnerList->GetNext(posInnerElem);
		}

		/* 根据每组等价关系中的最小的标记值对Mapping向量做出调整。 */
		posInnerElem=pInnerList->GetHeadPosition();
		while ( posInnerElem )
		{
			nIndex=(int)pInnerList->GetAt(posInnerElem)-1;
			vMarkMap[ nIndex ].nMappingMark=nMin;
			pInnerList->GetNext(posInnerElem);
		}
		exList.GetNext(posExElem);
	}

	/* 将映射向量nMappingMark中不重复的部分找出并对其进行排序。
	使用find()和sort()这两种泛型算法,应该#include <algorithm>。*/
	vector <int> vSortMark(nMarkRegion); //排序向量
	nIndex=0;

	for ( i=0; i<nMaxMarkValue; i++ )
	{
		if  ( find( vSortMark.begin(),vSortMark.end(), vMarkMap[i].nMappingMark )
			==vSortMark.end() )
		{
			vSortMark[nIndex++]= vMarkMap[i].nMappingMark;
		}
	}
	sort ( vSortMark.begin(),vSortMark.end() );

	/* 根据排序后的标记在vSortMark向量中的位置,对映射向量做出重新调整。 */
	vector<int>::iterator itFind;
	vector<int>::iterator itBegin;
	itBegin=vSortMark.begin();

	for ( i=0;i<nMaxMarkValue;i++ )
	{
		itFind = find ( vSortMark.begin(),vSortMark.end(), vMarkMap[i].nMappingMark );
		vMarkMap[i].nMappingMark= ( itFind-itBegin + 1);
	}

	//根据映射向量对标记数组进行调整
	for ( j=0;j<m_lngHeight;j++ )
	{
		m_lpnMarkMove=m_lpnMark + j*m_lngWidthBytes;
		for ( i=0;i<m_lngWidth;i++ )
		{
			if ( *m_lpnMarkMove != 0 )
			{
				*m_lpnMarkMove = vMarkMap[ *m_lpnMarkMove-1 ].nMappingMark;
			}
			m_lpnMarkMove++;
		}
	}

	//删除链表结构中通过new得到的元素
	posExElem = exList.GetHeadPosition();
	while( posExElem )
	{
		pInnerList = (CPtrList *)exList.GetAt( posExElem );
		pInnerList->RemoveAll();
		delete pInnerList;
		exList.GetNext( posExElem );
	}
	exList.RemoveAll();

	//通过类成员变量来记录连通区域的个数
	m_nMarkNumbers = nMarkRegion;
	return (long)TRUE;

}

long CImage::ReadBMPFile(LPCTSTR strFileName)
{
	Clear();

	CFile BitmapFile;
	BOOL blOpen=BitmapFile.Open(strFileName, CFile::modeRead,NULL);

	if( !blOpen )
	{
		CString str = "读文件失败!";
		AfxMessageBox(str);
		return (long)FALSE;
	}

	unsigned int FileLength=BitmapFile.GetLength();
	m_lpBMPFileData = new BYTE[FileLength];
	ASSERT( m_lpBMPFileData!=NULL );
	BitmapFile.Read(m_lpBMPFileData, FileLength);
	
	//初始化成员变量
	LPBITMAPFILEHEADER pBitmapFileHeader = (LPBITMAPFILEHEADER)m_lpBMPFileData;
	LPBITMAPINFOHEADER pBitmapInfoHeader = LPBITMAPINFOHEADER(m_lpBMPFileData+sizeof(BITMAPFILEHEADER));
		
	if ( pBitmapFileHeader->bfType != 0x4D42 )
	{
		CString str = "不支持除BMP之外的文件!";
		AfxMessageBox(str);
		return (long)FALSE;
	}

	//开始进行类成员的初始化
	m_BmpInfoHeader = * pBitmapInfoHeader;
	m_lngWidth=pBitmapInfoHeader->biWidth;
	m_lngHeight=pBitmapInfoHeader->biHeight;
	
	if  ( m_BmpInfoHeader.biBitCount ==8 )
	{
		m_lngWidthBytes = (m_lngWidth+3) & 0xfffffffc;
		m_ulngBitsCount = m_lngWidthBytes*m_lngHeight;
		m_lpImgBits= new BYTE[m_ulngBitsCount];
		ASSERT (m_lpImgBits!=NULL);
		::memcpy(m_lpImgBits,(LPBYTE)m_lpBMPFileData + ((BITMAPFILEHEADER *)m_lpBMPFileData)->bfOffBits,m_ulngBitsCount);
	}
	else
	{
		CString str = "不支持除8位BMP之外的文件!";
		AfxMessageBox(str);
		return (long)FALSE;	
	}
	
	return (long)TRUE;
}

long CImage::ShowBmpFile(HDC hdc, int nXDest, int nYDest)
{
	if( m_lpBMPFileData == NULL )
	{
		return (long)FALSE;
	}
	
	LPBITMAPINFOHEADER lpBMPInfoHeader=(LPBITMAPINFOHEADER) (m_lpBMPFileData + sizeof(BITMAPFILEHEADER) );
	BITMAPINFO * lpBMPInfo =(BITMAPINFO *) (m_lpBMPFileData + sizeof(BITMAPFILEHEADER) );
	SetDIBitsToDevice(hdc,nXDest,nYDest,lpBMPInfoHeader->biWidth,lpBMPInfoHeader->biHeight,
		0,0,0,lpBMPInfoHeader->biHeight,m_lpBMPFileData+14+40+1024,lpBMPInfo,
		DIB_RGB_COLORS);
	
	return (long)TRUE;
}

void CImage::Clear()
{
	if ( m_lpImgBits )
	{
		delete [] m_lpImgBits;
		m_lpImgBits = NULL;
	}

	if ( m_lpBMPFileData )
	{
		delete [] m_lpBMPFileData;
		m_lpBMPFileData = NULL;
	}

	if ( m_lpnMark )
	{
		delete [] m_lpnMark;
		m_lpnMark = NULL;
	}

	if ( m_lpShowMark )
	{
		delete [] m_lpShowMark;
		m_lpShowMark = NULL;
	}
	
}


HANDLE CImage::Create256DIB(LPBYTE lp8BitImageData)
{
//功能:   将一段已经4字节对齐的数据区(m_lpImgBits)转化为256色灰度的DIB,即填加infoheader和调色板
//Author: wholehope  2002.3.20 修改于3.26

	BITMAPINFOHEADER bi;             //bitmap header
	LPBITMAPINFOHEADER lpbi;         //pointer to bitmap header
	DWORD dwLength;                  //memory block的尺寸大小
	HANDLE hDIB;                     //定义句柄 
	BYTE * pByte;                    //定义数据区域指针
		
	//填充BMPINFOHEADER;
	bi.biSize=sizeof(BITMAPINFOHEADER);
	bi.biWidth=m_lngWidth;
	bi.biHeight=m_lngHeight;
	bi.biPlanes=1;
	bi.biBitCount=8;
	bi.biCompression=BI_RGB;
	bi.biSizeImage=m_ulngBitsCount;
	bi.biXPelsPerMeter=0;
	bi.biYPelsPerMeter=0;
	bi.biClrUsed=256;
	bi.biClrImportant=0;
	
	//计算DIB所需要的空间 BITMAPINFOHEADER + Palette + 数据区
	dwLength=bi.biSize+256*4+bi.biSizeImage;
	
	//分配内存区域: GHND包括 GMEM_MOVEABLE 和 GMEM_ZEROINIT
	// GMEN_MOVEABLE 表示在heap内可以移动 GM_ZROOINIT 表示全部设为0
	hDIB=::GlobalAlloc(GHND,dwLength);
	
	//如果分配内存失败的话,返回NUll
	if ( !hDIB )
		return NULL;

	//lock the mem and get its pointer
	lpbi=(LPBITMAPINFOHEADER)::GlobalLock(hDIB);

	//用我们自己的BITMAPINFOHEADER来填充memory的前面的区域
	*lpbi=bi;
	
	//自己填充调色板
	//指针指向调色板开始区域
	lpbi+=1;
	pByte=(BYTE *)lpbi;

	for( int i = 0;i < 256 * 4; )
	{
		memset(  pByte+ i,i / 4,3 );
		i += 4;
	}

	//填充数据
	pByte+=256*4;
	memcpy(pByte,lp8BitImageData,m_ulngBitsCount);
	
	//unlock DIB内存区 然后返回hDIB
	::GlobalUnlock(hDIB);
		
	return hDIB;
}

HANDLE CImage::CreateShowMarkHandle()
{
	int i,j;

	if ( m_lpnMark==NULL )
	{
		//没有标记过,以后要填加错误处理
		return NULL;
	}

	if ( m_lpShowMark==NULL )
	{
		m_lpShowMark= new BYTE[m_ulngBitsCount];
		ASSERT( m_lpShowMark != NULL );
	}
	::memset(m_lpShowMark,0,m_ulngBitsCount);

	LPBYTE lpShowMarkMove = m_lpShowMark;
	BYTE bStep = 150 / m_nMarkNumbers;

	for ( j=0;j<m_lngHeight;j++ )
	{
		m_lpnMarkMove=m_lpnMark + j*m_lngWidthBytes;	
		lpShowMarkMove=m_lpShowMark + j*m_lngWidthBytes;	
		for ( i=0;i<m_lngWidth;i++ )
		{
			if ( *m_lpnMarkMove != 0 )
			{
				*lpShowMarkMove = 255-(*m_lpnMarkMove-1)*bStep;
			}
			else
			{
				*lpShowMarkMove = 0;
			}

			m_lpnMarkMove++;
			lpShowMarkMove++;
		}
	}

	HANDLE hDIB = Create256DIB( m_lpShowMark );
	return hDIB;
}

long CImage::Show256DIB_vfw(HDC hdc, HANDLE hDIB, int nXDest, int nYDest)
{
//功能:使用vfw函数drawDIBDraw来显示256DIB数据
//参数:1 DC的句柄  2 DIB数据区的HANDLE
//Author: wholehope  2002.6.9 

	if ( hDIB==NULL )
	{
		CString str = "DIB HANDLE无效,无法显示!";
		AfxMessageBox(str);
		return (long)FALSE;
	}

	LPBITMAPINFOHEADER lpBMPinfo = ( LPBITMAPINFOHEADER )::GlobalLock(hDIB);
	HDRAWDIB hdd=::DrawDibOpen();
	::DrawDibDraw(hdd,hdc,nXDest,nYDest,lpBMPinfo->biWidth,lpBMPinfo->biHeight,lpBMPinfo,(LPBYTE)lpBMPinfo+40+1024,0,0,lpBMPinfo->biWidth,lpBMPinfo->biHeight,DDF_BACKGROUNDPAL);
	::DrawDibClose(hdd);
	::GlobalUnlock(hDIB);
	return (long)TRUE;
}

template<typename elemType> void CImage::AttachEqualMark(EqualMark &pEqualMark, 
							  elemType num1, elemType num2, int & pEqualNum, CList< EqualMark,EqualMark > & plEqualMark)
{
/*******************************************************
作用:private 函数,将所选出的等价关系,attach到list上里
参数1 pEqualMark   等价关系 
参数2 num1         新的等价关系 1
参数3 num2         新的等价关系 2
参数4 nEqualNum    等价数组的个数
参数5 plEqualMark  存放等价数组的list
wholehope 2002.4  写
修改记录: (1)  2002.5.23 原来所写会丢失掉部分等价关系,把逻辑改正
判断不等 正确: ( pEqualMark.MarkValue1 != num1
			|| pEqualMark.MarkValue2 != num2 )
		错误: ( pEqualMark.MarkValue1 != num1
			&& pEqualMark.MarkValue2 != num2 )
		(2). 2002.6.20  加入到CImageAnalyze中
********************************************************/
	
	//num1小的情况
	if ( num1 < num2 )
	{
		if ( pEqualMark.MarkValue1 != num1
			|| pEqualMark.MarkValue2 != num2 )
		{
			pEqualMark.MarkValue1=num1;
			pEqualMark.MarkValue2=num2;
			//插入到数组中
			pEqualNum++;
			plEqualMark.AddTail(pEqualMark);
		}
	}
	//num2小的情况
	else   
	{
		if ( pEqualMark.MarkValue2 != num1 
			|| pEqualMark.MarkValue1 != num2 )
		{
			pEqualMark.MarkValue1=num2;
			pEqualMark.MarkValue2=num1;
			//插入到数组中
			pEqualNum++;		
			plEqualMark.AddTail(pEqualMark);
		}
	}

}


long CImage::Save8BitBMPFile(HANDLE hDIB, LPCTSTR strFileName)
{
/*
函数功能:保存 hDIB 所代表的DIB数据存为一个BMP文件
参数:1、DIB数据的句柄 2、所要保存的文件名
*/
	if ( hDIB == NULL )
	{
		CString str = "DIB HANDLE无效,无法保存!";
		AfxMessageBox(str);
		return (long)FALSE;	
	}

	CString strName = strFileName;
	//MFC  CFile类
	CFile bmpFile;
	BOOL bFileOpen=bmpFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite,NULL);
	
	if ( bFileOpen==FALSE )
	{
		CString str = "创建文件失败!";
		AfxMessageBox(str);
		return (long)FALSE;
	}

	BITMAPFILEHEADER bmpFileHeader={
	0x4D42,
	14+40+1024+m_ulngBitsCount,
	0,
	0,
	14+40+1024 };
	
	bmpFile.Write(&bmpFileHeader,14);
	bmpFile.Write(::GlobalLock(hDIB),40+1024+m_ulngBitsCount);
	bmpFile.Close();
	::GlobalUnlock(hDIB);
	
	return (long)TRUE;
}

⌨️ 快捷键说明

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