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

📄 image.cpp

📁 医学图象处理系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:

//***********************************************************
BOOL CImage::SaveImageToFile(LPCTSTR lpszFileName)
{
    if(m_lpDibArray==NULL) return FALSE;
    CFile * pWriteFile = NULL;
    TRY {pWriteFile = new CFile( lpszFileName, CFile::modeCreate | CFile::modeWrite); }
    CATCH( CFileException, e )
    {
        AfxMessageBox(" 文件错误");
		if(pWriteFile != NULL)
		{
			pWriteFile->Close(); delete pWriteFile;  pWriteFile = NULL;
		}
        THROW_LAST();
    }
    END_CATCH

	BOOL    result = false;
    CString FileName(lpszFileName);
    if(FileName.Right(3) == "img" || FileName.Right(3) == "IMG")
    {
        result = SaveImageAsIMG( pWriteFile );
    }
    else if(FileName.Right(3) == "bmp" || FileName.Right(3) == "BMP")
    {    
        result = SaveImageAsBMP( pWriteFile );
    }
	
    if( pWriteFile != NULL )
	{
		pWriteFile->Close(); delete pWriteFile;  pWriteFile = NULL;
	}

    return true;
}

//***********************************************************

//***********************************************************
BOOL CImage::ReadImageAsBMP(CFile * pReadFile)
{
    pReadFile->SeekToBegin();          // Set the file pointer to the begin of the file

    //Check if the file header is "BM"
	if ((pReadFile->Read((LPSTR)&m_bmfHeader, sizeof(BITMAPFILEHEADER)) !=
		 sizeof(BITMAPFILEHEADER)) || (m_bmfHeader.bfType != DIB_HEADER_MARKER))    
    {
        AfxMessageBox("您所指定的不是一个BMP文件!");
        return FALSE;
    }  
    BITMAPINFOHEADER    bmiHeader;
	pReadFile->Read((LPSTR)&bmiHeader, sizeof(BITMAPINFOHEADER));
    
    m_ImageWidth     = bmiHeader.biWidth;	
    m_ImageHeight    = abs(bmiHeader.biHeight);
	m_wImageDepth    = bmiHeader.biBitCount;
    m_nDibWidth      = (m_ImageWidth* m_wImageDepth/ 8 + 3) & ~3;
    m_nDibHeight     = m_ImageHeight;
	m_ImageSize      = m_nDibWidth * m_nDibHeight;
    m_wColorMapNum   = GetColorMapNum(m_wImageDepth);
    m_HSIImageWidth  = (m_ImageWidth + 3) & ~3;
	m_HSIImageHeight = m_ImageHeight;
	
	if(bmiHeader.biCompression != BI_BITFIELDS&&bmiHeader.biCompression != BI_RGB)
	{
		AfxMessageBox("不支持RLE4 or RLE8 压缩格式");
		return FALSE;
	}
	if(bmiHeader.biCompression == BI_BITFIELDS&&(m_bmfHeader.bfOffBits-54)==12)
		AllocateMemory(TRUE);
	else
		AllocateMemory(); 

	if(m_lpDibInfo!=NULL) //create the bitmap info     
	{
		m_lpDibInfo->bmiHeader = bmiHeader;

		if(m_wImageDepth<=8&&m_wColorMapNum>0)
			pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors, m_wColorMapNum* sizeof(RGBQUAD));
		BakupColorIndex();
	}
	GenerateRowAddress();

	m_IsExistRGBMask = m_Is565RGBImage = FALSE;
	if(m_wImageDepth==16)
	{
		m_dwBBitMask    = 0x1F;
		m_dwGBitMask    = 0x3E0;
		m_dwRBitMask    = 0x7C00; 
		m_wlowRedBit    = 10;	
		m_wlowGreenBit  = 5;	
		m_wlowBlueBit   = 0;
		m_wNumRedBits   = 5; 	
		m_wNumGreenBits = 5;
		m_wNumBlueBits  = 5;	
		
		if(bmiHeader.biCompression == BI_BITFIELDS && (m_bmfHeader.bfOffBits-54)==12)
		{
			pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors, 12);
			m_IsExistRGBMask = true;
			DWORD *Mask  =  (DWORD *)m_lpDibInfo->bmiColors;
			m_dwRBitMask = Mask[0];
			m_dwGBitMask = Mask[1];
			m_dwBBitMask = Mask[2];
			if(m_dwGBitMask != 0x3E0 )
			{
				m_Is565RGBImage = TRUE;
				m_wlowRedBit    = 11;
				m_wNumGreenBits = 6;
			}			 
		}
	}
	else if(m_wImageDepth==32)
	{
		m_dwBBitMask    = 0xFF;
		m_dwGBitMask    = 0xFF00;
		m_dwRBitMask    = 0xFF0000; 
		m_wlowRedBit    = 16;	
		m_wlowGreenBit  = 8;	
		m_wlowBlueBit   = 0;
		m_wNumRedBits   = 8; 	
		m_wNumGreenBits = 8;
		m_wNumBlueBits  = 8;	

		if(bmiHeader.biCompression == BI_BITFIELDS && (m_bmfHeader.bfOffBits-54)==12)
		{
			pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors,12);
			m_IsExistRGBMask = TRUE;
			DWORD *Mask  =  (DWORD *)m_lpDibInfo->bmiColors;
			m_dwBBitMask = Mask[0];
			m_dwGBitMask = Mask[1];
			m_dwRBitMask = Mask[2];			 
		}
	}
	
	pReadFile->Seek(m_bmfHeader.bfOffBits, CFile::begin);
	if(m_lpDibArray!=NULL)
	{
		TRY	{ pReadFile->ReadHuge(m_lpDibArray, m_ImageSize); }
		CATCH(CFileException, e)
		{
			AfxMessageBox("读文件错误");
			THROW_LAST();
		}	  	                  
		END_CATCH
	}		
    return true;
}
//***********************************************************

//***********************************************************
BOOL CImage::SaveImageAsBMP(CFile * pSaveFile)
{
    if( pSaveFile == NULL||m_lpDibArray==NULL )
    {
        AfxMessageBox("文件类指针或图像数据错误!");
        return FALSE;
    } 
	m_bmfHeader.bfType      = DIB_HEADER_MARKER;
	m_bmfHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) +
							  m_lpDibInfo->bmiHeader.biSize +
							  m_wColorMapNum * sizeof(RGBQUAD);
	m_bmfHeader.bfSize      = m_bmfHeader.bfOffBits + m_ImageSize;
	m_bmfHeader.bfReserved1 = 0;
	m_bmfHeader.bfReserved2 = 0;
	TRY
	{   // Write the file header
		pSaveFile->Write( (LPSTR)&m_bmfHeader, sizeof(BITMAPFILEHEADER));
		// write bmp info header.
	    pSaveFile->Write( (LPSTR)&(m_lpDibInfo->bmiHeader), sizeof(BITMAPINFOHEADER));
        //Write palette info
		if(m_wColorMapNum)
			pSaveFile->Write( (LPSTR)m_lpDibInfo->bmiColors, m_wColorMapNum*sizeof(RGBQUAD));
		else if(m_IsExistRGBMask)
			pSaveFile->Write( (LPSTR)m_lpDibInfo->bmiColors, 3*sizeof(RGBQUAD)); 
		// Write the DIB  bits
		pSaveFile->WriteHuge(m_lpDibArray, m_ImageSize);
	}
	CATCH (CFileException, e)
	{
        AfxMessageBox(" 存文件时出错");
		THROW_LAST();
	}
	END_CATCH

	return TRUE;
}
//***********************************************************

//***********************************************************
BOOL CImage::ReadImageAsIMG(CFile * pReadFile)
{
	//get length of DIB in bytes for use when reading
	DWORD  dwBitsSize = pReadFile->GetLength();
    double multi=sqrt(dwBitsSize)/IMG_FORMAT_BASE_LENGTH;

	m_ImageWidth    = IMG_FORMAT_BASE_LENGTH*int(multi);
    m_ImageHeight   = dwBitsSize / m_ImageWidth;

	if( dwBitsSize % m_ImageWidth  )
	{
		AfxMessageBox(" Not IMG format or file error");
		return FALSE;                              
	}
    
	m_wImageDepth   = 8;
	m_wColorMapNum  = GetColorMapNum(m_wImageDepth);
	m_nDibWidth     = (m_ImageWidth* m_wImageDepth/ 8 + 3) & ~3;
	m_nDibHeight    = m_ImageHeight;
	m_ImageSize     = m_nDibWidth * m_nDibHeight;
	
	AllocateMemory();
    InitGrayImageInfo();
	GenerateRowAddress();
	
    TRY //Go read the bits.
    {                     
  	    pReadFile->ReadHuge(m_lpDibArray, dwBitsSize);
    }
    CATCH(CFileException, e)
    {
        AfxMessageBox("读文件错误");
        THROW_LAST();
	}	  	                  
	END_CATCH

	return TRUE;
}
//***********************************************************

//***********************************************************
BOOL CImage::SaveImageAsIMG(CFile * pSaveFile)
{	
    if( pSaveFile == NULL||m_lpDibArray==NULL )//Check if the file pointer is valid
    {
        AfxMessageBox("文件类指针或图像数据错误!");
        return FALSE;
    } 
    
	TRY
	{	// Write the IMG  bits
		pSaveFile->WriteHuge(m_lpDibArray, m_ImageSize);
	}
	CATCH (CFileException, e)
	{
        AfxMessageBox(" 存文件时出错");
		THROW_LAST();
	}
	END_CATCH

	return TRUE;
}
//***********************************************************

//***********************************************************
BOOL CImage::ShowCurrentImage(CDC *pMpDc,CRect ShowRect)
{
	BOOL   bSuccess=FALSE;      // Success or fail flag	
	// Check for valid image data*
	if( m_lpDibArray == NULL)        
		return  bSuccess;  
	UINT Mode;
	if(m_lpDibInfo->bmiHeader.biCompression == BI_RGB)
		Mode = DIB_RGB_COLORS;
	else if(m_lpDibInfo->bmiHeader.biCompression == BI_BITFIELDS)
		Mode = DIB_PAL_COLORS;
	// Make sure to use the stretching mode best for color pictures 
	pMpDc->SetStretchBltMode(COLORONCOLOR);
    
	BOOL Show1to1 = fabs(m_fScale - 1.0)<0.05 &&
		            abs(ShowRect.Width() - m_ImageWidth)<5 &&
					abs(ShowRect.Height() - m_ImageHeight)<5;//*/
    if(Show1to1)
	{
  		bSuccess = ::SetDIBitsToDevice(pMpDc->m_hDC,       // hDC
  									   ShowRect.left,	   //DestX
  									   ShowRect.top,	   //DestY
  									   (int)m_ImageWidth,  //最好是图像的宽度
									   (int)m_ImageHeight, //最好是图像的高度
									   0,                  //SrcX
									   0,                  //SrcY
									   0,                  //nStartScan
									   (int)m_nDibHeight,  //nNumScans
									   m_lpDibArray,       //lpBits
									   m_lpDibInfo,		   //lpBitsInfo
									   Mode);    //wUsage //*/
	}
	else
	{
		double tmpscalex = ShowRect.Width()/(double)m_ImageWidth;
		double tmpscaley = ShowRect.Height()/(double)m_ImageHeight;
		if(tmpscalex<tmpscaley)
		{
			m_fScale = tmpscalex;
			ShowRect.bottom = ShowRect.top  + int(m_fScale*m_ImageHeight + 0.5);
		}
		else
		{
			m_fScale = tmpscaley;
			ShowRect.right  = ShowRect.left + int(m_fScale*m_ImageWidth  + 0.5);
		}		
		bSuccess = ::StretchDIBits(pMpDc->m_hDC,           // hDC
								   ShowRect.left,          // DestX
								   ShowRect.top,           // DestY
								   ShowRect.Width(),	   // nDestWidth
								   ShowRect.Height(),	   // nDestHeight
								   0,	  	               // SrcX
								   0,                      // SrcY
								   (int)m_ImageWidth,      // wSrcWidth
								   (int)m_ImageHeight,     // wSrcHeight
								   m_lpDibArray,           // lpBits
								   m_lpDibInfo,            // lpBitsInfo
								   Mode,         // wUsage
								   SRCCOPY);               // dwROP//*/
	}
	return bSuccess;
}  
BOOL CImage::ShowCurrentImage(CDC *pMpDc,CPoint LTp, CPoint RBp)
{
	return ShowCurrentImage( pMpDc, CRect(LTp,RBp) );
}
BOOL CImage::ShowCurrentImage(CDC *pMpDc,int x1, int y1, int x2, int y2)
{
	return ShowCurrentImage( pMpDc, CRect(x1,y1,x2,y2) );
}
//***********************************************************

//***********************************************************
BOOL CImage::ShowPartialImage(CDC *pMpDc,CRect ShowRect,CPoint LTp,CPoint RBp, BOOL Is1to1)
{
#ifdef _DEBUG
	if(!CheckRect(LTp,RBp)||m_lpDibArray == NULL)
	{
		AfxMessageBox("下标越界!!!");
		AfxAbort();
	}
#endif  
	BOOL   bSuccess=FALSE;      // Success/fail flag	
	// Make sure to use the stretching mode best for color pictures 
	pMpDc->SetStretchBltMode(COLORONCOLOR);

    int width   = RBp.x - LTp.x + 1;
    int height  = RBp.y - LTp.y + 1;
	if(Is1to1)
	{
		bSuccess = ::SetDIBitsToDevice(pMpDc->m_hDC,       // hDC
  									   ShowRect.left,		   // DestX
									   ShowRect.top,		   // DestY
								       ShowRect.Width(),	   // nDestWidth
								       ShowRect.Height(),	   // nDestHeight
									   LTp.x,                  //SrcX
									   m_nDibHeight - RBp.y -1,   //SrcY
									   0,                       //nStartScan
									   (int)m_nDibHeight- RBp.y - 1 + height,  //nNumScans
									   m_lpDibArray,       //lpBits
									   m_lpDibInfo,		   //lpBitsInfo
									   DIB_RGB_COLORS);    //wUsage //*/
	}
	else
	{
  		bSuccess = ::StretchDIBits(pMpDc->m_hDC,           // hDC
								   ShowRect.left,		   // DestX
								   ShowRect.top,		   // DestY
								   ShowRect.Width(),	   // nDestWidth
								   ShowRect.Height(),	   // nDestHeight
								   LTp.x,		           // SrcX
								   m_ImageHeight - RBp.y -1,// SrcY
								   width,                  // wSrcWidth
								   height,                 // wSrcHeight
								   m_lpDibArray,           // lpBits
								   m_lpDibInfo,            // lpBitsInfo
								   DIB_RGB_COLORS,         // wUsage
								   SRCCOPY);               // dwROP	
	}
    return bSuccess;
}
//***********************************************************

//***********************************************************
void CImage::SelectChannel(DWORD channel)
{
#ifdef _DEBUG
	if(m_lpDibArray     == NULL)  
	{
		AfxMessageBox("下标越界!!!");
		AfxAbort();
	}
#endif
	static BOOL HaveShowChannel = FALSE; // 是否已经显示过单色分量图
	if(!HaveShowChannel)
	{
		BackUp();
		HaveShowChannel=true;
	}
	else
	{
		ImgSwap();
		BackUp();
	}
    
	switch(channel)
	{
	    case  REDCOMPONENT: 
		{
			if( m_wImageDepth == 24 )
			{
				for(int j= 0; j< m_ImageHeight; j++)
				{
					RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
					for(int i= 0; i< m_ImageWidth; i++)
					{
						pixptr[i].rgbtGreen = pixptr[i].rgbtRed;
						pixptr[i].rgbtBlue  = pixptr[i].rgbtRed;
					}
				}
			}	
			break;
		}
		case  GREENCOMPONENT:
		{
			if( m_wImageDepth == 24 )
			{
				for(int j= 0; j< m_ImageHeight; j++)
				{
					RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
					for(int i= 0; i< m_ImageWidth; i++)
					{
						pixptr[i].rgbtRed  = pixptr[i].rgbtGreen;
						pixptr[i].rgbtBlue = pixptr[i].rgbtGreen;
					}
				}
			}	
			break;
		}
		case  BLUECOMPONENT: 
		{
			if( m_wImageDepth == 24)
			{
				for(int j= 0; j< m_ImageHeight; j++)
				{
					RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
					for(int i= 0; i< m_ImageWidth; i++)
					{
						pixptr[i].rgbtGreen = pixptr[i].rgbtBlue;
						pixptr[i].rgbtRed   = pixptr[i].rgbtBlue;
					}
				}
			}	
			break;
		}
		case  REDCOMPONENT | GREENCOMPONENT: 
		{
			if( m_wImageDepth == 24 )
			{
				for(int j= 0; j< m_ImageHeight; j++)
				{
					RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
					for(int i= 0; i< m_ImageWidth; i++)
					{
						pixptr[i].rgbtBlue  = 0;
					} 
				}
			}	
			break;
		}
		case  GREENCOMPONENT | BLUECOMPONENT:
		{
			if( m_wImageDepth == 24)
			{
				for(int j= 0; j< m_ImageHeight; j++)
				{
					RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
					for(int i= 0; i< m_ImageWidth; i++)
					{
						pixptr[i].rgbtRed =0 ;
					}

⌨️ 快捷键说明

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