在bmp上写字,画画等

这个功能很实用,可以说经常用到,但由于dc,位图的复杂性,经常忘记,所以记下今天写的一个程序。

 

功能:加载一个现有的位图,在此位图上写字,最后在位图的外圈rectangle上画一个淡绿色的框,最终在一个cstatic控件上显示出来

 

CxImage m_image;   //使用cximage库加载图片

m_image->load("a://b.jpg", CXIMAGE_FORMAT_JPG);
if(m_image.IsValid())
{
    m_image.Resample(width, height);        //根据宽高重新采样
   
    CDC* pCdc = m_static->GetDC();            //m_static是一个cstatic控件
    m_hBitmap = m_image->MakeBitmap(pCdc->m_hDC);
   
    //HBITMAP bmp = CreateCompatibleBitmap(pCdc->m_hDC, 100,100);        //创建一个DB位图
   
    CDC dcMem;
    dcMem.CreateCompatibleDC(pCdc);                //创建一个内存兼容dc
    dcMem.SetBKMode(TRANSPARENT);                //将dc设置为透明模式
    dcMem.SetTextColor(RGB(0, 255, 0));            //设置文字颜色
   
    HBITMAP hBmpTemp = (HBITMAP)dcMem.SelectObject(m_hBitmap);       //内存dc选中图片
    CRect rct(0, 0, m_nWidth, m_nHeight);
    //一定要同时使用DT_EDITCONTROL
    int nHeight = dcMem.DrawText( m_strDesc.c_str(), m_strDesc.length(), &rct,
                    DT_RIGHT|DT_WORDBREAK|DT_EDITCONTROL|DT_CALCRECT);
    //重新调整显示区域,让文字显示在图片的右下角
    rct.bottom = m_nHeight;
    rct.top = rct.bottom - nHeight;
    rct.left = m_nWidth - rct.Width();
    rct.right = m_nWidth();
   
    //正式画文字
    dcMem.DrawText( m_strDesc.c_str(), m_strDesc.length(), &rct,
                    DT_RIGHT|DT_WORDBREAK|DT_EDITCONTROL);
   
    //在图片的外围画一层框,注意不能使用Rectangle函数,会使用brush颜色填充rect的
    dcMem.Draw3dRect(CRect(0, 0,m_nWidth, m_nHeight), RGB(0,128,128), RGB(0,128,128));


    //或者使用drawEdge来画3d的框
    //dcMem.DrawEdge(CRect(0, 0,m_nWidth, m_nHeight), EDGE_SUNKEN, BF_RECT);   

    dcMem.SelectObject(hBmpTemp);            //将画好的位图选出
   
    HBITMAP hOldBmp = m_static->SetBitmap(m_hBitmap);        //ctatic控件设置位图
    if(hOldBmp)
        DeleteObject(hOldBmp);
    if(pCdc->m_hDC)
        m_static->ReleaseDC(pCdc);
}

 

代码基本就是这样,可以举一反三

 

 

 

下面是另外找的一篇文章

 

 

介绍:
本文描述了如何在位图上画线、图形或者文字。要求很简单,可以给初学者的一个方便快速的参考。

用HBITMAP操作位图
首先我们需要一个背景位图,这个位图是通过一个hbitmap句柄引用的。至于hbitmap是如何得到,可以有多种方法:先前操作得到的hbitmap;用CreateBitmap函数创建返回的;或者是通过资源导入的:
HBITMAP hbitmap = ::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
//LoadBitmap从工程的资源里装载位图,位图的ID为IDB_BITMAP1

然后通过hbitmap句柄,我们可以得到一些关于位图的基本信息:
BITMAP bm;                  //位图对象结构
GetObject(hbitmap,sizeof(BITMAP),&bm);      //返回hbitmap所指位图的基本信息到结构对象bm里
long width=bm.bmWidth;
long height=bm.bmHeight;         //得到位图的高度、宽度

接着创建一个内存DC,同时选入一个新的位图

BITMAPINFO bmInfo; //定义位图头结构对象
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth=width;
bmInfo.bmiHeader.biHeight=height;
bmInfo.bmiHeader.biPlanes=1;
bmInfo.bmiHeader.biBitCount=24;
//创建临时的内存DC对象
HDC pDC = ::GetDC(0);
HDC TmpDC=CreateCompatibleDC(pDC);

//利用位图头结构对象bmInfo创建一个新的位图,同时选入创建的内存DC
BYTE *pbase;
HBITMAP TmpBmp=CreateDIBSection(pDC,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);

在创建的TmpDC上我们就可以画线、写文字或者画图。下面的代码就是如何在一个背景位图上写文字:

//把背景位图选入DC设备
HDC dcBmp=CreateCompatibleDC(TmpDC);
HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap); //把hbitmap选入内存DC
BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY);//复制图片到内存DC
SelectObject(TmpDC,TmpObj2);
DeleteDC(dcBmp);

//选择创建字体
CFont m_Font;
LOGFONT* m_pLF;
m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT));
strncpy(m_pLF->lfFaceName,"Times New Roman",31);
m_pLF->lfHeight=64;
m_pLF->lfWeight=600;
m_pLF->lfItalic=1;
m_pLF->lfUnderline=0;
m_Font.CreateFontIndirect(m_pLF);
//用LOGFONT结构创建一种字体

//把创建的字体对象选入DC
CDC dc;
dc.Attach(TmpDC);
CFont* pOldFont=NULL;
if(m_Font.m_hObject) //判断字体创建是否成功
{
    //如果创建成功就选入DC
    pOldFont = dc.SelectObject(&m_Font);
}
else
{
    //如果创建没成功则选入默认的字体
    dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT));
}

//设置文本颜色
dc.SetTextColor(RGB(60,120,240));
//设置添加文字的位置
RECT pos = {40,40,0,0};
//添加文字
dc.SetBkMode(TRANSPARENT);
dc.DrawText("Test",4,&pos,DT_CALCRECT);
dc.DrawText("Test",4,&pos,0);

//释放和清除
if (pOldFont)
{
    dc.SelectObject(pOldFont);
}
m_Font.DeleteObject();
dc.Detach();
free(m_pLF);

这里有两个两个位图对象:hbitmap和TmpBmp,就能同时保存新旧两个图象,或者用TmpBmp替代
hbitmap:
DeleteObject(hbitmap);
hbitmap=TmpBmp;

最后,我们就能删除临时DC。此时不要删除hbitmap和TmpBmp,否则就可能丢失位图。

//最后的资源清除
SelectObject(TmpDC,TmpObj);
DeleteDC(TmpDC);

结论:
文章开始用一个保存在HBITMAP里的背景图象,最后形成一个新图象,保存在一个新的HBITMAP里。这在操作过程中给了我们很 大的灵活性: 可以利用所有的GDI函数创建图象,比如CBitmap,象FreeImage和CxImage这些图形处理库,还可以给图片添加效果或者保存图片到文 件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在MFC应用程序中的CStatic控件上显示BMP图像,可以按照以下步骤操作: 1. 首先,使用LoadBitmap函数加载BMP图像文件。例如,下面的代码将加载名为“myimage.bmp”的图像文件。 ```C++ CBitmap bmp; bmp.LoadBitmap(IDB_MYIMAGE); ``` 其中,IDB_MYIMAGE是资源文件中BMP图像的ID。 2. 创建CDC对象并将其与CStatic控件关联。可以使用以下代码创建CDC对象并从CStatic控件获取设备上下文。 ```C++ CDC* pDC = m_pMyStatic->GetDC(); ``` 其中,m_pMyStatic是指向CStatic控件的指针。 3. 创建CDC对象后,可以使用CDC的BitBlt函数将图像绘制到设备上下文中。例如,下面的代码将图像绘制到CStatic控件中。 ```C++ CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap* pOldBitmap = memDC.SelectObject(&bmp); BITMAP bm; bmp.GetBitmap(&bm); pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY); memDC.SelectObject(pOldBitmap); ``` 4. 最后,释放CDC对象并释放资源。 ```C++ ReleaseDC(pDC); bmp.DeleteObject(); ``` 完整的示例代码如下所示: ```C++ // Load BMP image CBitmap bmp; bmp.LoadBitmap(IDB_MYIMAGE); // Get device context of CStatic control CDC* pDC = m_pMyStatic->GetDC(); // Draw image to device context CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap* pOldBitmap = memDC.SelectObject(&bmp); BITMAP bm; bmp.GetBitmap(&bm); pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY); memDC.SelectObject(pOldBitmap); // Release resources ReleaseDC(pDC); bmp.DeleteObject(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值