创建位图失败,高手请进。非常感谢!

flyjzy5 2004-12-28 07:05:39
创建位图的函数,没有成功,请高手帮忙看看,分析哪里错了。非常感谢!
其中cx,cy为位图高度,ibitcount为位深度,lpData为图像数据,bSave为是否保存标志。

HBITMAP CreatBMP(long cx, long cy, UINT ibitcount, LPBYTE lpData, bool bSave)
{
// 宽度为 4 的整数倍
cx = ((cx+3)/4 * 4);

ASSERT((ibitcount == 1) || (ibitcount == 4) ||
(ibitcount == 8) || (ibitcount == 16)
|| (ibitcount == 24) ||(ibitcount == 32));

int iSize = sizeof(BITMAPINFOHEADER);
switch(ibitcount){
case 8:
iSize += 4*4;
break;
case 1:
case 4:
case 16:
case 24:
case 32:
break;
default:
break;
}

// 创建信息头
BITMAPINFO* pBmpInfo;
BYTE *pByte;
pByte = new BYTE[iSize];
pBmpInfo = (BITMAPINFO*) pByte;
memset(pBmpInfo, 0, iSize);

pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBmpInfo->bmiHeader.biWidth = cx;
pBmpInfo->bmiHeader.biHeight = cy;
pBmpInfo->bmiHeader.biPlanes = 1;
pBmpInfo->bmiHeader.biBitCount = ibitcount;
pBmpInfo->bmiHeader.biCompression = BI_RGB;
pBmpInfo->bmiHeader.biSizeImage = 0;
pBmpInfo->bmiHeader.biClrUsed = 0;

// 创建DIB
CDC *pDC = new CDC;
pDC->CreateCompatibleDC(NULL);
LPVOID lpBits;
HBITMAP hDIB = ::CreateDIBSection(pDC->GetSafeHdc(),
pBmpInfo,
DIB_RGB_COLORS,
&lpBits,
NULL,
0);

// 填充图像数据
LONG lineBytes = cx * ibitcount*8;
memcpy(lpBits, (void* )lpData, lineBytes*cy);

// 是否保存
if( bSave )
{
int iBmpBytes = cx * cy * ibitcount/8;
BITMAPFILEHEADER fileHeader;
ZeroMemory(&fileHeader, sizeof(BITMAPFILEHEADER));
*((char* )&fileHeader.bfType) = 'B';
*(((char*)&fileHeader.bfType) + 1) = 'M';
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER) + ibitcount*sizeof(RGBTRIPLE);
fileHeader.bfSize = fileHeader.bfOffBits + iBmpBytes;

CFile file;
if(file.Open("temp.bmp", CFile::modeWrite | CFile::modeCreate))
{
file.Write(&fileHeader, sizeof(BITMAPFILEHEADER));
file.Write(&(pBmpInfo->bmiHeader), sizeof(BITMAPINFOHEADER));
file.WriteHuge(lpBits, iBmpBytes);
file.Close();
}
}

delete pDC;
delete pBmpInfo;
delete pByte;

return hDIB;
}

一执行就s了啊。
...全文
270 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyjzy5 2005-01-05
  • 打赏
  • 举报
回复
换了另外一种方法替代,哎。

先结贴
flyjzy5 2004-12-31
  • 打赏
  • 举报
回复
TO Wyhshp(阿呆) :我现在主要是想创建DIB,并得到该hDIB, 函数CreateDIBSection会处理相关部分的。

TO vcleaner:创建的时候只要得到句柄就行,如果我要保存或显示,需要的时候再利用hDIB处理。
老夏Max 2004-12-31
  • 打赏
  • 举报
回复
void CCreateRandomBMPDlg::OnBtnCreateBMP()
{
CDC dc;
dc.CreateDC("DISPLAY", NULL, NULL, NULL);
CBitmap bm;
int Width = 800;//GetSystemMetrics(SM_CXSCREEN);
int Height = 600;//GetSystemMetrics(SM_CYSCREEN);
bm.CreateCompatibleBitmap(&dc, Width, Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap* pOld = tdc.SelectObject(&bm);
tdc.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
tdc.SelectObject(pOld);

BITMAP btm;
bm.GetBitmap(&btm);
DWORD size = btm.bmWidthBytes* btm.bmHeight;
LPSTR lpData = (LPSTR) GlobalAllocPtr(GPTR, size);
/////////////////////////////////////////////


/////////////////////////////////////////////
BITMAPINFOHEADER bih;
bih.biBitCount = btm.bmBitsPixel;
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biCompression = 0;
bih.biHeight = btm.bmHeight;
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = size;
bih.biWidth = btm.bmWidth;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
///////////////////////////////////
GetDIBits(dc, bm, 0, bih.biHeight, lpData, (BITMAPINFO *) &bih,
DIB_RGB_COLORS);
// bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱
//////////////////////////////
//修改RGB值
int nWidth = btm.bmWidth * 4;
for (int i = 0; i < btm.bmHeight; i++)
{
for (int j = 0; j < btm.bmWidth; j++)
{
lpData[i * nWidth + j * 4 + 2] = GetRandomRGBValue(); //R
lpData[i * nWidth + j * 4 + 1] = GetRandomRGBValue(); //G
lpData[i * nWidth + j * 4] = GetRandomRGBValue(); //B
TRACE("\nR = %d; G = %d; B = %d\n",
lpData[i * nWidth + j * 4 + 2],
lpData[i * nWidth + j * 4 + 1], lpData[i * nWidth + j * 4]);
}
}

static int filecount = 0;
CString name;
name = "D:\\Test.bmp";//m_Path+name;
BITMAPFILEHEADER bfh;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
bfh.bfType = ((WORD) ('M' << 8) | 'B');
bfh.bfSize = 54 + size;
bfh.bfOffBits = 54;

CFile bf;
if (bf.Open(name, CFile::modeCreate | CFile::modeWrite))
{
bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData, size);
bf.Close();
}
GlobalFreePtr(lpData);
AfxMessageBox("Create BMP File Over!");
}
Wyhshp 2004-12-31
  • 打赏
  • 举报
回复
图片大小没有算对,如果是8位256色位图还需要分配调色板空间!!
flyjzy5 2004-12-30
  • 打赏
  • 举报
回复
TO DentistryDoctor:
biSizeImage = 0 没错的,当不使用压缩时置0。
调色板可能要考虑。但是我创建24位色位图时程序也不行。不知道是不是创建过程逻辑有问题。

热切期望各位再帮忙!多谢。
DentistryDoctor 2004-12-30
  • 打赏
  • 举报
回复
pBmpInfo->bmiHeader.biSizeImage = 0;?????????

另:对于16色/256位图,还需要自己创建调色板。



MZP 2004-12-30
  • 打赏
  • 举报
回复
后边一句没有问题,呵呵!
bitcount=4 时iSize += 16*4 是对的。
flyjzy5 2004-12-29
  • 打赏
  • 举报
回复
多谢各位引导,图像保存部分已经参考SaveDIB()解决(是《VC数字图像处理》里的吧?
)。

To MZP(mzp): 首先谢了。还有,bitcount=4 时iSize += 16*4 吧?这一句
memcpy(lpBits, (void* )lpData, lineBytes*cy);哪里错了?

麻烦大家帮帮忙,主要是创建部分。
MZP 2004-12-28
  • 打赏
  • 举报
回复
bitcount = 4时iSize = 16
bitcount = 8时isize = 256*4 = 1024
计算行像数个数,4字节对齐
这两句都有问题
LONG lineBytes = cx * ibitcount*8; 这里应该是(cx*ibitcount/8 +3)/4*4
memcpy(lpBits, (void* )lpData, lineBytes*cy);

另的地方不看了
Kudeet 2004-12-28
  • 打赏
  • 举报
回复
先用MessageBox调试看是什么地方的问题
I_Love_CPP 2004-12-28
  • 打赏
  • 举报
回复
参考:
http://community.csdn.net/Expert/topic/3567/3567472.xml?temp=.551449

19,468

社区成员

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

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