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

📄 bmp.cpp

📁 打开一个bmp影像
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		m_pDibBits[i] = pDibBits[i];
	}
	delete []pDibBits;


}

COLORREF BMP::ConvolutionPixel24(int i, int j, int Values[][9], int nSize, int Division, int Offset)
{
	int red = 0; int green =0; int blue =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))
			{
				int bb =  GetBValue(c);
				int gg =  GetGValue(c);
				int rr =  GetRValue(c);
				blue  += (Values[m][n] * GetBValue(c));
				green += (Values[m][n] * GetGValue(c));
				red   += (Values[m][n] * GetRValue(c));
				cof   += Values[m][n];
				size ++;
			}
		}//end n
	}//end m
	if(cof <0)  //如果系数小于0,取原值
	{ 
		COLORREF c;
		GetPixel(i,j,c);
		blue  = GetBValue(c);
		green = GetGValue(c);
		red   = GetRValue(c);
	}
	else if(size<nSize*nSize) //如果参与卷积运算的像素数比模板小,模板系数设置为cof
	{
		if(cof == 0) cof = 1;
		blue  = min(blue/cof +Offset,255);
		green = min(green/cof +Offset,255);
		red   = min(red/cof +Offset,255);
	}
	else 
	{
		blue  = max(0,min(blue/Division + Offset,255));
		green = max(0,min(green/Division +Offset,255));
		red   = max(0,min(red/Division +Offset,255));
	}
	//返回变换的结果
   return RGB(red,green,blue);
}
void BMP::ConvertDIB24(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列象素的新值
            COLORREF c = ConvolutionPixel24(i,j,Values,nSize,Division,Offset);
	        BYTE *pData = pDibBits + (Height-i-1)*WidthBytes+j*3;
			pData[0]    = GetBValue(c);
			pData[1]    = GetGValue(c);
			pData[2]    = GetRValue(c);
		}
	}
	//赋值
	for(i=0; i<Height*WidthBytes;i++)
	{
		m_pDibBits[i] = pDibBits[i];
	}
	delete []pDibBits;
}

void BMP::DeleteContents()
{
	if(m_pDib != NULL)
		delete []m_pDib;
	m_nHeight    = 0;
	m_nWidth     = 0;
	m_nFileSize  = 0;
	m_nScanWidth = 0;
	m_nColorBits = 0;
	m_pDib       = NULL;
	m_pDibBits   = NULL;

}

void BMP::UserDefinedFilter(int Values[][9], int TempSize, int Division, int Offset)
{
   if(m_pDibBits == NULL)
	{
		AfxMessageBox("Can't Get Image Data,Please reload the image again!",0,0);
		return ;
	}
	if(GetImageBits() == 8)
	{
		ConvertDIB8(Values,TempSize,Division,Offset);
	}
	else if(GetImageBits() == 24)
	{
		ConvertDIB24(Values,TempSize,Division,Offset);
	}
}

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

	int test1 =sizeof(BITMAPINFOHEADER);
	int test2 = sizeof(BITMAPFILEHEADER);
	int test3 = sizeof(LOGPALETTE);
	int test4 = sizeof(PALETTEENTRY);
	int test5 = sizeof(RGBQUAD);
	int test7 = sizeof(LOGPALETTE);
    int test8 = sizeof(BITMAPINFO);
	/******************/
	
	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);

   	HANDLE	hMap= ::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); 
	
	if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) 
	{
		CloseHandle(hMap); 
        hMap = NULL;
		return  FALSE;
	}

	//读图像
	unsigned long WriteNum;
	ReadFile(hFile,m_pDib,m_nFileSize,&WriteNum,NULL);
	ASSERT(m_nFileSize == (long)WriteNum);
	CloseHandle(hFile);

    //获取文件头和文件信息头
	//(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;
		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);


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

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

	return TRUE;
}

/*WriteFile(hDestFile,&bmfDest,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);	
	WriteFile(hDestFile,&bmiDest,sizeof(BITMAPINFOHEADER),&dwWrite,NULL);

	RGBQUAD* bmiColor = new RGBQUAD[256];
	if(bmiColor==NULL)
		return FALSE;
	for(int k=0;k<256;k++)
	{
		bmiColor[k].rgbBlue = k;
		bmiColor[k].rgbGreen = k;
		bmiColor[k].rgbRed = k;
		bmiColor[k].rgbReserved = 0;
	}
	//write palette
	WriteFile(hDestFile,bmiColor,1024,&dwWrite,NULL); */

BOOL BMP::CreateBmp(int nWidth,int nHeight,int nCount,CString CPath)
{

	//设置合成图象的文件信息头
	unsigned long WriteNum;
    BITMAPFILEHEADER BFH;
	BITMAPINFOHEADER BIH;
	int WidthBytes;
	if( nCount == 8)
		WidthBytes= WIDTHBYTES(nWidth*8);
	if(nCount ==24)
		WidthBytes = WIDTHBYTES(nWidth*24); 
	BFH.bfType      = 'MB';
	BFH.bfSize      = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) 
		+ WidthBytes * nHeight;
	BFH.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	BFH.bfReserved1 = BFH.bfReserved2 = 0;
	//图象信息头
	BIH.biSize          = sizeof(BITMAPINFOHEADER);//40 ;
	BIH.biWidth         = nWidth ;
	BIH.biHeight        = nHeight;
	BIH.biPlanes        = 1;
	BIH.biBitCount      = nCount;
	BIH.biCompression   = 0;
	BIH.biSizeImage     = WidthBytes * nHeight;
	BIH.biXPelsPerMeter = 0;
	BIH.biYPelsPerMeter = 0;
	BIH.biClrUsed       = 0;
	BIH.biClrImportant  = 0;
	
	//创建文件
	HANDLE hNewFile = ::CreateFile(CPath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,
		CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hNewFile == NULL)
	{
		AfxMessageBox("Could not create file.",0,0);
		CloseHandle(hNewFile);
		return FALSE;
	}
	
	//写入文件信息头
	WriteFile(hNewFile, &BFH, sizeof(BITMAPFILEHEADER), &WriteNum, NULL);
	WriteFile(hNewFile, &BIH, sizeof(BITMAPINFOHEADER), &WriteNum, NULL);
    
	unsigned char *pDibBits;
	if( nCount == 24)
	{
        pDibBits = new unsigned char[BIH.biHeight * WidthBytes];
		/******************/
		//写象素
		memset(pDibBits,255,BIH.biHeight * WidthBytes);
		/******************/
		
		//写入文件
		WriteFile(hNewFile, pDibBits, WidthBytes*BIH.biHeight, &WriteNum, NULL);
		ASSERT(WriteNum = WidthBytes * BIH.biHeight);
		CloseHandle(hNewFile);
		delete pDibBits;
		return TRUE;
	}


	///////////////////对于灰度影像	
	RGBQUAD* bmiColor = new RGBQUAD[256];
	if(bmiColor==NULL)
		return FALSE;
	for(int k=0;k<256;k++)
	{
		bmiColor[k].rgbBlue = k;
		bmiColor[k].rgbGreen = k;
		bmiColor[k].rgbRed = k;
		bmiColor[k].rgbReserved = 0;
	}
	//write palette
	WriteFile(hNewFile,bmiColor,1024,&WriteNum,NULL);
	
	
	pDibBits = new unsigned char[BIH.biHeight * WidthBytes];
	/******************/
	//写象素
	memset(pDibBits,255,BIH.biHeight * WidthBytes);
	/******************/
	
	//写入文件
	WriteFile(hNewFile, pDibBits, WidthBytes*BIH.biHeight, &WriteNum, NULL);
	ASSERT(WriteNum = WidthBytes * BIH.biHeight);
	CloseHandle(hNewFile);
	delete pDibBits;
    return TRUE;

}


BOOL BMP::LinerTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, FLOAT fA, FLOAT fB)
{
  	unsigned char*	lpSrc;
	LONG	i;
	LONG	j;
   	LONG	lLineBytes;
  	FLOAT	fTemp;
    lLineBytes = WIDTHBYTES(lWidth * 8);
    for(i = 0; i < lHeight; i++)
	{
		for(j = 0; j < lWidth; j++)
		{
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
		
			fTemp = fA * (*lpSrc) + fB;
			
			
			if (fTemp > 255)
			{
				
				*lpSrc = 255;
			}
			else if (fTemp < 0)
			{
				
				*lpSrc = 0;
			}
			else
			{
			
				*lpSrc = (unsigned char) (fTemp + 0.5);
			}
		}
	}
	
	
	return TRUE;
}

⌨️ 快捷键说明

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