关于HBITMAP的问题,请专家指点,谢谢

sinfee 2004-12-23 10:32:59
我从剪贴板获得了一个HBITMAP的数据,也可以显示,可是如何知道其大小呢,如何转化为void*的指针,
或是拷贝到另外一个内存BUFFER中呢?
我使用了GlobalLock()得到是0,用GlobakSize()也得到是0,可是明明可以显示的?

请大家帮忙,解决问题一定加分。
...全文
164 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
sinfee 2005-01-27
  • 打赏
  • 举报
回复
虽然没有解决问题,可是依然感谢大家。
老夏Max 2005-01-21
  • 打赏
  • 举报
回复
参考:
void CCreateRandomBMPDlg::OnBtnTest()
{
// TODO: Add your control notification handler code here
HBITMAP hBmp;

CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this);

if (dlg.DoModal() != IDOK)
{
return;
}

hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);

if (hBmp == NULL)
{
return;
}

BITMAP bm;
PBITMAPINFO bmpInf;

if (GetObject(hBmp, sizeof(bm), &bm) == 0)
return ;

int nPaletteSize = 0;

if (bm.bmBitsPixel < 16)
nPaletteSize = (int) pow(2, bm.bmBitsPixel);

bmpInf = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize);

//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) /
8 * bm.bmHeight * bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//-----------------------------------------------

HDC hDC = ::GetWindowDC(NULL);
if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf,
DIB_RGB_COLORS))
{
LocalFree(bmpInf);
::ReleaseDC(NULL, hDC);
return ;
}

void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage];
if (buf == NULL)
{
::ReleaseDC(NULL, hDC);
LocalFree(bmpInf);
return ;
}

if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf,
DIB_RGB_COLORS))
{
::ReleaseDC(NULL, hDC);
delete[]buf;
LocalFree(bmpInf);
return ;
}

::ReleaseDC(NULL, hDC);

CString sMsg;
sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth,
bm.bmHeight);

AfxMessageBox(sMsg);

CClientDC dc(this);

if (bm.bmBitsPixel == 8)
{
BYTE* pData = (BYTE*) buf;

int nWidth = bm.bmWidth;
while (nWidth % 4 != 0)
{
//Bmp每行数据都是4个字节的整数倍。
nWidth++;
}

for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
RGBQUAD rgbQ;
rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]];
dc.SetPixel(j, bm.bmHeight - i,
RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue));
}
}
}
else if (bm.bmBitsPixel == 16)
{
BYTE* pData = (BYTE*) buf;

int nWidth = bm.bmWidth*2;
while (nWidth % 4 != 0)
{
nWidth++;
}

BYTE red, green, blue;

for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
blue = pData[i * nWidth + j * 2] & 0x1F;
green = pData[i * nWidth + j * 2] >> 5;
green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3;
red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F;

WORD wRed = red*8;
WORD wBlue = blue*8;
WORD wGreen = green*8;

red = min(255, wRed);
blue = min(255, wBlue);
green = min(255, wGreen);

dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue));
}
}
}
else if (bm.bmBitsPixel == 24)
{
BYTE* pData = (BYTE*) buf;

int nWidth = bm.bmWidth*3;
while (nWidth % 4 != 0)
{
nWidth++;
}

for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 3 + 2],
pData[i * nWidth + j * 3 + 1],
pData[i * nWidth + j * 3]));
}
}
}
else if (bm.bmBitsPixel == 32)
{
BYTE* pData = (BYTE*) buf;

int nWidth = bm.bmWidth*4;

for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 4 + 2],
pData[i * nWidth + j * 4 + 1],
pData[i * nWidth + j * 4]));
}
}
}

delete[]buf;

DeleteObject(hBmp);
LocalFree(bmpInf);
}
sinfee 2004-12-23
  • 打赏
  • 举报
回复
bmBits是指的缓冲区指针吗?那么缓冲区有多大呢?

我准备把全部信息存入数据库中,再读出来要还原成HBITMAP或是CBitmap*的,

应该如何做呢?

我刚刚跟踪发现实现上剪贴板中的数据是CF_DIB类型的,可是强行用CF_BITMAP也能获得,
不过用GlobalSize什么的就会提示句柄无效了。
token_lys 2004-12-23
  • 打赏
  • 举报
回复
不用MFC的方法:

BITMAP bmp;

if (GetObject(hBmp,sizeof(bmp),&bmp))
{
bmp.bmWidth;//宽度
bmp.bmHeight;//高度
}
快乐鹦鹉 2004-12-23
  • 打赏
  • 举报
回复
CBitmap *pBmp = CBitmap::FromHandle(hBmp);
BITMAP bm;
pBmp->GetBitmap(&bm);
bm中就有大小了
typedef struct tagBITMAP { /* bm */
int bmType;
int bmWidth;
int bmHeight;
int bmWidthBytes;
BYTE bmPlanes;
BYTE bmBitsPixel;
LPVOID bmBits;
} BITMAP;

sinfee 2004-12-23
  • 打赏
  • 举报
回复
我用的是
HBITMAP hBmp=(HBITMAP)::GetClipboardData(CF_BITMAP);
获得的HBITMAP。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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