Windows GDI、GDI+ 绘图 闪烁问题



“闪烁”的原因是擦除背景(用背景色重新填充)与绘制前景图像之间有时间差,而且背景和前景颜色有差异,导致眼睛看上去好像在闪烁。
“闪烁”并不主要是因为GDI或GDI+效率低造成的。

解决这个问题需从两个方面入手:1.缩短(或消除)前后景绘图时间差,2.减少绘制次数
1.缩短(或消除)前后景绘图时间差
OnEraseBkgnd(CDC* pDC)
{
    return TRUE;
}

实际上背景填充是必须,否则前景图像与残留的背景混在一起非常杂乱,
这里取消的步骤,其实移到绘图过程了(见2.),合成一张完整图像。

2.减少绘制次数
采用“双缓冲”技术,先在内存缓冲区中完成绘图,再贴到屏幕上
另外如果缓冲图像内容不是变化的,应存为成员对象之类,不要每次去画
一般在OnDraw(CDC* pDC)中完成
///--GDI --
int nWidth=1000;
int nHeight=1000;
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(pDC); //这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
//,也可以自己定义(如:有滚动条时就要大于当前窗口的大小,在BitBlt时决定拷贝内存的哪部分到屏幕上)

MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上

CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净,这里用原背景色作为背景
//你也可以用自己应该用的颜色

MemDC.FillSolidRect(0,0,nWidth,nHeight,pDC->GetBkColor());
//绘图
CBrush brush(RGB(0,255,0));
 for(int i=0;i<50;i++)
 {
  for(int j=0;j<80;j++)
  {
   //MemDC.Rectangle(10*j,10*i,9,9);
   CRect rc(10*j,10*i,10*j+8,10*i+8);
   MemDC.FillRect(&rc,&brush);
  }
 }
//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();


///--GDI+ --
 Bitmap* buf=new Bitmap(2000,2000) ;
 Graphics gc(buf);//Graphics.FromImage(buf);
 //反锯齿
 //gc.SetSmoothingMode(SmoothingModeAntiAlias);
 SolidBrush bgbrush(Color(255,255,255,255));
 gc.FillRectangle(&bgbrush,0,0,2000,2000);//背景填充
 Pen      pen(Color(255, 0, 0, 255));
 SolidBrush sbrush(Color(255,0,255,255));
 for(int i=0;i<60;i++)
 {
  for(int j=0;j<60;j++)
   gc.FillRectangle(&sbrush,10*j,10*i,9,9);
 }
 Graphics G(pDC->GetSafeHdc()); 
 G.DrawImage(buf ,0,0);

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值