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

📄 bmp.cpp

📁 打开一个bmp影像
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// BMP.cpp: implementation of the BMP class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BMP.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

BMP::BMP()
{
    m_nHeight    = 0;
	m_nWidth     = 0;
	m_nFileSize  = 0;
	m_nScanWidth = 0;
	m_nColorBits = 0;
	m_pDib       = NULL;
	m_pDibBits   = NULL;
}

BMP::~BMP()
{

	
}

int WIDTHBYTES(int Width)
{
	return ((Width+31)/32*4);
}

BOOL BMP::LoadImage(CString FileName)
{
    /**************
    BITMAPFILEHEADER          |  (14 byte)
	------------------------
  + BITMAPINFOHEADER (40 byte)|
  + Palette          (4  byte)|  BITMAPINFO(44 byte)
	***************/

	int test1 =sizeof(BITMAPINFOHEADER);  //40
	int test2 = sizeof(BITMAPFILEHEADER); //14
	int test3 = sizeof(LOGPALETTE);       //8
	int test4 = sizeof(PALETTEENTRY);     //4
	int test5 = sizeof(RGBQUAD);          //4
	int test7 = sizeof(LOGPALETTE);       ///8
    int test8 = sizeof(BITMAPINFO);      //44
	/******************/
	
	m_sFilePath = FileName;
	CFile file(m_sFilePath,CFile::modeRead);
	m_sFilePath = file.GetFilePath();
	m_sFileName = file.GetFileName();
	m_sFilePath = m_sFilePath.Left(m_sFilePath.GetLength()-m_sFileName.GetLength());
	file.Close();
    
    //创建文件句柄
	HANDLE hFile = ::CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,
		                 OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    ASSERT(hFile != INVALID_HANDLE_VALUE);
	
	
	
	
	//获取文件大小
	m_nFileSize = GetFileSize(hFile,NULL);
	m_pDib = new unsigned char[m_nFileSize];
	ASSERT(m_pDib != NULL);

	//读图像
	unsigned long WriteNum;
	ReadFile(hFile,m_pDib,m_nFileSize,&WriteNum,NULL);
	ASSERT(m_nFileSize == (long)WriteNum);
	CloseHandle(hFile);
/////////////////////////////////////////////////
    //获取图象信息
	/*BITMAPFILEHEADER *pBFH; //图象文件头
	BITMAPINFOHEADER *pBIH; //图象信息头
	unsigned char *pPixel;
	unsigned char *pFirst = m_pDib;
	pBFH = (BITMAPFILEHEADER *)pFirst;
	pFirst += sizeof(BITMAPFILEHEADER);
	pBIH = (BITMAPINFOHEADER *)pFirst;
	pFirst += sizeof(BITMAPINFOHEADER);
	//获取图象的实际象素值
 
	pPixel = pFirst + 256*sizeof(RGBQUAD);
    // pPixel = pFirst;
	BYTE  gray1 =pPixel[0];
	long lWidth = pBIH->biWidth;
	long lHeight = pBIH->biHeight;*/
	
	




//////////////////////////////////////////////
    //获取文件头和文件信息头
	//(1)指针指向文件的头
	unsigned char *pDib = (unsigned char *)m_pDib;  
	BITMAPFILEHEADER *pFileHeader = (BITMAPFILEHEADER * )pDib;
	if(pFileHeader->bfType != 'MB')
	{
		AfxMessageBox("文件类型有误,无法打开,请重新选择");
		return FALSE;
	}
	//(2)指向BITMAPFILEHEADER的末尾
	pDib += sizeof(BITMAPFILEHEADER);

	BITMAPINFOHEADER *pInfoHeader = (BITMAPINFOHEADER * )pDib;
	
	//初始化成员数据
    m_nHeight    = pInfoHeader->biHeight;
	m_nWidth     = pInfoHeader->biWidth ;
	m_nScanWidth = WIDTHBYTES(m_nWidth*pInfoHeader->biBitCount);
	m_nColorBits = pInfoHeader->biBitCount;
	//(3)指向BITMAPINFOHEADER的末尾
	pDib        += sizeof(BITMAPINFOHEADER);
	int ColorNumber = 1<<m_nColorBits;           //图像的颜色数图像的颜色数pow(2,m_nColorBits)
	RGBQUAD *pPaletteInfo = (RGBQUAD*)pDib;
	if( m_Palette.GetSafeHandle() != NULL )     //删除现有的调色板信息
		m_Palette.DeleteObject();

	if( m_nColorBits == 24 )                        //真彩色图像,无调色板
	{
		m_pDibBits = pDib;

		BYTE GRAY1 =  m_pDibBits[0];
		return TRUE;                     //退出函数,不执行席面的操作
	} 
	//否则设置调色板(对于8位)

	LOGPALETTE *pLogPal = (LOGPALETTE *) new char[sizeof(LOGPALETTE)+
		ColorNumber * sizeof(PALETTEENTRY)];
	if( pLogPal != NULL )
	{
		pLogPal->palVersion    = 0x300;
		pLogPal->palNumEntries = ColorNumber;
		for( int i = 0; i < ColorNumber; i++ )
		{
			pLogPal->palPalEntry[i].peRed   = pPaletteInfo[i].rgbRed;					
			pLogPal->palPalEntry[i].peGreen = pPaletteInfo[i].rgbGreen;					
			pLogPal->palPalEntry[i].peBlue  = pPaletteInfo[i].rgbBlue;

			//初始化调色板数组
			m_nPalette[i][0] = pPaletteInfo[i].rgbBlue;
			m_nPalette[i][1] = pPaletteInfo[i].rgbGreen;
			m_nPalette[i][2] = pPaletteInfo[i].rgbRed;
		}
		m_Palette.CreatePalette( pLogPal );
		delete [] pLogPal;
	}
	//(4)指向位图数据(Palette的末尾)
	
	m_pDibBits = pDib + ColorNumber * sizeof(RGBQUAD);

	//BYTE gray = m_pDibBits[0];

    /**************
      m_pDib--> BITMAPFILEHEADER
				----------------------
                BITMAPINFOHEADER
                Palette
				------------------------
  m_pDibBits--> Data

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

	return TRUE;
}

BOOL BMP::SaveImage(CString FileName)
{
    if( m_pDibBits == NULL )
	{
		AfxMessageBox("还没有打开文件,请先载入一幅图像再保存!",0,0);
		return( FALSE );
	}
	HANDLE hFile = ::CreateFile(FileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,
		                 CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hFile == NULL)
	{
		AfxMessageBox("无法创建文件.",0,0);
		CloseHandle(hFile);
		hFile = NULL;
		return FALSE;
	}

	unsigned long WriteNum;
	WriteFile(hFile,m_pDib,m_nFileSize,&WriteNum,NULL);
	if(WriteNum != (unsigned long)m_nFileSize)
		 return FALSE;

	CloseHandle(hFile);
	return TRUE;
	return TRUE;
}

BOOL BMP::Draw(CDC *pDC, int nX, int nY, int nWidth, int nHeight)
{
	if( m_Palette.GetSafeHandle() != NULL )
	{
		// 选择调色板,实现调色板并保存旧的调色板
		CPalette *pOldPalette;
		pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
		pDC->RealizePalette();
		pDC->SelectPalette( pOldPalette, FALSE );
	}
	//调用StrechDibBits绘图
	if( nWidth == -1 )
		nWidth = m_nWidth;
	if( nHeight == -1 )
		nHeight = m_nHeight;
	//使用拉伸模式使彩色图像显示时的彩色效果最好
	::SetStretchBltMode(pDC->m_hDC, COLORONCOLOR);
	StretchDIBits( pDC->m_hDC, nX, nY, nWidth, nHeight, 0, 0,		         	           	
		           m_nWidth, m_nHeight, m_pDibBits,
		           (BITMAPINFO *)(m_pDib + sizeof(BITMAPFILEHEADER)),		
		           BI_RGB, SRCCOPY );	
	return TRUE;

}

int BMP::GetImageWidth()
{
  return m_nWidth;
}

int BMP::GetImageHeight()
{
  return m_nHeight;
}


int BMP::GetImageBits()
{
   return m_nColorBits;
}

BOOL BMP::GetPixel(int i, int j, COLORREF &Value)
{
   if( (i < 0)||(i>=m_nHeight)||(j<0)||(j>=m_nWidth) )
		return FALSE;
	if(m_nColorBits == 24)
	{
		BYTE *pData = m_pDibBits + (m_nHeight-1-i)*m_nScanWidth + j*3;
		Value = RGB(pData[2], pData[1], pData[0]);
	}
	else if( m_nColorBits == 8 )
	{
		BYTE *pData = m_pDibBits + (m_nHeight-1-i)*m_nScanWidth + j;
		Value = RGB( *pData, *pData, *pData );
	}
	return TRUE;
}

BOOL BMP::SetPixel(int i, int j, COLORREF Value)
{
   	if( (i < 0)||(i>=m_nHeight)||(j<0)||(j>=m_nWidth) )
		return FALSE;
	if( m_nColorBits == 24 )
	{
		 BYTE *pData = m_pDibBits + (m_nHeight-1-i)*m_nScanWidth + j*3;
		 pData[0] = GetBValue(Value);
		 pData[1] = GetGValue(Value);
		 pData[2] = GetRValue(Value);
	}
	else if( m_nColorBits == 8 )
	{
		BYTE *pData = m_pDibBits + (m_nHeight-1-i)*m_nScanWidth + j;
		*pData = GetBValue(Value);
	}
	return TRUE;
}

CString BMP::GetFileName()
{
   	return m_sFileName;
}

CString BMP::GetFilePath()
{
  	return m_sFilePath;
}



int BMP::ConvolutionPixel8(int i, int j, int Values[][9], int nSize, int Division, int Offset)
{
    int gray = 0;
	int cof=0; int size=0;
	for(int m=0;m<nSize;m++)
	{
		for(int n=0;n<nSize;n++)
		{
			COLORREF c;
			if(GetPixel(i-nSize/2+m,j-nSize/2+n,c))
			{
				gray += (Values[m][n] *GetBValue(c));
				cof += Values[m][n];
				size ++;
			}
		}//end n
	}//end m
	if(cof <0)  //如果系数小于0,取原值
	{ 
		COLORREF c;
		GetPixel(i,j,c);
		gray =GetBValue(c);
	}
	else if(size <nSize*nSize)
	{
		if(cof == 0) cof =1;
		gray = min(gray/cof +Offset,255);
	}
	else gray = min(gray/Division + Offset,255);
	//把变换的结果保存到新建的数组中
	gray = max(0,gray);
    return gray;
}


float BMP::ConvolutionPixel8f(int i, int j, int Values[][9], int nSize, int Division, int Offset)
{
	float gray = 0;
	float cof=0; int size=0;
	for(int m=0;m<nSize;m++)
	{
		for(int n=0;n<nSize;n++)
		{
			COLORREF c;
			if(GetPixel(i-nSize/2+m,j-nSize/2+n,c))
			{
				gray += (Values[m][n] *GetBValue(c));
				cof += Values[m][n];
				size ++;
			}
		}//end n
	}//end m
	if(cof <0)  //如果系数小于0,取原值
	{ 
		COLORREF c;
		GetPixel(i,j,c);
		gray = GetBValue(c);
	}
	else if(size <nSize*nSize)
	{
		if(cof == 0) cof =1;
		gray = (float)(gray/cof +Offset);
	}
	else gray = float(gray/(float)Division + Offset);
	//把变换的结果保存到新建的数组中
    return gray;

}
void BMP::ConvertDIB8(int Values[][9], int nSize, int Division, int Offset)
{
   	int Width    =  GetImageWidth();
	int Height   =  GetImageHeight();
	int ColorBits = GetImageBits();
	int WidthBytes = WIDTHBYTES(Width*ColorBits);
	//开辟与图象同样大小的数组,用于保存图象结果
	unsigned char *pDibBits = new unsigned char[WidthBytes*Height];
	for(int i = 0 ;i < Height; i++)
	{
		for(int j = 0;j < Width; j++)
		{
			//计算第i行,第j列象素的新值
			int gray = ConvolutionPixel8(i,j,Values,nSize,Division,Offset);
			BYTE *pData = pDibBits + (Height-i-1)*WidthBytes+j;
			*pData = gray;
		}
	}
	//赋值
	for(i=0;i<Height*WidthBytes;i++)

⌨️ 快捷键说明

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