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

📄 dibdoc.cpp

📁 segmentation sample good luck
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				// Start a blob with this line.

				CBlob *pBlobNew = lineNew.m_pBlob = new CBlob;
				pBlobNew->m_nOpenLines = 1;
				pBlobNew->m_pFirstLine = &lineNew;
				pBlobNew->m_ppLastLine = &(lineNew.m_pNextLineSameBlob);
				pBlobNew->m_nLoops = 0;
			}
		}
linedone:
		if (pLineOld) {
			while (TRUE) {
				// Finish all old lines.
				CBlob *pBlobOld = pLineOld->m_pBlob;
				if (--(pBlobOld->m_nOpenLines) == 0) {
					AddBlob(pBlobOld);
				}
				if (clpviOld == clpviOldEnd) break;
				pLineOld = *clpviOld++;
			}
		}

		// Finally, record the end of the new list as the
		// end of the old list to be.

		clpviOldEnd = clpviNew;
	}

	// At the end, we've got one last raster of lines to finish.

	CLinePointerVector &clpvLast = clpvRaster[nOldLineIndex];
	for (CLinePointerVectorIterator clpvi = clpvLast.begin();
	clpvi != clpviOldEnd;) {
		// Finish all old lines.
		CBlob *pBlobOld = (*clpvi++)->m_pBlob;
		if (--(pBlobOld->m_nOpenLines) == 0) {
			AddBlob(pBlobOld);
		}
	}

	// and finally, segmentation is complete
}

/////////////////////////////////////////////////////////////////////////////
// CDIBDoc - This implements CImageDoc for a device independent bitmap.

IMPLEMENT_DYNCREATE(CDIBDoc, CImageDoc)

//-----------------------------------------------------------------
//
// CDIBDoc::CDIBDoc - constructor
//
//-----------------------------------------------------------------

CDIBDoc::CDIBDoc()
{
	m_pMonochromeBitmap = NULL;
	m_hFileMapping = NULL;
	m_pFile = NULL;
	m_pBMFH = NULL;
	m_pBMI = NULL;
	m_eThresholdMethod = eWhiteBackground;
	m_nThreshold = 128*3;
}

//-----------------------------------------------------------------
//
// CDIBDoc::OnNewDocument - This resets the doc when it gets reused.
//
//-----------------------------------------------------------------

BOOL CDIBDoc::OnNewDocument()
{
	if (! CImageDoc::OnNewDocument()) return FALSE;

	if (m_file.m_hFile != CFile::hFileNull) {
		CloseFile();
		ASSERT(m_file.m_hFile == CFile::hFileNull);
	}
	return TRUE;
}

CDIBDoc::~CDIBDoc()
{
	if (! IsEmpty())
		CloseFile();	
	if (m_pMonochromeBitmap) delete m_pMonochromeBitmap;
}


BEGIN_MESSAGE_MAP(CDIBDoc, CImageDoc)
	//{{AFX_MSG_MAP(CDIBDoc)
	ON_COMMAND(ID_IMAGE_HISTOGRAM, OnImageHistogram)
	ON_UPDATE_COMMAND_UI(ID_IMAGE_HISTOGRAM, OnUpdateImageHistogram)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDIBDoc diagnostics

#ifdef _DEBUG
void CDIBDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CDIBDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDIBDoc commands

//-----------------------------------------------------------------
//
// CDIBDoc::OnOpenDocument - Open a DIB directly. Don't go through
//							 MFC serialize. We map the file into
//							 memory and let its consumers hack it.
//
// lpszPathName - open this file.
//
//-----------------------------------------------------------------

BOOL CDIBDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	if (m_file.m_hFile != CFile::hFileNull) CloseFile();
	
	CFileException e;
	if (! m_file.Open(lpszPathName,CFile::modeRead|CFile::shareDenyWrite,&e)) {
		AfxThrowFileException(e.m_cause,e.m_lOsError,lpszPathName);
	}
	
	m_hFileMapping = CreateFileMapping((HANDLE)(m_file.m_hFile),NULL,PAGE_READONLY,0,0,NULL);
	if (m_hFileMapping == NULL) {
		m_file.Close();
		CFileException::ThrowOsError(GetLastError(),lpszPathName);
	}

	m_pFile = MapViewOfFile(m_hFileMapping,FILE_MAP_READ,0,0,0);
	if (m_pFile == NULL) {
		m_file.Close();
		CFileException::ThrowOsError(GetLastError(),lpszPathName);
	}

	// Here's a bunch of useful pointers.

	m_pBMFH = (BITMAPFILEHEADER *)m_pFile;
	if (m_pBMFH->bfType != 0x4d42) {
		CString csz;
		AfxFormatString1(csz,IDS_FILE_TYPE_ERROR,lpszPathName);
		AfxMessageBox(csz);
		return FALSE;
	}

	m_pBMI = (BITMAPINFO *)(m_pBMFH + 1);
	if (m_pBMI->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) ||
		m_pBMI->bmiHeader.biCompression != BI_RGB ||
		m_pBMI->bmiHeader.biPlanes != 1) {
		CString csz;
		AfxFormatString1(csz,IDS_FILE_FORMAT_NOT_SUPPORTED,lpszPathName);
		AfxMessageBox(csz);
		return FALSE;
	}

	m_pBits = ((char *)(m_pFile)) + m_pBMFH->bfOffBits;

	if (m_pMonochromeBitmap) {
		delete m_pMonochromeBitmap;
		m_pMonochromeBitmap = NULL;
	}

	m_bThresholdTable.SetSize(0);

	switch(m_pBMI->bmiHeader.biBitCount) {
	default: {
		CString csz;
		AfxFormatString1(csz,IDS_FILE_FORMAT_NOT_SUPPORTED,lpszPathName);
		return FALSE;
			 }

	case 1:
		m_nRasterWidthInBytes = (m_pBMI->bmiHeader.biWidth + 7) / 8;
		m_pMonochromeBitmap = new CDIB1MonochromeBitmap;
		break;
	case 4:
		m_nRasterWidthInBytes = (m_pBMI->bmiHeader.biWidth + 1) / 2;
		m_pMonochromeBitmap = new CDIB4MonochromeBitmap;
		if (m_pBMI->bmiHeader.biClrUsed == 0) {
			m_bThresholdTable.SetSize(16);
		} else {
			m_bThresholdTable.SetSize(m_pBMI->bmiHeader.biClrUsed);
		}
		break;
	case 8:
		m_nRasterWidthInBytes = m_pBMI->bmiHeader.biWidth;
		m_pMonochromeBitmap = new CDIB8MonochromeBitmap;
		if (m_pBMI->bmiHeader.biClrUsed == 0) {
			m_bThresholdTable.SetSize(256);
		} else {
			m_bThresholdTable.SetSize(m_pBMI->bmiHeader.biClrUsed);
		}
		break;
#ifdef NOTYET
	case 16:
		m_nRasterWidthInBytes = m_pBMI->bmiHeader.biWidth * 2;
		break;
	case 24:
		m_nRasterWidthInBytes = m_pBMI->bmiHeader.biWidth * 3;
		break;
	case 32:
		m_nRasterWidthInBytes = m_pBMI->bmiHeader.biWidth * 4;
		break;
#endif
	}
	m_pMonochromeBitmap->SetDoc(*this);
	m_nRasterWidthInBytes = ((m_nRasterWidthInBytes + 3) / 4) * 4;

	BuildThresholdTable();
	return TRUE;
}

//-----------------------------------------------------------------
//
// CDIBDoc::CloseFile - Close the file and back out its mapping.
//
//-----------------------------------------------------------------

void CDIBDoc::CloseFile()
{
	if (m_pFile) {
		ASSERT(m_hFileMapping);
		ASSERT(m_file.m_hFile != CFile::hFileNull);
		if (! UnmapViewOfFile(m_pFile)) {
			CFileException::ThrowOsError(GetLastError(),GetPathName());
		}
		m_pFile = NULL;
		m_hFileMapping = NULL;
	}
	m_file.Close();
}

//-----------------------------------------------------------------
//
// CDIBDoc::StretchBlt - Paint a device independent bitmap onto
//					     the given DC
//
// dc - paint onto this device context
// crDest - paint onto this rectangle
// crSrc - paint only the portion in this rect on the DIB
// dwROP - raster operation to use (see BitBlt, for instance)
//
//-----------------------------------------------------------------

void CDIBDoc::StretchBlt(CDC &dc,CRect &crDest, CRect &crSrc,DWORD dwROP)
{
	if (m_file.m_hFile == CFile::hFileNull) return;
	int nBitmapTop = Height() - crSrc.bottom;
	if (::StretchDIBits(dc.m_hDC,
					    crDest.left,
					    crDest.top,
					    crDest.Width(),
					    crDest.Height(),
						crSrc.left,
						nBitmapTop,
						crSrc.Width(),
						crSrc.Height(),
						m_pBits,
						m_pBMI,
						DIB_RGB_COLORS,
						dwROP) == GDI_ERROR) {
		CFileException::ThrowOsError(GetLastError(),NULL);
	}
}

//-----------------------------------------------------------------
//
// CDIBDoc::GetBitmapInfo - return the bitmap info structure for
//							the DIB.
//
//-----------------------------------------------------------------

BITMAPINFO * CDIBDoc::GetBitmapInfo()
{
	ASSERT(m_pBMI);
	return m_pBMI;
}

//-----------------------------------------------------------------
//
// CDIBDoc::GetBitmapBits - Return the pointer to the actual bitmap
//							data.
//
//-----------------------------------------------------------------

LPVOID CDIBDoc::GetBitmapBits()
{
	ASSERT(m_pBits);
	return m_pBits;
}

//-----------------------------------------------------------------
//
// CDIBDoc::GetRasterWidthInBytes - Return the number of bytes
//									needed to map one raster of data.
//
//-----------------------------------------------------------------

int CDIBDoc::GetRasterWidthInBytes()
{
	return m_nRasterWidthInBytes;
}

//-----------------------------------------------------------------
//
// CDIBDoc::GetThresholdTable - The threshold table contains one
//					boolean (TRUE for above threshold/FALSE for below)
//					for each color in the bitmap.
//
//-----------------------------------------------------------------

const CByteArray & CDIBDoc::GetThresholdTable()
{
	return m_bThresholdTable;
}

//-----------------------------------------------------------------
//
// CDIBDoc::GetMonochromeBitmap - return a reference to the monochrome
//					bitmap (used to generically hack an image)
//					that we built for this DIB.
//
//-----------------------------------------------------------------

CMonochromeBitmap &CDIBDoc::GetMonochromeBitmap()
{
	ASSERT(m_pMonochromeBitmap);
	return *m_pMonochromeBitmap;
}

//-----------------------------------------------------------------
//
// BYTE * CDIBDoc - Return a pointer to a raster of bitmap data. Note
//					that these will be in different formats for
//					different bitmap # of bits.
//
// nLine - Y coordinate of raster to fetch.
//-----------------------------------------------------------------

const BYTE * CDIBDoc::GetRaster(int nLine)
{
	ASSERT(m_pBits);
	ASSERT(m_pBMI);
	return ((const BYTE *)m_pBits) + (m_pBMI->bmiHeader.biHeight - nLine - 1) * m_nRasterWidthInBytes;
}

//-----------------------------------------------------------------
//
// CDIBDoc::Width - # of pixels per raster.
//
//-----------------------------------------------------------------

int CDIBDoc::Width()
{
	if (IsEmpty()) return 0;
	return m_pBMI->bmiHeader.biWidth;
}

//-----------------------------------------------------------------
//
// CDIBDoc::Height - # of rasters in bitmap
//
//-----------------------------------------------------------------

int CDIBDoc::Height()
{
	if (IsEmpty()) return 0;
	return m_pBMI->bmiHeader.biHeight;

}

//-----------------------------------------------------------------
//
// CDIBDoc::IsEmpty - returns TRUE if this is the null document.
//
//-----------------------------------------------------------------

BOOL CDIBDoc::IsEmpty()
{
    return (m_file.m_hFile == CFile::hFileNull);
}


//-----------------------------------------------------------------
//
// CDIBDoc::OnImageHistogram - Display a histogram indicating how
//							   many pixels are at each brightness.
//							   The dialog box allows the user to
//							   eyeball the histogram and set the
//							   threshold.
//
//-----------------------------------------------------------------

void CDIBDoc::OnImageHistogram() 
{
	CHistogramDlg dlg;
	vector<int> vBrightness;
	GetMonochromeBitmap().GetBrightnessHistogram(dlg.m_wndHistogram.m_vHistogram,vBrightness);
	for (int i = 0; i < vBrightness.size() && vBrightness[i] < m_nThreshold; i++);

	dlg.m_wndHistogram.m_nBound = i;

	if (dlg.DoModal() == IDOK) {
		m_nThreshold = vBrightness[dlg.m_wndHistogram.m_nBound];
		BuildThresholdTable();
		m_pMonochromeBitmap->ClearBlobList();
		m_pMonochromeBitmap->BuildBlobList();
		UpdateAllViews(NULL);
	}
}

//-----------------------------------------------------------------
//
// CDIBDoc::OnUpdateImageHistogram - Only allow this for non-monochrome
//								bitmaps.
//
//-----------------------------------------------------------------

void CDIBDoc::OnUpdateImageHistogram(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable((! IsEmpty()) && m_pBMI->bmiHeader.biBitCount > 1);	
}

//-----------------------------------------------------------------
//
// CDIBDoc::BuildThresholdTable - Build the boolean table that tells
//								whether a color is above or below
//								threshold.
//
//-----------------------------------------------------------------

void CDIBDoc::BuildThresholdTable()
{
	const RGBQUAD *pRGBQ = m_pBMI->bmiColors;
	for (int i = 0; i < m_bThresholdTable.GetSize(); i++) {
		switch(m_eThresholdMethod) {
		case eBlackBackground:
			if (pRGBQ[i].rgbRed + pRGBQ[i].rgbGreen + pRGBQ[i].rgbBlue > m_nThreshold) {
				m_bThresholdTable[i] =  TRUE;
			} else {
				m_bThresholdTable[i] = FALSE;
			}
			break;
		case eWhiteBackground:
			if (pRGBQ[i].rgbRed + pRGBQ[i].rgbGreen + pRGBQ[i].rgbBlue > m_nThreshold) {
				m_bThresholdTable[i] =  FALSE;
			} else {
				m_bThresholdTable[i] = TRUE;
			}
			break;
		}
	}
}

⌨️ 快捷键说明

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