关于CDib类的问题。

wsh_yao 2004-04-08 05:13:53
这是技术内幕里面的原码
BOOL CDib::Read(CFile* pFile)
{
// 1. read file header to get size of info hdr + color table
// 2. read info hdr (to get image size) and color table
// 3. read image
// can't use bfSize in file header
Empty();
int nCount, nSize;
BITMAPFILEHEADER bmfh;
try {
nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
if(nCount != sizeof(BITMAPFILEHEADER)) {
throw new CException;
}
if(bmfh.bfType != 0x4d42) {
throw new CException;
}
nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
m_nBmihAlloc = m_nImageAlloc = crtAlloc;
nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
ComputeMetrics();
ComputePaletteSize(m_lpBMIH->biBitCount);
MakePalette();
m_lpImage = (LPBYTE) new char[m_dwSizeImage];
nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
}
catch(CException* pe) {
AfxMessageBox("Read error");
pe->Delete();
return FALSE;
}
return TRUE;
}



HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)
{
if(m_lpBMIH == NULL) return NULL;
if(m_lpImage != NULL) return NULL; // can only do this if image doesn't exist
m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
ASSERT(m_lpImage != NULL);
return m_hBitmap;
}


LPBYTE m_lpImage; // starting address of DIB bits
=========================================================================
我用read打开一个位图,然后想用CreateSection得到其句柄,但是m_lpImage != NULL,CreateSection返回为空,为什么m_lpImage会非空?如果强制清空则程序错误,应该怎么解决?。
技术内幕上说CreateSection调用CreateDIBSection函数来创建一个DIB段(section),什么叫DIB段?
...全文
156 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wsh_yao 2004-04-09
  • 打赏
  • 举报
回复
那dib段呢?
ymbymb 2004-04-09
  • 打赏
  • 举报
回复
read 只是把数据从文件里读出来,readsection是用文件中的数据创建一个位图对象,如果你要显示位图,你要用readsection ,如果你只是对位图的数据感兴趣,你就要用read
wsh_yao 2004-04-09
  • 打赏
  • 举报
回复
多谢;ymbymb(毛病大哥) !
不多我还是不太懂。。。。read和readsection各有什么好处啊?什么地方用哪个比较好?
还有:dib段我还不太明白是什么意思。
分数不够可以另加。
ymbymb 2004-04-09
  • 打赏
  • 举报
回复
CDib::Read是给m_lpImage 分配空间,然后把图像数据从文件里读到m_lpImage;
CDib::CreateDibSession 也要给m_lpImage分配空间, 创建一个空的位图
两个不能同时用
ymbymb 2004-04-09
  • 打赏
  • 举报
回复
楼主用法不对,如果你要从文件里构造一个HBITMAP的话你应该直接调用
ReadSection(...);
调用完成后m_hBitmap就是你要的句柄
快乐鹦鹉 2004-04-09
  • 打赏
  • 举报
回复
你在if(m_lpImage != NULL) return NULL; 这里加个断点,调试一下,看看m_lpImage是指向有效内存还是一个垃圾地址?
wsh_yao 2004-04-09
  • 打赏
  • 举报
回复
puhuofeie(扑火飞蛾) :
初始化里面没有问题。
酒红绿叶 2004-04-09
  • 打赏
  • 举报
回复
在初始化,也就是构造函数里面m_lpImage = NULL
给他赋初值!
快乐鹦鹉 2004-04-08
  • 打赏
  • 举报
回复
那检查一下,还有哪里对m_lpImage赋值啊!!
wsh_yao 2004-04-08
  • 打赏
  • 举报
回复
void CDib::Empty()
{
// this is supposed to clean up whatever is in the DIB
DetachMapFile();
if(m_nBmihAlloc == crtAlloc) {
delete [] m_lpBMIH;
}
else if(m_nBmihAlloc == heapAlloc) {
::GlobalUnlock(m_hGlobal);
::GlobalFree(m_hGlobal);
}
if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
m_nBmihAlloc = m_nImageAlloc = noAlloc;
m_hGlobal = NULL;
m_lpBMIH = NULL;
m_lpImage = NULL;
m_lpvColorTable = NULL;
m_nColorTableEntries = 0;
m_dwSizeImage = 0;
m_lpvFile = NULL;
m_hMap = NULL;
m_hFile = NULL;
m_hBitmap = NULL;
m_hPalette = NULL;
}
wsh_yao 2004-04-08
  • 打赏
  • 举报
回复
void CDib::Empty()
{
// this is supposed to clean up whatever is in the DIB
DetachMapFile();
if(m_nBmihAlloc == crtAlloc) {
delete [] m_lpBMIH;
}
else if(m_nBmihAlloc == heapAlloc) {
::GlobalUnlock(m_hGlobal);
::GlobalFree(m_hGlobal);
}
if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
m_nBmihAlloc = m_nImageAlloc = noAlloc;
m_hGlobal = NULL;
m_lpBMIH = NULL;
m_lpImage = NULL;
m_lpvColorTable = NULL;
m_nColorTableEntries = 0;
m_dwSizeImage = 0;
m_lpvFile = NULL;
m_hMap = NULL;
m_hFile = NULL;
m_hBitmap = NULL;
m_hPalette = NULL;
}
itmaster 2004-04-08
  • 打赏
  • 举报
回复
CreateDIBSection 原型定义:
HBITMAP CreateDIBSection(
HDC hDC, // handle to device context
CONST BITMAPINFO *lpbmi,
// pointer to structure containing bitmap size, format, and color data
UINT iUsage, // color data type indicator: RGB values or palette indexes
VOID *ppvBits, // pointer to variable to receive a pointer to the bitmap's bit values
HANDLE hSection, // optional handle to a file mapping object
DWORD dwOffset // offset to the bitmap bit values within the file mapping object
);



CreateDIBSection能创建一种特殊的DIB,称为DIB项(DIBSection),然后返回一个GDI位图的句柄。它提供了DIB和GDI位图的最好的特性。这样我们可以直接访问DIB的内存,可以利用位图句柄和内存设备环境,我们甚至还可以在DIB中调用GDI函数来绘图
返回值:
执行成功返回DIBSection位图的句柄,零表示失败。会设置GetLastError
参数:
hDC 一个设备场景的句柄。如dw设为DIB_PAL_COLORS,那么DIB颜色表就会用来自逻辑调色板的颜色进行初始化
lpbmi 指向BITMAPINFO(为兼容BMP4/5而声明成Any),这个结构初始化成欲创建的那幅位图的配置数据
iUsage DIB_PAL_COLORS 颜色表是一个整数数组,其中包含了与目前选入hDC设备场景的调色板相关的索引
DIB_RGB_COLORS 颜色表包含了RGB颜色

ppvBits 用于得到DIBSection数据区的内存地址
hSection 指向一个文件映射对象的可选句柄,位图将在其中创建。如设为零,Windows会自动分配内存
dwOffset 如指定了句柄,就用这个参数指定位图数据在文件映射对象中的偏移量


快乐鹦鹉 2004-04-08
  • 打赏
  • 举报
回复
检查一下你的程序中,有没有对m_lpImage赋值为NULL的语句。如果定义LPBYTE m_lpImage,而没有赋值为NULL的话,m_lpImage并不等于NULL。

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧