图形放大、缩小时产生的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 ujin
  • 开始时间 开始时间
U

ujin

Unregistered / Unconfirmed
GUEST, unregistred user!
对于手工绘制的图形,当改变Image大小而重绘图形时,CPU占用率极高(为赛扬1G+128M 内存),速度很慢,Canvas.StretchDraw的效率就是这么低吗?怎样使图形重绘时CPU占用率降下来。
代码:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;

type
TForm1 = class(TForm)
Image2: TImage;
Image3: TImage;
procedure FormShow(Sender: TObject);
procedure Image2Click(Sender: TObject);
procedure Image2DblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyPix=Class
PixX:integer;
PixY:integer;
end;

var
Form1: TForm1;
JP,TmpJP:TBitmap;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
image2.Width :=663;
image2.Height :=458;

Image2.Canvas.MoveTo(100,100);
Image2.Canvas.LineTo(100,300);
Image2.Canvas.LineTo(300,300);
Image2.Canvas.MoveTo(300,300-15);
Image2.Canvas.LineTo(300,300-15+40);
Image2.Canvas.LineTo(300+36,300-15+40);
Image2.Canvas.LineTo(300+36,300-15);
Image2.Canvas.LineTo(300,300-15);

Image2.Canvas.TextOut(310,300-12,'256');
Image2.Canvas.TextOut(310,300,'423');
Image2.Canvas.TextOut(310,300+12,'789');

Image2.Canvas.MoveTo(28,28);
Image2.Canvas.LineTo(28,32);
Image2.Canvas.LineTo(32,32);
Image2.Canvas.LineTo(32,28);
Image2.Canvas.LineTo(28,28);

Image2.Canvas.MoveTo(128,128);
Image2.Canvas.LineTo(128,132);
Image2.Canvas.LineTo(132,132);
Image2.Canvas.LineTo(132,128);
Image2.Canvas.LineTo(128,128);

Image2.Canvas.MoveTo(228,228);
Image2.Canvas.LineTo(228,232);
Image2.Canvas.LineTo(232,232);
Image2.Canvas.LineTo(232,228);
Image2.Canvas.LineTo(228,228);

Image2.Canvas.MoveTo(328,328);
Image2.Canvas.LineTo(328,332);
Image2.Canvas.LineTo(332,332);
Image2.Canvas.LineTo(332,328);
Image2.Canvas.LineTo(328,328);

Image2.Canvas.MoveTo(428,428);
Image2.Canvas.LineTo(428,432);
Image2.Canvas.LineTo(432,432);
Image2.Canvas.LineTo(432,428);
Image2.Canvas.LineTo(428,428);



JP:=TBitmap.Create;
JP.Assign(Image2.Picture.Graphic );
end;

procedure TForm1.Image2Click(Sender: TObject);
begin
image2.Width :=1326;
image2.Height :=916;
Image2.Picture.Assign(nil);
image2.Canvas.StretchDraw(Rect(0,0,1326,916),JP);

end;

procedure TForm1.Image2DblClick(Sender: TObject);
begin
image2.Width :=663;
image2.Height :=458;
Image2.Picture.Assign(nil);
image2.Canvas.StretchDraw(Rect(0,0,663,458),JP);
end;

end.
 
对于手工绘制的图形,当改变Image大小而重绘图形时,CPU占用率极高(为赛扬1G+128M 内存),速度很慢,Canvas.StretchDraw的效率就是这么低吗?怎样使图形重绘时CPU占用率降下来。
代码:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;

type
TForm1 = class(TForm)
Image2: TImage;
Image3: TImage;
procedure FormShow(Sender: TObject);
procedure Image2Click(Sender: TObject);
procedure Image2DblClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyPix=Class
PixX:integer;
PixY:integer;
end;

var
Form1: TForm1;
JP,TmpJP:TBitmap;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
image2.Width :=663;
image2.Height :=458;

Image2.Canvas.MoveTo(100,100);
Image2.Canvas.LineTo(100,300);
Image2.Canvas.LineTo(300,300);
Image2.Canvas.MoveTo(300,300-15);
Image2.Canvas.LineTo(300,300-15+40);
Image2.Canvas.LineTo(300+36,300-15+40);
Image2.Canvas.LineTo(300+36,300-15);
Image2.Canvas.LineTo(300,300-15);

Image2.Canvas.TextOut(310,300-12,'256');
Image2.Canvas.TextOut(310,300,'423');
Image2.Canvas.TextOut(310,300+12,'789');

Image2.Canvas.MoveTo(28,28);
Image2.Canvas.LineTo(28,32);
Image2.Canvas.LineTo(32,32);
Image2.Canvas.LineTo(32,28);
Image2.Canvas.LineTo(28,28);

Image2.Canvas.MoveTo(128,128);
Image2.Canvas.LineTo(128,132);
Image2.Canvas.LineTo(132,132);
Image2.Canvas.LineTo(132,128);
Image2.Canvas.LineTo(128,128);

Image2.Canvas.MoveTo(228,228);
Image2.Canvas.LineTo(228,232);
Image2.Canvas.LineTo(232,232);
Image2.Canvas.LineTo(232,228);
Image2.Canvas.LineTo(228,228);

Image2.Canvas.MoveTo(328,328);
Image2.Canvas.LineTo(328,332);
Image2.Canvas.LineTo(332,332);
Image2.Canvas.LineTo(332,328);
Image2.Canvas.LineTo(328,328);

Image2.Canvas.MoveTo(428,428);
Image2.Canvas.LineTo(428,432);
Image2.Canvas.LineTo(432,432);
Image2.Canvas.LineTo(432,428);
Image2.Canvas.LineTo(428,428);



JP:=TBitmap.Create;
JP.Assign(Image2.Picture.Graphic );
end;

procedure TForm1.Image2Click(Sender: TObject);
begin
image2.Width :=1326;
image2.Height :=916;
Image2.Picture.Assign(nil);
image2.Canvas.StretchDraw(Rect(0,0,1326,916),JP);

end;

procedure TForm1.Image2DblClick(Sender: TObject);
begin
image2.Width :=663;
image2.Height :=458;
Image2.Picture.Assign(nil);
image2.Canvas.StretchDraw(Rect(0,0,663,458),JP);
end;

end.
 
在内存中绘图,然后在画到你要画的地方,每次重绘都以这个内存中的位图为源就好了
 
在内存中绘图?怎么做?能不能说的详细点。
 
你的
type
TMyPix=Class
PixX:integer;
PixY:integer;
end;
好象没用到。而且定义成 Class 不好,Class主要是要封装一些东西、显示一些东西、执行一些东西...在使用时也麻烦,var myPix1:TMyPix; myPix1:=TMyPix.Create; ....
什么都没做最好用 Record
type
TMyPix=Record PixX,PixY:integer; end;
其实你的 TmyPix 跟 Delphi 的 TPoint 是一样的,干吗不用它。
 
画到内存:
procedure DrawToImage(toImage:TImage);
var tmpBitmap:TBitmap;
begin
tmpBitmap:=TBitmap.Create;
tmpBitmap.Width:=toImage.Width;
tmpBitmap.Height:=toImage.Height;
with tmpBitmap.Canvas do
begin
MoveTo(0,0);
LineTo(100,100);
end;
toImage.Picture.Bitmap.Assign(tmpBitmap);
tmpBitmap.Free;
end;
 
type
TMyPix=Class
PixX:integer;
PixY:integer;
end;
这个类现在做测试,只放了两个属性,以后还要放放其他的属性,要定义一个数组,类型是TMyPix。

MPixArr: array of TMyPix;
这是一组数据,里面是坐标和其他一些信息,判断如果鼠标在Image2中的坐标和MPixArr中的某一个相同,就显示MPixArr的一些信息。

因为这个问题不涉及到这方面,就没有贴这些代码。
 
画到内存:
procedure DrawToImage(toImage:TImage);
var tmpBitmap:TBitmap;
begin
tmpBitmap:=TBitmap.Create;
tmpBitmap.Width:=toImage.Width;
tmpBitmap.Height:=toImage.Height;
with tmpBitmap.Canvas do
begin
MoveTo(0,0);
LineTo(100,100);
end;
toImage.Picture.Bitmap.Assign(tmpBitmap);
tmpBitmap.Free;
end;

-------------------------------------------------------------------
这种方法我也试过,现在的问题是我的Image要求是按比例缩放,就是对于已有的图片,随着图片的放大,画的线也要加粗,效果就是Canvas.StretchDraw的效果,但这样效率太低。
并且这样做还有其他一个问题,就是我要在Image2MouseMove事件中判断鼠标点的位置,这样当鼠标在进入、离开要判断的坐标点内时,鼠标明显停顿,CPU占用率很高。这个问题的描述是http://www.delphibbs.com/delphibbs/dispq.asp?lid=3078742
Image2MouseMove代码如下:
Image3.Visible:=false;
if ((X-MPixArr[j].PixX*B<=10) and (X-MPixArr[j].PixX*B >=-10)) then
if ((Y-MPixArr[j].PixY*B<=10) and (Y-MPixArr[j].PixY*B >=-10)) then
begin
image3.Left :=(MPixArr[j].PixX*B-9*B)+Image2.Left;
image3.Top :=(MPixArr[j].PixY*B-9*B)+Image2.Top;
image3.Visible :=true;
Form2.Label1.Caption :='&amp;micro;±&amp;Ccedil;°&amp;micro;&amp;atilde;&amp;micro;&amp;Auml;&amp;Icirc;&amp;raquo;&amp;Ouml;&amp;Atilde;&amp;pound;&amp;ordm;' + IntToStr(MPixArr[j].PixX) + ',' + IntToStr(MPixArr[j].PixY );
Break;
end;
 
CPU占用率很高
-------------------------------------------------------------------------
你这个循环比较耗时,在循环里加上sleep(0)

或者根本不用循环,改用PtInRect,这个一次就能够判断鼠标当前点的范围了
 
或者根本不用循环,改用PtInRect,这个一次就能够判断鼠标当前点的范围了
----------------------------------------------------------------------
我的Image上有很多要判断的点啊。
 
接受答案了.
 
后退
顶部