首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

MFC中为什么直接使用DC不直接使用效果不一样解决方法

2012-04-15 
MFC中为什么直接使用DC不直接使用效果不一样在 OnPaint 的函数中 直接加载图片到DC上CPaintDC dc(this)CR

MFC中为什么直接使用DC不直接使用效果不一样
在 OnPaint 的函数中 直接加载图片到DC上
CPaintDC dc(this); 
CRect m_PictureRect;
GetClientRect(m_PictureRect);
  Gdiplus::Rect rccd;
Graphics graphics(dc.m_hDC);
rccd.X = m_PictureRect.left;
rccd.Y = m_PictureRect.top;
rccd.Width = m_PictureRect.Width();
rccd.Height = m_PictureRect.Height();
Image imagePic(_T("ico_tip.png")); 是PNG 的图片
graphics.DrawImage(&imagePic, rccd);
和缓冲一次在加载到DC上效果不一样?(图片周围有少量的黑色)
CPaintDC dc(this); 
CRect m_PictureRect;
GetClientRect(m_PictureRect);
CDC SaveDC;
SaveDC.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,m_PictureRect.Width(),m_PictureRect.Height());
SaveDC.SelectObject(bitmap);
Gdiplus::Rect rccd;
Graphics graphics(SaveDC.m_hDC);
rccd.X = m_PictureRect.left;
rccd.Y = m_PictureRect.top;
rccd.Width = m_PictureRect.Width();
rccd.Height = m_PictureRect.Height();
Image imagePic(_T("ico_tip.png"));
graphics.DrawImage(&imagePic, rccd);
dc.TransparentBlt(0,0,m_PictureRect.Width(),m_PictureRect.Height(),&SaveDC,0,0,m_PictureRect.Width(),m_PictureRect.Height(),RGB(0,0,0));
大神们 帮帮小弟把 怎么解决啊?

[解决办法]
png 图片你要是有半透明边缘的话, 贴PNG之前要贴父窗口该区域的图像,也就是底图
[解决办法]
测试代码1:
void C**View::OnDraw( CDC* pDC )
{
C**Doc* pDoc = GetDocument( ); ASSERT_VALID( pDoc );

CRect m_PictureRect;
GetClientRect(m_PictureRect);
Gdiplus::Rect rccd;
Graphics graphics( pDC->m_hDC);
rccd.X = m_PictureRect.left;
rccd.Y = m_PictureRect.top;
rccd.Width = m_PictureRect.Width();
rccd.Height = m_PictureRect.Height();
Image imagePic( L"2.png" );
graphics.DrawImage(&imagePic, rccd);
}
代码1效果图:

测试代码2:
void CMSPrintView::OnDraw( CDC* pDC )
{
CMSPrintDoc* pDoc = GetDocument( ); ASSERT_VALID( pDoc );

CRect m_PictureRect;
GetClientRect(m_PictureRect);
CDC SaveDC;
SaveDC.CreateCompatibleDC( pDC );
CBitmap bitmap;
bitmap.CreateCompatibleBitmap( pDC, m_PictureRect.Width( ), m_PictureRect.Height( ) );
SaveDC.SelectObject(bitmap);
Gdiplus::Rect rccd;
Graphics graphics(SaveDC.m_hDC);
rccd.X = m_PictureRect.left;
rccd.Y = m_PictureRect.top;
rccd.Width = m_PictureRect.Width();
rccd.Height = m_PictureRect.Height();
Image imagePic( L"2.png" );
graphics.DrawImage(&imagePic, rccd);

pDC->BitBlt( 0, 0, m_PictureRect.Width( ), m_PictureRect.Height( ), &SaveDC, 0, 0, SRCCOPY );

}
代码2效果图:

我这样的测试应该没有违背楼主的主要意图。
从测试结果来看,楼主的主要问题是,在调用dc.TransparentBlt之前,你不进行内存绘图和进行内存绘图时,源DC得到的是两张不同的图,一个背景为白色,一个背景为黑色。这对dc.TransparentBlt的影响就是会产生黑边。
我想楼主应该明白怎么做了,呵呵 代码:

C/C++ code
void CMSPrintView::OnDraw( CDC* pDC ){    C**Doc* pDoc = GetDocument( ); ASSERT_VALID( pDoc );    CRect m_PictureRect;    GetClientRect(m_PictureRect);    CDC SaveDC;    SaveDC.CreateCompatibleDC( pDC );    CBitmap bitmap;    bitmap.CreateCompatibleBitmap( pDC, m_PictureRect.Width( ), m_PictureRect.Height( ) );    SaveDC.SelectObject(bitmap);    [color=#FF0000]SaveDC.FillSolidRect( 0, 0, m_PictureRect.Width( ), m_PictureRect.Height( ), RGB( 255,255,255 ) );[/color]    Gdiplus::Rect rccd;    Graphics graphics(SaveDC.m_hDC);    rccd.X = m_PictureRect.left;    rccd.Y = m_PictureRect.top;    rccd.Width = m_PictureRect.Width();    rccd.Height = m_PictureRect.Height();    Image imagePic( L"2.png" );    graphics.DrawImage(&imagePic, rccd);    pDC->BitBlt( 0, 0, m_PictureRect.Width( ), m_PictureRect.Height( ), &SaveDC, 0, 0, SRCCOPY );    DrawTransBitmap( pDC->m_hDC, 0, 0, m_PictureRect.Width( ), m_PictureRect.Height( ), SaveDC.m_hDC, 0, 0, RGB( 24, 24, 24 ) );    //pDC->TransparentBlt(0,0,m_PictureRect.Width(),m_PictureRect.Height(),&SaveDC,0,0,m_PictureRect.Width(),m_PictureRect.Height(),RGB(0,0,0));} 


[解决办法]
1. 缓存还是要用的,否则绘图效果将是各种悲剧;
2. 你出现“周围有少量的黑色”的本质原因在于TransparentBlt。这个函数会进行掩码处理(在2D游戏人物贴图中经常使用),可以达到背景透明的效果。
3. 使用这种掩码处理的图片必须满足一个条件:图片的前景部分绝对不能包含和背景色相同的颜色RGB,否则就是你所描述的效果。
4. 要解决这个问题,两个选择:(1) 不做掩码处理,直接BitBlt或者StretchBlt,但贴图的背景色全部选用同一种颜色,且不能有区域重叠 (2)做掩码处理,但请专门搞美工的处理下图片,使得处理过的图片满足3中的条件。总之不管怎么解,都得从图源下手,图源不行的话,你的算法再牛逼也没用。

热点排行