这是我绘制直线的代码发现运行时CPU占用很高,有什么方法能优化一下效率吗?PS:不使用XOR方式
var
TempBmp1,TempBmp2:TBitMap;
bDown:Boolean;
orgx,orgy:Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
self.PaintBox1.Canvas.FillRect(self.PaintBox1.Canvas.ClipRect);
bDown:=false;
Tempbmp1:=TBitmap.Create;
Tempbmp1.Width:=self.PaintBox1.Width;
Tempbmp1.Height:=self.PaintBox1.Height;
Tempbmp2:=TBitmap.Create;
Tempbmp2.Width:=self.PaintBox1.Width;
Tempbmp2.Height:=self.PaintBox1.Height;
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=true;
Tempbmp1.Canvas.CopyRect(PaintBox1.Canvas.ClipRect, PaintBox1.Canvas, PaintBox1.Canvas.ClipRect);
orgx:=x;
orgy:=y;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if bDown then
begin
Tempbmp2.Assign(Tempbmp1);
Tempbmp2.Canvas.MoveTo(orgx,orgy);
Tempbmp2.Canvas.LineTo(x,y);
self.PaintBox1.Canvas.Draw(0,0,Tempbmp2);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=false;
end;
var
TempBmp1,TempBmp2:TBitMap;
bDown:Boolean;
orgx,orgy:Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
self.PaintBox1.Canvas.FillRect(self.PaintBox1.Canvas.ClipRect);
bDown:=false;
Tempbmp1:=TBitmap.Create;
Tempbmp1.Width:=self.PaintBox1.Width;
Tempbmp1.Height:=self.PaintBox1.Height;
Tempbmp2:=TBitmap.Create;
Tempbmp2.Width:=self.PaintBox1.Width;
Tempbmp2.Height:=self.PaintBox1.Height;
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=true;
Tempbmp1.Canvas.CopyRect(PaintBox1.Canvas.ClipRect, PaintBox1.Canvas, PaintBox1.Canvas.ClipRect);
orgx:=x;
orgy:=y;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if bDown then
begin
Tempbmp2.Assign(Tempbmp1);
Tempbmp2.Canvas.MoveTo(orgx,orgy);
Tempbmp2.Canvas.LineTo(x,y);
self.PaintBox1.Canvas.Draw(0,0,Tempbmp2);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=false;
end;
解决方案 »
- 给指导下如何快速上手DELPHI~~
- 如何获取当前日期以前的日期最近的记录,如果不存在则获取当前日期以后的日期最近的记录(急急急,送高分)?
- 100分,请高手给一个思路~~~~顶者有分
- 用 ADO Com 对象编程时,如何获得SQL 的执行进程??
- 请大虾们支招:Dll 中注册热建 (谢谢了先。在线等待……)
- 提出一个关于query查询问题
- 这个东西我搞不定,不爽呀,帮我搞定,给分!!!!! 不够再开贴加
- 开展“09年Delphi学习热潮”学习活动
- TClientSocket控件如何一次只收取服务端返回的一条信息
- 一个菜鸟的问题,求各位大哥大姐帮帮 忙!!!
- GDI+图片复制到剪贴板
- fastreport 条件打印
Tempbmp2.Assign(Tempbmp1);
Tempbmp2.Canvas.MoveTo(orgx,orgy);
Tempbmp2.Canvas.LineTo(x,y);
self.PaintBox1.Canvas.Draw(0,0,Tempbmp2);
这几句要怎么优化,是不是有其它的替代方式
在画虚线时速度能大幅提高self.PaintBox1.Canvas.Draw(0,0,Tempbmp2);
这句很慢吧,是不是可以换个方式试试
自己想了办法,欺骗性地加上Sleep(10)解决之
你把你想要做什麼,說清楚一點。如果單純畫直線,直接在鼠標事件裡moveto lineto就可以了。
程序不多大问题,楼上的几位方法也可以试试,当然看你的兴趣!
用双缓冲是为了画面不闪动
单单程序运行起来当然不会慢,问题在于如果窗口最大化,别外还有其它程序运行时怎么办。
这个程序在运行时,鼠标移动过程中CPU占用自然就高了起来,不信可以试试(PS:双核CPU占用50%,单核就是100%)
var
TempBmp1,TempBmp2:TBitMap;
bDown:Boolean;
orgx,orgy:Integer;
prevx, prevy: integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
bDown:=false;
Tempbmp1:=TBitmap.Create();
Tempbmp2:=TBitmap.Create();
Tempbmp2.Canvas.Pen.Color := $00C0C0;
Tempbmp2.Canvas.Pen.Mode := pmXor;
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=true;
Tempbmp2.Canvas.Draw(0, 0, Tempbmp1);
orgx:=x;
orgy:=y;
prevx := -1;
prevy := -1;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if bDown then
begin
// 消除之前画在 Tempbmp2上的临时线
if prevx >= 0 then
begin
Tempbmp2.Canvas.MoveTo(orgx, orgy);
Tempbmp2.Canvas.LineTo(prevx, prevy);
end;
Tempbmp2.Canvas.MoveTo(orgx,orgy);
Tempbmp2.Canvas.LineTo(x,y);
prevx := x; prevy := y;
PaintBox1Paint(nil);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if bDown then
begin
bDown:=false;
Tempbmp1.Canvas.MoveTo(orgx,orgy);
Tempbmp1.Canvas.LineTo(x,y);
PaintBox1Paint(nil);
end;
end;procedure TForm1.FormResize(Sender: TObject);
begin
Tempbmp1.Width:=self.PaintBox1.Width;
Tempbmp1.Height:=self.PaintBox1.Height;
Tempbmp2.Width:=self.PaintBox1.Width;
Tempbmp2.Height:=self.PaintBox1.Height;
end;procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
// PaintBox1.Canvas.FillRect(PaintBox1.Canvas.ClipRect);
if bDown then
PaintBox1.Canvas.Draw(0,0,Tempbmp2)
else
PaintBox1.Canvas.Draw(0,0,Tempbmp1);
end;
临时线以Xor方式画线,同一位置再画一次就清除之前的线了。
谢谢代码,这样做就只复制一次图片,移动时就省去了图片复制,CPU占用是很低,可问题再于不想采用Xor方式,因为画的过程中效果不太好
var
TempBmp1: TBitMap;
bDown: Boolean;
orgx,orgy: Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
bDown:=false;
Tempbmp1:=TBitmap.Create();
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=true;
orgx:=x;
orgy:=y;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if bDown then
begin
PaintBox1Paint(nil);
PaintBox1.Canvas.MoveTo(orgx,orgy);
PaintBox1.Canvas.LineTo(x,y);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if bDown then
begin
bDown:=false;
Tempbmp1.Canvas.MoveTo(orgx,orgy);
Tempbmp1.Canvas.LineTo(x,y);
PaintBox1Paint(nil);
end;
end;procedure TForm1.FormResize(Sender: TObject);
begin
Tempbmp1.Width:=self.PaintBox1.Width;
Tempbmp1.Height:=self.PaintBox1.Height;
end;procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Draw(0,0,Tempbmp1);
end;
这个程序要求的是:
1、CPU占用较低
2、不使用Xor方式
3、绘制过程中不能出现闪烁
但Windows自带的绘图程序就不会出现上面的问题,我反汇编过程序,发现自带的绘图程序没有使用到MoveTo LineTo函数。
var
TempBmp1,TempBmp2:TBitMap;
bDown:Boolean;
orgx,orgy:Integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
bDown:=false;
Tempbmp1:=TBitmap.Create();
Tempbmp2:=TBitmap.Create();
end;procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bDown:=true;
Tempbmp2.Canvas.Draw(0, 0, Tempbmp1);
orgx:=x;
orgy:=y;
end;procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if bDown then
begin
Tempbmp2.Canvas.Draw(0, 0, Tempbmp1);
Tempbmp2.Canvas.MoveTo(orgx,orgy);
Tempbmp2.Canvas.LineTo(x,y);
PaintBox1Paint(nil);
end;
end;
procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if bDown then
begin
bDown:=false;
Tempbmp1.Canvas.MoveTo(orgx,orgy);
Tempbmp1.Canvas.LineTo(x,y);
PaintBox1Paint(nil);
end;
end;procedure TForm1.FormResize(Sender: TObject);
begin
Tempbmp1.Width:=self.PaintBox1.Width;
Tempbmp1.Height:=self.PaintBox1.Height;
Tempbmp2.Width:=self.PaintBox1.Width;
Tempbmp2.Height:=self.PaintBox1.Height;
end;procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
// PaintBox1.Canvas.FillRect(PaintBox1.Canvas.ClipRect);
if bDown then
PaintBox1.Canvas.Draw(0,0,Tempbmp2)
else
PaintBox1.Canvas.Draw(0,0,Tempbmp1);
end;
大哥这个方法CPU占用并不会改善,其实跟我发的代码一样
你发的三种方法第一种使用的Xor
第二种出现的闪烁
第三种CPU占用高了
还是谢谢,我还是采用Sleep(10)的方法,
好像这个问题基本无解
sleep虽然可以使cpu暂时喘口气,但对其总的占用却是有增无减
最重要的是要减少画线和拷贝图形的次数和图形的大小范围
确实如此,首先硬件方面是不自己能改善的,减少画线也是不可能的,必竟这就是一个画线的程序
剩下拷贝次数,这个好像可以欺骗性地做成每隔两点执行,MouseMove中的代码
图形的大小范围好像也能控制,只复制和画改变的部分,就像屏幕录像一样
没啥招了,只能采用局部刷新的方式,这样CPU也能降下来,线太长时只好多加上Sleep
这句有严重的问题,
不需要在move时总执行