问题:现在想直接对内存BMP进行直接处理,而我后面处理部分开始做的时候是针对BMP图片做的,通过打开文件然后来做的处理,现在不知道怎么把他给改成针对内存BMP直接处理,还请大家帮帮忙,在线等,分数不够可以在加。比较的急。
最好是有源程序。拜托了!!!
传过来的是4个参数 UBYTE* pBmpBuf , long DataLeng ,long width ,long height
最好是有源程序。拜托了!!!
传过来的是4个参数 UBYTE* pBmpBuf , long DataLeng ,long width ,long height
CFileDialog dlgFile(true,
_T(".BMP|.JPEG|.PNG"),
NULL,
4|2,
_T("位图格式(*.bmp)|*.bmp|;JPEG格式(*.jpg)|*.jpg|;PNG格式(*.png)|*.png||"),
NULL);
//显示打开文件对话框
if(dlgFile.DoModal() == IDOK)
{
CString fileExt = dlgFile.GetFileExt();//获得文件的扩展名
CString fileName = dlgFile.GetFileName();//获得文件名
CString fileFullPath = dlgFile.GetPathName();//获得文件的全称路径
BITMAPFILEHEADER bmpBackFileHeader;//位图文件头
int nColorEntries; //颜色表项的个数
//读取图形文件
CFile file;
if(file.Open(fileFullPath,CFile::modeRead | CFile::shareDenyWrite))
{
//读取文件头
if(file.Read ( &bmpBackFileHeader, sizeof (BITMAPFILEHEADER)) != sizeof (BITMAPFILEHEADER))
{
MessageBox(_T("读取位图文件头失败!"));
} if(m_lpBMPBackInfoHeader != NULL)
{
delete[] m_lpBMPBackInfoHeader;
m_lpBMPBackInfoHeader=NULL;
} //读取文件信息头和颜色表
int nBmpInfoHeaderSize = bmpBackFileHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
m_lpBMPBackInfoHeader = (LPBITMAPINFOHEADER)new BYTE[nBmpInfoHeaderSize];
if (file.Read( m_lpBMPBackInfoHeader, nBmpInfoHeaderSize) != nBmpInfoHeaderSize)
{
MessageBox(_T("读取位图文件信息头失败!"));
} //根据象素字节数计算逻辑调色板项数
LPVOID lpvColorTable = m_lpBMPBackInfoHeader + sizeof (BITMAPINFOHEADER);//颜色表信息
switch (m_lpBMPBackInfoHeader->biBitCount)
{
case 1:
nColorEntries=2;
break;
case 4:
nColorEntries=16;
break;
case 8:
nColorEntries=256;
break;
case 16:
case 24:
case 32:
nColorEntries=0;
break;
default:
ASSERT(FALSE);
} LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD)
+ nColorEntries * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = nColorEntries;
LPRGBQUAD pDibRGBquad = (LPRGBQUAD) lpvColorTable;
for(int i = 0; i < nColorEntries; i++)
{
pLogPal->palPalEntry[i].peRed = pDibRGBquad->rgbRed;
pLogPal->palPalEntry[i].peGreen =pDibRGBquad->rgbGreen;
pLogPal->palPalEntry[i].peBlue =pDibRGBquad->rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
pDibRGBquad++;
} m_hBackPalette = ::CreatePalette(pLogPal); //调色板
delete pLogPal;
//成功打开新背景图片后,释放上次背景图片内存空间
if(dataAreaBack != NULL)
{
delete[] dataAreaBack;
dataAreaBack = NULL;
} m_widthBack = m_lpBMPBackInfoHeader->biWidth;//位图宽
m_heightBack = m_lpBMPBackInfoHeader->biHeight;//位图高
//m_widthBackDisplay = m_widthBack;//显示宽度
//m_heightBackDisplay = m_heightBack;//显示高度
int m_bitPerPixelBack = m_lpBMPBackInfoHeader->biBitCount;//位图像素深度 int m_destBackWidthByte = (m_widthBack * m_bitPerPixelBack + 7) / 8;//位图宽度为4的倍数,计算其行的字节数
dataAreaBack = new BYTE[m_destBackWidthByte * m_heightBack];//开辟空间存储图像实际数据
file.Read(dataAreaBack, m_destBackWidthByte * m_heightBack);//读取图像数据
int widthBack = 2 * m_lpBMPBackInfoHeader->biWidth;//位图宽
int heightBack = 2 * m_lpBMPBackInfoHeader->biHeight;//位图高
//m_widthBackDisplay = m_widthBack;//显示宽度
//m_heightBackDisplay = m_heightBack;//显示高度
int bitPerPixelBack = m_lpBMPBackInfoHeader->biBitCount;//位图像素深度
int destBackWidthByte = (widthBack * bitPerPixelBack + 7) / 8;
BYTE* newDataAreaBack = new BYTE[destBackWidthByte * heightBack]; int nPixel;//放大2倍,原图象一个象素现在变成2个
for(int i = 0; i < m_heightBack; i++ )
{
for(int j = 0; j < m_widthBack; j++ )
{
nPixel = m_heightBack * i + j;
newDataAreaBack[nPixel * 6] = dataAreaBack[nPixel * 3];
newDataAreaBack[nPixel * 6 + 1] = dataAreaBack[nPixel * 3 + 1];
newDataAreaBack[nPixel * 6 + 2] = dataAreaBack[nPixel * 3 + 2];
newDataAreaBack[nPixel * 6 + 3] = dataAreaBack[nPixel * 3];
newDataAreaBack[nPixel * 6 + 4] = dataAreaBack[nPixel * 3 + 1];
newDataAreaBack[nPixel * 6 + 5] = dataAreaBack[nPixel * 3 + 2];
}
} m_lpBMPBackInfoHeader->biWidth = widthBack;
m_lpBMPBackInfoHeader->biHeight = heightBack; delete[] dataAreaBack;
dataAreaBack = newDataAreaBack; m_isBackModified = true;
PostMessage(WM_PAINT);//发送绘制窗口消息
Invalidate();//更新窗口
} file.Close();
}以上是打开bmp文件(按文件的格式顺序:文件头,文件信息头,调色板(24位图没有此项),实际像素数据)到读到内存的全过程,写到文件中也是一样的,只需按bmp文件格式的顺序写到文件中即可。通常实际要操作的只为第2(图片的高、宽等信息)和第4部分,写文件时才要考虑第3部分。
可能我没说清楚,我原来从打开图片开始,现在改成输入是这样的一个函数
CString GetReognize(UBYTE* pBmpBuf , long DataLeng ,long width ,long height)
{
....
}
我现在从这函数开始来做处理
你的UBYTE* pBmpBuf数组里面是一个bmp图片?DataLeng是数组长度?如果是的话可以参考下面,一段用图片数组来生成Bitmap的代码IStream* istream;
HGLOBAL m_hGlobal = GlobalAlloc(GPTR, DataLeng);
VOID* global_addr = GlobalLock(m_hGlobal);
memcpy(global_addr,pBmpBuf,DataLeng);
CreateStreamOnHGlobal(m_hGlobal,true, &istream );bitmap = new Bitmap(istream,false);
派生MemStream和FileStream就可以了
对内存中的bmp进行操作,看我上面代码中间的部分就行了,取相应操作的字节数据就行了。
看这一部分:m_widthBack = m_lpBMPBackInfoHeader->biWidth;//位图宽
m_heightBack = m_lpBMPBackInfoHeader->biHeight;//位图高
//m_widthBackDisplay = m_widthBack;//显示宽度
//m_heightBackDisplay = m_heightBack;//显示高度
int m_bitPerPixelBack = m_lpBMPBackInfoHeader->biBitCount;//位图像素深度 上面这部分可操作位图的基本文件信息。 int m_destBackWidthByte = (m_widthBack * m_bitPerPixelBack + 7) / 8;//位图宽度为4的倍数,计算其行的字节数
dataAreaBack = new BYTE[m_destBackWidthByte * m_heightBack];//开辟空间存储图像实际数据
file.Read(dataAreaBack, m_destBackWidthByte * m_heightBack);//读取图像数据 现在dataAreaBack中存储的就是图像的实际像素了,如果是8位图,数组中每一个元素表示一个像素,如是24位图,则3位表示一个像素。 不知道你还想操作什么?