📄 image.cpp
字号:
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 + -