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