TBitmap* prevImg
对象需要一些时间才能生成,因此我生成一次,并希望将其设置为背景:
Image1->Picture->Assign(prevImg); //TImage* Image1
现在我想在mousemove上绘制一些线条和数字:
void __fastcall TTriggerSystemForm::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y){
if(!prevImg)return;
Image1->Picture->Assign(prevImg); //reset image
Image1->Canvas->Pen->Color=clRed; //draw a vertical dotted red line
Image1->Canvas->Pen->Style=psDot;
Image1->Canvas->MoveTo(X,0);
Image1->Canvas->LineTo(X,Image1->Picture->Height);
}
现在这已经很好了。但是,由于图像有时会闪烁而且任务的CPU因为这个鼠标移动事件而上升到8%,这可能不是很有效。
我正在使用带有VCL的C ++ Builder XE2。
有没有更好的方法在给定的TImage对象上动态绘制内容而不更改原始图像源?
答案 0 :(得分:0)
了解双缓冲,诀窍在于您使用不同的缓冲区,一旦您的工作完成,您就可以切换缓冲区。这样可以防止“闪烁”。
要降低CPU使用率,您可以最小化已处理鼠标事件的数量,例如,如果上次处理的事件的时间低于100-200ms,则跳过事件处理
答案 1 :(得分:0)
您可以简单地绘制实际更改的图像部分,而不是绘制整个图像,例如:
int oldX = -1;
void __fastcall TTriggerSystemForm::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
if (!prevImg) return;
if (!Image1->Picture->Graphic)
Image1->Picture->Assign(prevImg); //reset image
if (oldX == X) return;
if (oldX != -1)
{
TRect r = Rect(oldX, 0, oldX + Image1->Canvas->Pen->Width, Image1->Height);
Image1->Canvas->CopyRect(r, prevImg->Canvas, r);
}
Image1->Canvas->Pen->Color = clRed; //draw a vertical dotted red line
Image1->Canvas->Pen->Style = psDot;
Image1->Canvas->MoveTo(X, 0);
Image1->Canvas->LineTo(X, Image1->Height);
oldX = X;
}
话虽如此,我建议使用TPaintBox
代替TImage
,例如:
int MouseX = -1;
void __fastcall TTriggerSystemForm::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
MouseX = X;
PaintBox1->Invalidate();
}
void __fastcall TTriggerSystemForm::PaintBox1MouseMove(TObject *Sender)
{
if (!prevImg) return;
PaintBox1->Canvas->Draw(0, 0, prevImg); //reset image
if (MouseX != -1)
{
PaintBox1->Canvas->Pen->Color = clRed; //draw a vertical dotted red line
PaintBox1->Canvas->Pen->Style = psDot;
PaintBox1->Canvas->MoveTo(MouseX, 0);
PaintBox1->Canvas->LineTo(MouseX, PaintBox1->Height);
}
}