VC++里怎么读取位图,具体的步骤是什么啊?
刚开始要将位图读进设备(位图的构成我都差不多明白了),对于读文件头,信息头,调色板还有数据部分,我不清楚在哪写,其实也不是不知道在哪写,就是操作起来很乱,就是写不对,(没办法,为了工作,也只能硬着头皮用VC++)
我是这么想的:
1. view类里定义一个函数来初始化位图,这么写的,貌似又写的不完整:
CRwView::CRwView(CSize size, LPRGBQUAD lpColorTable,
unsigned char *pImgData)
{
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=8;
m_nColorTableLength=256;
int lineByte=(m_imgWidth*8/8+3)/4*4;
int imgBufferSize=m_imgHeight*lineByte;
m_lpDib=new BYTE[sizeof(BITMAPINFOHEADER)+sizeof(LPRGBQUAD)*
m_nColorTableLength+imgBufferSize];
m_lpBmpInfoHead=(LPBITMAPINFOHEADER)m_lpDib;
m_lpBmpInfoHead->biBitCount=m_nBitCount;
m_lpBmpInfoHead->biClrImportant=m_nColorTableLength;
m_lpBmpInfoHead->biClrUsed=m_nColorTableLength;
m_lpBmpInfoHead->biCompression=BI_RGB;
m_lpBmpInfoHead->biHeight=m_imgHeight;
m_lpBmpInfoHead->biPlanes=1;
m_lpBmpInfoHead->biSize=sizeof(BITMAPINFOHEADER);
m_lpBmpInfoHead->biSizeImage=0;
m_lpBmpInfoHead->biWidth=m_imgWidth;
m_lpBmpInfoHead->biXPelsPerMeter=0;
m_lpBmpInfoHead->biYPelsPerMeter=0;
m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));
LPLOGPALETTE pLogPal=(LPLOGPALETTE)new char[2*sizeof(WORD)+m_nColorTableLength*sizeof(PALETTEENTRY)];
LPRGBQUAD lpDibQuad=(LPRGBQUAD)m_lpColorTable;
for(int i=0;i<m_nColorTableLength;i++)
{
pLogPal->palPalEntry[i].peBlue=lpDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peGreen=lpDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peRed=lpDibQuad->rgbRed;
pLogPal->palPalEntry[i].peFlags=0;
lpDibQuad++;
}
m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD) * m_nColorTableLength;
memcpy(m_pImgData,pImgData,imgBufferSize);
}
CRwView函数又感觉是重载了构造函数CRwView(),至于里面的参数,我还不明白从哪里传递进来。
2.我写了一个读函数和写函数:
BOOL CRwView::Read(LPCTSTR lpszPathName)
{
CFile file;
if(!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyNone))
return FALSE;
BITMAPFILEHEADER bmfh;
int nCount=file.Read(&bmfh,sizeof(BITMAPFILEHEADER));
m_lpDib=new BYTE[file.GetLength()-sizeof(BITMAPFILEHEADER)];
file.Read(m_lpDib,file.GetLength()-sizeof(BITMAPFILEHEADER));
m_lpBmpInfoHead=(LPBITMAPINFOHEADER)m_lpDib;
m_imgWidth=m_lpBmpInfoHead->biWidth;
m_imgHeight=m_lpBmpInfoHead->biHeight;
m_nBitCount=m_lpBmpInfoHead->biBitCount;
m_nColorTableLength=256;
m_lpColorTable=(LPRGBQUAD)m_lpDib+sizeof(BITMAPINFOHEADER);
m_pImgData=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
return TRUE;
}
BOOL CRwView::Write(LPCTSTR lpszPathName)
{
CFile file;
if(!file.Open(lpszPathName,CFile::modeWrite | CFile::modeReadWrite | CFile::shareExclusive))
return FALSE;
BITMAPFILEHEADER bmfh;
bmfh.bfType=0x4d42;
bmfh.bfSize=0;
bmfh.bfReserved1=bmfh.bfReserved2=0;
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
try
{
file.Write((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
file.Write(m_lpBmpInfoHead,sizeof(BITMAPINFOHEADER));
file.Write(m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
int imgBufSize=(m_imgWidth*8/8+3)/4*4*m_imgHeight;
file.Write(m_pImgData,imgBufSize);
}
catch(CException *pe)
{
pe->Delete();
AfxMessageBox("write error");
return FALSE;
}
return TRUE;
}
3.其次在Doc类中这么写,把位图读进内存:
BOOL CRwDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
m_view.Write(lpszPathName);
return TRUE;
}
4.在View类的OnDraw函数里把位图读到设备:
void CRwView::OnDraw(CDC* pDC)
{
CRwDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
StretchDIBits(pDC->m_hDC,0,0,m_lpBmpInfoHead->biWidth,m_lpBmpInfoHead->biHeight,
0,0,m_lpBmpInfoHead->biWidth,m_lpBmpInfoHead->biHeight,m_pImgData,
(LPBITMAPINFO)m_lpBmpInfoHead,DIB_RGB_COLORS,SRCCOPY);
}
可是所出的问题是非法操作,无法运行。
感觉是内存分配出了问题,可是不知道怎么改,能不能给我说一下这部分处理的问题的步骤,比如在哪个类添加什么处理函数之类的。