Form中Image控件显示图片闪烁的问题,不是DoubleBuffered问题,是鼠标移上去就会闪的问题

qq_32969683 2017-12-07 02:53:32
做了一个udp传说的桌面采集的东西,但在接收方显示时出了一些问题
我的显示流程:将接收到的图片流拼接成大图,再直接用Form中的image空间assign生成的大图,效果是显示没问题,不闪烁(在Form中已经定义了doublebuffered = true),但是只要将鼠标移入窗口或者在窗口中移动,窗口就会闪烁且内存会开始不正常增加,考虑是不是欧尼mousemove的问题但是具体不清楚,望大神指导
贴上我的合成图片及显示的代码
void CSCREENFORCEDSYNCLIENTCLASS::TransformPngToBmpAndMergeIntoOneImage()
{
int i = 0;
unsigned short usTotalWidthTemp = 0;
unsigned short usTotalHeightTemp = 0;

unsigned short usSingleWidthTemp = 0;
unsigned short usSingleHeightTemp = 0;

this->iMergeSuccess = 0;

//char cFilenameTemp[32]= ".\\test\\total.bmp";
//AnsiString ansiFileName = AnsiString(cFilenameTemp);
//定义单张bmp图像
Graphics::TBitmap *tBmpSingleBitmapTemp;

//建立整张完整的bmp对象
this->tBmpTotalBmp = new Graphics::TBitmap;
this->tBmpTotalBmp->Width = this->usTotalImageWidth;
this->tBmpTotalBmp->Height = this->usTotalImageHeight;
this->tBmpTotalBmp->PixelFormat = pf16bit;
//this->tBmpTotalBmp->Assign(Form1->Image1->Picture->Bitmap);

//建立仅由变化了的图像组成的图像
Graphics::TBitmap *tBmpChangedTotalBitmap;
tBmpChangedTotalBitmap = new Graphics::TBitmap;
tBmpChangedTotalBitmap->Width = this->usTotalImageWidth;
tBmpChangedTotalBitmap->Height = this->usTotalImageHeight;
tBmpChangedTotalBitmap->PixelFormat = pf16bit;

while(usTotalHeightTemp<this->usTotalImageHeight)
{
while(usTotalWidthTemp<this->usTotalImageWidth)
{
//若整张图片还未填满但存储当前单张图片的向量列表中所有图片已经全部复制到整张图片上,说明此次接受完成后图片不全,需向发送方请求所有图片发送
if(i>=this->vRecvImageListNow.size())
{
this->SendRequestForTotalImage();
break;
}
//将单张png转为bmp
tBmpSingleBitmapTemp = new Graphics::TBitmap();
tBmpSingleBitmapTemp->Assign(this->vRecvImageListNow[i].tPngOfSinglePiece);
usSingleWidthTemp = tBmpSingleBitmapTemp->Width;
usSingleHeightTemp = tBmpSingleBitmapTemp->Height;
//将列表中的图片按顺序拷贝到整张大图上
BitBlt(this->tBmpTotalBmp->Canvas->Handle,usTotalWidthTemp,usTotalHeightTemp,usSingleWidthTemp,usSingleHeightTemp,tBmpSingleBitmapTemp->Canvas->Handle,0,0,SRCCOPY);
//将变化了的图片拷贝到另一张大图上
if(this->vRecvImageListNow[i].iIsThisImageChanged==1)
{
this->vRecvImageListNow[i].iIsThisImageChanged = 0;
BitBlt(tBmpChangedTotalBitmap->Canvas->Handle,usTotalWidthTemp,usTotalHeightTemp,usSingleWidthTemp,usSingleHeightTemp,tBmpSingleBitmapTemp->Canvas->Handle,0,0,SRCCOPY);
}
usTotalWidthTemp = usTotalWidthTemp+usSingleWidthTemp;
i++;
//tBmpSingleBitmapTemp->FreeImage();
//tBmpSingleBitmapTemp->ReleaseHandle();
delete tBmpSingleBitmapTemp;
}//end while usTotalWidthTemp<this
usTotalHeightTemp = usTotalHeightTemp+usSingleHeightTemp;
usTotalWidthTemp = 0;
} //end while usTotalHeightTemp<this

Form1->Image1->Picture->Bitmap->Assign(this->tBmpTotalBmp);
Form2->Image1->Picture->Bitmap->Assign(tBmpChangedTotalBitmap);
delete this->tBmpTotalBmp;
delete tBmpChangedTotalBitmap;

//this->iMergeSuccess = 1;
//this->iImageShowed = 0;
//this->tBmpTotalBmp->SaveToFile(ansiFileName);
}
...全文
996 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2017-12-25
  • 打赏
  • 举报
回复
怎么解决的分享一下?
qq_32969683 2017-12-25
  • 打赏
  • 举报
回复
引用 15楼draculamx 的回复:
线程里面不要调用任何窗体资源,窗体,控件,只做数据处理,切记
嗯,我已经解决了,谢谢了
qq_32969683 2017-12-21
  • 打赏
  • 举报
回复
引用 12楼draculamx 的回复:
引用 11 楼 qq_32969683 的回复:
[quote=引用 10楼draculamx 的回复:]你是否使用了第三方皮肤库,或者IDE自带的皮肤?
没有,我只使用了自带的image/paintbox控件
TImage和TPaintBox,最好不要作为自绘的“画布”,用Label或者Panel即可[/quote]直接bitblt到lable里吗?我试了一下没有显示。。。是不是因为我在线程里面做的所以要同步?
draculamx 2017-12-21
  • 打赏
  • 举报
回复
线程里面不要调用任何窗体资源,窗体,控件,只做数据处理,切记
draculamx 2017-12-21
  • 打赏
  • 举报
回复
你的画图,是在线程里面的?那不出问题是有鬼了。。。 你处理数据可以在线程中,但是一旦涉及到任何与界面相关的内容,请使用SendMessage或者PostMessage发送消息到主线程,然后主线程去画图 你在线程中去处理界面上的任何东西:控件,窗体,画图。都会造成程序崩溃
draculamx 2017-12-20
  • 打赏
  • 举报
回复
引用 11 楼 qq_32969683 的回复:
引用 10楼draculamx 的回复:
你是否使用了第三方皮肤库,或者IDE自带的皮肤?
没有,我只使用了自带的image/paintbox控件
TImage和TPaintBox,最好不要作为自绘的“画布”,用Label或者Panel即可
qq_32969683 2017-12-20
  • 打赏
  • 举报
回复
引用 10楼draculamx 的回复:
你是否使用了第三方皮肤库,或者IDE自带的皮肤?
没有,我只使用了自带的image/paintbox控件
draculamx 2017-12-20
  • 打赏
  • 举报
回复
你是否使用了第三方皮肤库,或者IDE自带的皮肤?
qq_32969683 2017-12-18
  • 打赏
  • 举报
回复
引用 7楼draculamx 的回复:
凡是用到DOUBLEBUFFER的地方,全部关闭,不要使用DOUBLEBUFFER
我单开工程测试了一下全部关闭了doublebuffer但还是有问题
qq_32969683 2017-12-18
  • 打赏
  • 举报
回复
引用 6楼draculamx 的回复:
不要使用 paint box,用panel或者label试试看,paint box和image控件内部都有BCB自己在维护,我们在上面做渲染的时候,容易和它冲突
嗯好的我试试
draculamx 2017-12-14
  • 打赏
  • 举报
回复
凡是用到DOUBLEBUFFER的地方,全部关闭,不要使用DOUBLEBUFFER
draculamx 2017-12-14
  • 打赏
  • 举报
回复
不要使用 paint box,用panel或者label试试看,paint box和image控件内部都有BCB自己在维护,我们在上面做渲染的时候,容易和它冲突
qq_32969683 2017-12-13
  • 打赏
  • 举报
回复
引用 4楼我是你的主体 的回复:
[quote=引用 1楼ooolinux 的回复:]楼主可以看一下这个有没有用: http://blog.163.com/tab_98/blog/static/1192409720170247251785/ 注意 WM_ERASEBKGND
这个我试了,效果不是很明显[/quote]还是谢了,我再试试
qq_32969683 2017-12-13
  • 打赏
  • 举报
回复
引用 1楼ooolinux 的回复:
楼主可以看一下这个有没有用: http://blog.163.com/tab_98/blog/static/1192409720170247251785/ 注意 WM_ERASEBKGND
这个我试了,效果不是很明显
qq_32969683 2017-12-13
  • 打赏
  • 举报
回复
引用 2楼draculamx 的回复:
这种情况没有必要使用Image控件了,你得到了图,直接画到内存CD上,然后在窗口上放一个Panel或者Label什么的,直接调用BitBlt画到这些控件的DC就可以了,也不用开启DoubleBuffer DoubleBuffer这个东西,你不知道它内部是怎么实现的,而且Image控件,你也不知道它的内部刷新是怎么实现的 所以你这个问题,可以化繁为简,不使用Image控件来显示图像,自己画到Panel上就行了 在我看来Image这个控件,是用来显示静态图像的,也就是硬盘上某一个已经存在的图片文件,仅此用途而已 如果你需要在某个控件里重复绘制很多次图像,那还是自己bitblt比较好 从你上面的代码来看,改几行就可以实现我说的了,应该不会闪烁的
我把收到合成的bitmap用TRect复制到paint box里,光标经过不会闪烁了可是会出现床体内图像部分丢失,出现色块,而且内存会暴涨,光标不碰没有问题,跑了一晚上也很稳定
draculamx 2017-12-09
  • 打赏
  • 举报
回复
这种情况没有必要使用Image控件了,你得到了图,直接画到内存CD上,然后在窗口上放一个Panel或者Label什么的,直接调用BitBlt画到这些控件的DC就可以了,也不用开启DoubleBuffer DoubleBuffer这个东西,你不知道它内部是怎么实现的,而且Image控件,你也不知道它的内部刷新是怎么实现的 所以你这个问题,可以化繁为简,不使用Image控件来显示图像,自己画到Panel上就行了 在我看来Image这个控件,是用来显示静态图像的,也就是硬盘上某一个已经存在的图片文件,仅此用途而已 如果你需要在某个控件里重复绘制很多次图像,那还是自己bitblt比较好 从你上面的代码来看,改几行就可以实现我说的了,应该不会闪烁的
ooolinux 2017-12-07
  • 打赏
  • 举报
回复
楼主可以看一下这个有没有用: http://blog.163.com/tab_98/blog/static/1192409720170247251785/ 注意 WM_ERASEBKGND

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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