Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 237, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

EVC中的图片背景透明处理

在EVC或VC8.0中,有关图片处理的资料并不多,SDK中的例子只是告诉你如何加载图片,下面的代码可以用在VC的任何编译器上,它的原理是采用的双缓冲技术,用为运算来完成此项功能。
void TransparentBlt2( HDC hdcDest,      // 目标DC
      int nXOriginDest,   // 目标X偏移
      int nYOriginDest,   // 目标Y偏移
      int nWidthDest,     // 目标宽度
      int nHeightDest,    // 目标高度
      HDC hdcSrc,         // 源DC
      int nXOriginSrc,    // 源X起点
      int nYOriginSrc,    // 源Y起点
      int nWidthSrc,      // 源宽度
      int nHeightSrc,     // 源高度
      UINT crTransparent  // 透明色,COLORREF类型
      )
{
 HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
 HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);   // 创建单色掩码位图
 HDC  hImageDC = CreateCompatibleDC(hdcDest);
 HDC  hMaskDC = CreateCompatibleDC(hdcDest);
 hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
 hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

 // 将源DC中的位图拷贝到临时DC中
 if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
  BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
 else
  StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
  hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

 // 设置透明色
 SetBkColor(hImageDC, crTransparent);

 // 生成透明区域为白色,其它区域为黑色的掩码位图
 BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

 // 生成透明区域为黑色,其它区域保持不变的位图
 SetBkColor(hImageDC, RGB(0,0,0));
 SetTextColor(hImageDC, RGB(255,255,255));
 BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

 // 透明部分保持屏幕不变,其它部分变成黑色
 SetBkColor(hdcDest,RGB(0xff,0xff,0xff));
 SetTextColor(hdcDest,RGB(0,0,0));
 BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

 // "或"运算,生成最终效果
 BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

 SelectObject(hImageDC, hOldImageBMP);
 DeleteDC(hImageDC);
 SelectObject(hMaskDC, hOldMaskBMP);
 DeleteDC(hMaskDC);
 DeleteObject(hImageBMP);
 DeleteObject(hMaskBMP);

}

这个函数的调用一般在WM_PAINT消息处理函数,在WIN32工程中,可参照下面的代码来做:
RECT rc;
GetClientRect(hwnd,&rc);
 HDC dc = GetDC(hwnd);//客户区的HDC
void LoadImg(HDC dc,LPCTSTR FilePath)//HDC是客户区的HDC,FilePath是文件路径,
{

 COLORREF crMask = RGB(255,0,255);
 HBITMAP m_hSrcBmp = SHLoadDIBitmap(FilePath);/此函数仅限于WM5.0等PPC,
 BITMAPINFO BitInfo;
 GetObject(m_hSrcBmp, sizeof(BITMAPINFO), &BitInfo);


 int nWidth = BitInfo.bmiHeader.biWidth;
 int nHeight = BitInfo.bmiHeader.biHeight;

 HDC ImageDC = CreateCompatibleDC(dc);

 HBITMAP pOldImageBMP = NULL;
 HDC OldDC = CreateCompatibleDC(dc);

 SelectObject(ImageDC,pOldImageBMP);
 SelectObject(ImageDC,m_hSrcBmp);


  TransparentBlt2(dc,24,0,nWidth,nHeight,ImageDC,0,0,nWidth,nHeight,crMask);

 
 SelectObject(ImageDC,pOldImageBMP);
}
MFC的工程的调用相对简单,在OnPaint中调用
{
CRect rect;
 ::GetWindowRect (GetDlgItem(IDC_COMBO1)->m_hWnd, rect);
 ScreenToClient (rect);

 //加载位图
 CBitmap m_bitmap;//注意这个变量不能是全局变量或类的成员变量,否则不能更新
  wchar_t FilePath1[128] = {0};
 
 m_bitmap.Attach(SHLoadImageFile(FilePath));
 

 COLORREF crMask = RGB(255,0,255);//要过滤颜色的RGB的值
 BITMAP bm;

 m_bitmap.GetBitmap(&bm);
  int nWidth1 = bm.bmWidth;
 int nHeight1 = bm.bmHeight;
 

 CDC ImageDC;
 ImageDC.CreateCompatibleDC(&dc);
 CBitmap *pOldImageBMP = ImageDC.SelectObject(&m_bitmap);
 TransparentBlt2(dc.m_hDC,0,rect.bottom,nWidth1,nHeight1,ImageDC.m_hDC,0,0,nWidth1,nHeight1,crMask);
 ImageDC.SelectObject(pOldImageBMP);
}

posted on 2008-11-09 22:48 Benjamin 阅读(1721) 评论(0)  编辑 收藏 引用 所属分类: PDA/PPC开发


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理