VS/MFC--------MFC中如何在CBitmap上写字?

独行~背包客 2019-01-24 09:30:13
看别人的回复是说“将位图选入内存DC,然后就可以在内存DC上用TextOut写字,然后将位图选出内存DC”,代码是如下这样吗?有没有问题?

CDC* mem_dc;
mem_dc->CreateCompatibleDC(cDC);
mem_dc->SelectObject(bitmap);
mem_dc->TextOutA(5, 10, _T("Hello Everyone!"));
mem_dc->DeleteDC();

如果没问题的话,此时把bitmap显示在cDC上,是可以看到"Hello Everyone!"的吗?

刚接触MFC,有许多不懂的地方,请多多指教,谢谢!
...全文
1301 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
独行~背包客 2019-02-13
  • 打赏
  • 举报
回复
[quote=引用 34 楼 schlafenhamster 的回复:]
如果一定要用 全局 cdc ,要 使用 CS_OWNDC, 还要 重新注册

会用用看,谢谢!
schlafenhamster 2019-01-28
  • 打赏
  • 举报
回复
还是 dcMem.CreateCompatibleDC(cDC);
不用 这个 cDC 不行吗 ?
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
就还是这一段代码有问题,但不知道在哪里....


HBITMAP hbmp = (HBITMAP)image_show->Detach();
CBitmap* bitmap = new CBitmap;//创建位图
bitmap->DeleteObject();
bitmap->Attach(hbmp);

CDC dcMem;//兼容的内存DC
dcMem.CreateCompatibleDC(cDC);
BITMAP bmp;
bitmap->GetBitmap(&bmp);
CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bitmap);
CRect rect_bit;//控件位置尺寸(0,0,w,h)
cDC->GetWindow()->GetClientRect(&rect_bit);
cDC->SetStretchBltMode(STRETCH_HALFTONE);//设置伸展模式:半色调
cDC->StretchBlt(0, 0, rect_bit.Width(), rect_bit.Height(), &dcMem, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

dcMem.SelectObject(pOldBitmap);
VERIFY(bitmap->DeleteObject());
VERIFY(dcMem.DeleteDC());
delete bitmap;
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
void CameraDisplay_bitmap(BYTE * pbyRGB24, tDSFrameInfo * frameInfo)
{
CImage*image_show = new CImage;
image_show->Create(frameInfo->uiWidth, frameInfo->uiHeight, 24, 0);
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
BYTE *image_byte = (BYTE*)image_show->GetPixelAddress(0, y);
memcpy(image_byte, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3, frameInfo->uiWidth * 3);
}

HBITMAP hbmp = (HBITMAP)image_show->Detach();
CBitmap* bitmap = new CBitmap;//创建位图
bitmap->DeleteObject();
bitmap->Attach(hbmp);

CDC dcMem;//兼容的内存DC
dcMem.CreateCompatibleDC(cDC);
BITMAP bmp;
bitmap->GetBitmap(&bmp);
CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bitmap);
CRect rect_bit;//控件位置尺寸(0,0,w,h)
cDC->GetWindow()->GetClientRect(&rect_bit);
cDC->SetStretchBltMode(STRETCH_HALFTONE);//设置伸展模式:半色调
cDC->StretchBlt(0, 0, rect_bit.Width(), rect_bit.Height(), &dcMem, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

dcMem.SelectObject(pOldBitmap);
VERIFY(bitmap->DeleteObject());
VERIFY(dcMem.DeleteDC());
delete bitmap;
delete image_show;
}

这一段CImage转CBitmap的代码,没有错误提示,没有显示图片,两个函数是在同一个位置调用
weixin_43924360 2019-01-28
  • 打赏
  • 举报
回复
坤哥牛逼CBitmap
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
void CameraDisplay_bitmap(BYTE * pbyRGB24, tDSFrameInfo * frameInfo)
{
CImage*image_show = new CImage;
image_show->Create(frameInfo->uiWidth, frameInfo->uiHeight, 24, 0);
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
BYTE *image_byte = (BYTE*)image_show->GetPixelAddress(0, y);
memcpy(image_byte, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3, frameInfo->uiWidth * 3);
}
CWnd* wnd = cDC->GetWindow();
CRect rect;
GetClientRect(wnd->m_hWnd, rect);
SetStretchBltMode(cDC->m_hDC, STRETCH_HALFTONE);
image_show->StretchBlt(cDC->m_hDC, rect, SRCCOPY);
image_show->Draw(cDC->m_hDC, rect);
delete image_show;
}

这一段CImage代码可以正常显示,如下:
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
引用 15 楼 远水孤云 的回复:
[quote=引用 14 楼 远水孤云 的回复:]
[quote=引用 13 楼 schlafenhamster 的回复:]
“在调用GetDC或BeginPaint时,windows用默认值创建一个设备描述表,对设备描述表属性所做的一切改变在ReleaseDC或EndPaint使用后都会失效。”


那就是了,我并没有主动对其做改变

请教了别人,说是要先cDC->Attach(hDC);绑定句柄,可是我这边会报错,目前还在搞,不清楚啥问题...[/quote][/quote]

这个值没问题,是我打断点打错,不好意思,请忽略
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
引用 18 楼 schlafenhamster 的回复:
void CameraDisplay_bitmap 在哪里 调用 ?


谢谢!
因为涉及到了相机,CameraDisplay_bitmap()这个显示图像的函数是在相机的初始化时自带的回调函数中调用,回调函数带的参数就是颜色数据和图像信息,之前用CImage写是可以显示的

我现在怀疑是不是下面这里的数据转换的有问题,现在去试一下用CImage去加载这些数据,然后把CImage转化为CBitmap,再显示看一下.....

BYTE *bitbyte = new BYTE[frameInfo->uiWidth*frameInfo->uiHeight*3];
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
memcpy(bitbyte + frameInfo->uiWidth * 3 * y, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3,
frameInfo->uiWidth * 3);
}
schlafenhamster 2019-01-28
  • 打赏
  • 举报
回复
如果一定要用 全局 cdc ,要 使用 CS_OWNDC, 还要 重新注册 窗口 类。
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
引用 32 楼 schlafenhamster 的回复:
HDC hDC = GetDC(hWND);
CDC*pDC = new CDC;
pDC->Attach(hDC);
//
CDC*pDC = GetDC();

问题是 GetDC 需要 ReleaseDC , 你的做法 不 规范 !


1.CameraDisplay_bitmap()这个函数是全局函数,并不属于某各类,在里面用不了CDC* GetDC( )这个函数
2.CDC*pDC = new CDC 用的是new,所以最后用的delete,但觉得是有点问题,会改成 CDC pDC;
3.至于HDC hDC = GetDC(hWND);这里Get,在函数最后有ReleaseDC掉




schlafenhamster 2019-01-28
  • 打赏
  • 举报
回复
HDC hDC = GetDC(hWND);
CDC*pDC = new CDC;
pDC->Attach(hDC);
//
CDC*pDC = GetDC();

问题是 GetDC 需要 ReleaseDC , 你的做法 不 规范 !
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
void CameraDisplay_bitmap(BYTE * pbyRGB24, tDSFrameInfo * frameInfo)
{
CImage*image_show = new CImage;//CImage数据加载
image_show->Create(frameInfo->uiWidth, frameInfo->uiHeight, 24, 0);
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
BYTE *image_byte = (BYTE*)image_show->GetPixelAddress(0, y);
memcpy(image_byte, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3, frameInfo->uiWidth * 3);
}

CDC dcMem;//内存DC
dcMem.CreateCompatibleDC(cDC);
ASSERT(NULL != dcMem.GetSafeHdc());
CBitmap bitmap;

HBITMAP hbmp = (HBITMAP)image_show->Detach();//CBitmap数据加载
bitmap.DeleteObject();
bitmap.Attach(hbmp);
ASSERT(NULL != bitmap.GetSafeHandle());
BITMAP bmp;
bitmap.GetBitmap(&bmp);
CRect rect;
cDC->GetWindow()->GetClientRect(&rect);
CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bitmap);

dcMem.SetBkMode(TRANSPARENT);//输出格式
dcMem.SetTextColor(RGB(255, 0, 0));
SelectObject(dcMem.m_hDC, font);
dcMem.DrawText("帧 率:", CRect(20, 50, 550, 130), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dcMem.DrawText(str_rate, CRect(570, 50, 800, 130), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dcMem.DrawText("CPU占用率:", CRect(20, 140, 550, 220), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dcMem.DrawText(str_cpu, CRect(570, 140, 800, 220), DT_CENTER | DT_VCENTER | DT_SINGLELINE);

cDC->SetStretchBltMode(STRETCH_HALFTONE);//拉伸模式
cDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcMem, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

dcMem.SelectObject(pOldBitmap);
VERIFY(bitmap.DeleteObject());
VERIFY(dcMem.DeleteDC());
}


感谢诸位,问题已解决,重新写了一下函数,已经可以显示,原因还在找!!!
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
引用 29 楼 远水孤云 的回复:
void CameraDisplay_bitmap(BYTE * pbyRGB24, tDSFrameInfo * frameInfo)
{
CImage*image_show = new CImage;
image_show->Create(frameInfo->uiWidth, frameInfo->uiHeight, 24, 0);
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
BYTE *image_byte = (BYTE*)image_show->GetPixelAddress(0, y);
memcpy(image_byte, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3, frameInfo->uiWidth * 3);
}

HBITMAP hbmp = (HBITMAP)image_show->Detach();
CBitmap* bitmap = new CBitmap;//创建位图
bitmap->DeleteObject();
bitmap->Attach(hbmp);

HWND hWND = GetDlgItem(afx_m_hWnd, IDC_PIC);//其中afx_m_hWnd为对话框句柄,afx_m_hWnd = this->m_hWnd
HDC hDC = GetDC(hWND);
CDC*pDC = new CDC;

pDC->Attach(hDC);

CDC dcMem;//兼容的内存DC
dcMem.CreateCompatibleDC(pDC);
BITMAP bmp;
bitmap->GetBitmap(&bmp);
CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bitmap);
CRect rect_bit;//控件位置尺寸(0,0,w,h)
pDC->GetWindow()->GetClientRect(&rect_bit);
pDC->SetStretchBltMode(STRETCH_HALFTONE);//设置伸展模式:半色调
pDC->StretchBlt(0, 0, rect_bit.Width(), rect_bit.Height(), &dcMem, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

dcMem.SelectObject(pOldBitmap);
VERIFY(bitmap->DeleteObject());
VERIFY(dcMem.DeleteDC());
ReleaseDC(hWND, hDC);
delete bitmap;
delete image_show;
delete pDC;
}


再Get一次?依然没效果,还是我Get错了?


HWND hWND = GetDlgItem(afx_m_hWnd, IDC_PIC);//afx_m_hWnd为对话框句柄,afx_m_hWnd = this->m_hWnd
HDC hDC = GetDC(hWND);
CDC*pDC = new CDC;
pDC->Attach(hDC);

就是这几行pDC
独行~背包客 2019-01-28
  • 打赏
  • 举报
回复
void CameraDisplay_bitmap(BYTE * pbyRGB24, tDSFrameInfo * frameInfo)
{
CImage*image_show = new CImage;
image_show->Create(frameInfo->uiWidth, frameInfo->uiHeight, 24, 0);
for (unsigned int y = 0; y < frameInfo->uiHeight; y++)
{
BYTE *image_byte = (BYTE*)image_show->GetPixelAddress(0, y);
memcpy(image_byte, pbyRGB24 + (frameInfo->uiHeight - y - 1)*frameInfo->uiWidth * 3, frameInfo->uiWidth * 3);
}

HBITMAP hbmp = (HBITMAP)image_show->Detach();
CBitmap* bitmap = new CBitmap;//创建位图
bitmap->DeleteObject();
bitmap->Attach(hbmp);

HWND hWND = GetDlgItem(afx_m_hWnd, IDC_PIC);//其中afx_m_hWnd为对话框句柄,afx_m_hWnd = this->m_hWnd
HDC hDC = GetDC(hWND);
CDC*pDC = new CDC;

pDC->Attach(hDC);

CDC dcMem;//兼容的内存DC
dcMem.CreateCompatibleDC(pDC);
BITMAP bmp;
bitmap->GetBitmap(&bmp);
CBitmap* pOldBitmap = (CBitmap*)dcMem.SelectObject(&bitmap);
CRect rect_bit;//控件位置尺寸(0,0,w,h)
pDC->GetWindow()->GetClientRect(&rect_bit);
pDC->SetStretchBltMode(STRETCH_HALFTONE);//设置伸展模式:半色调
pDC->StretchBlt(0, 0, rect_bit.Width(), rect_bit.Height(), &dcMem, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

dcMem.SelectObject(pOldBitmap);
VERIFY(bitmap->DeleteObject());
VERIFY(dcMem.DeleteDC());
ReleaseDC(hWND, hDC);
delete bitmap;
delete image_show;
delete pDC;
}


再Get一次?依然没效果,还是我Get错了?
csdn15617596510 2019-01-25
  • 打赏
  • 举报
回复
程序员就是不一般,敲了那么多代码。
独行~背包客 2019-01-25
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
if(!dcMem.CreateCompatibleDC(cDC))
说明这个 cDC ??


BOOL CreateCompatibleDC( CDC* pDC );
cDC对应的是Picture Control控件,是个全局变量,前面有求过,这里没有显示出来
这里是为让两个dc关联一下,顺便判断一下是否成功,有什么问题?
谢谢!
weixin_44622071 2019-01-25
  • 打赏
  • 举报
回复
牛了哈。
weixin_43924360 2019-01-25
  • 打赏
  • 举报
回复
用CBitmap双缓存
schlafenhamster 2019-01-25
  • 打赏
  • 举报
回复
if(!dcMem.CreateCompatibleDC(cDC))
说明这个 cDC ??
加载更多回复(15)

15,979

社区成员

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

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