我用了一个image控件,在image.canvans上画了一段曲线,但是这幅曲线要定时更新。请问我更新前,怎么把先前画的曲线擦除?同事说,vb里有专门的清屏语句,不知道delphi里有没有?
   请各位大侠指点迷津阿!

解决方案 »

  1.   

    建立一个临时变量,保存每一步的上一步Image,就很容易恢复了。
      

  2.   

    怎么保存每一步的上一步Image?什么意思?比如下面的用xexch[i]存入每点x坐标,mexch[i]存入每点y坐标,那什么是上一步Image?
    procedure TForm1.drawtest();
    var
      i:integer;
      x0:integer;                     
      y0:=integer;
      xexch: array[0..11]of integer;  
      mexch: array[0..11]of integer;  
    begin
      x0:=0;                     
      y0:=0;
      for i:=0 to 11 do
      begin
      xexch[i]:=x0;
      mexch[i]:=y0;
      x0:=x0+10;
      y0:=y0+10;
      end;  for i:=0 to 10 do
      begin
        image1.Canvas.MoveTo(xexch[i],mexch[i]);
        image1.Canvas.LineTo(xexch[i+1],mexch[i+1]);
        //连接各点画出曲线
      end;
    end;
      

  3.   

    HeLiang7(阿亮) :能否给个例子?
      

  4.   

    with Image1.Canvas do
    begin
      Brush.Color := clWHite;      //白色
      FillRect(Image1.ClientRect); //用白色填充
      ...下面画线
    end
      

  5.   

    TO:SeaWave(NoSound
    这样的方法我也想到过,可是,这只是用背景色把原先的曲线盖住了,我的定时器十秒钟更新
    一次,这样子的话,会不会出问题,这方法很笨也不科学啊
      

  6.   

    回复:阿亮
    谢谢你在百忙中,给我回复,不过我还是不太明白,可能我是初学者的原因,如果大侠不闲麻烦的话,能否在写得详细点,我在定时器计时procedure 中该怎么写。type
      ....
      tmimage:timage;
      ...
    procedure tform1.drawline();
    var
      i:integer;
      xexch: array[0..11]of integer;  
      mexch: array[0..11]of integer;  
    begin
      
    for i:=0 to 10 do
      begin
        tmimage[i] := image1
        image1.Canvas.MoveTo(xexch[i],mexch[i]);
        image1.Canvas.LineTo(xexch[i+1],mexch[i+1]);
        //连接各点画出曲线
      end;
    end;
    procedure tform1.timr1ontimer(...);
    begin
    end;
      

  7.   

    同意 SeaWave(NoSound),“这只是用背景色把原先的曲线盖住了”,不是盖住,是相当于直接改颜色是通常使用的做法啊
      

  8.   

    你们说的那种方法根本不好
    因为,做这个程序,不可能背景什么也没有!!!
    让你擦来擦去,那背景呢?
    给些有建设性的方法
    我等了很多天了
    ------------
    如果说背景不是单色,而是一幅图片,那也只怪你提问的时候没有说清楚。但是原理是一样,画一个BITMAP到画布上也花不了多少时间。
    说用某个色彩填充背景(FillRect)的方法不科学,那么我真不知道科学的方法是什么了
      

  9.   

    回复楼上:
    说用某个色彩填充背景(FillRect)的方法不科学,那么我真不知道科学的方法是什么了
    ----------------------
    是这样,我用了两个Timage重叠放置,上的transparent:=true;
    如果不用擦除,fillrect会挡住下面的图,就是这么简单的原因
    所以不能用fill的方法,我想用擦线的方法最好,还有
    画bitmap到花布用不了多少时间是不假,但是在存在高像素,或高彩的时候,而且图像稍微一多,马上就能感觉到,
      

  10.   

    假设你用的两层image
    image1和image2
    1是顶层,2是底层
    RubberSize、Pic_X、Pic_Y是我自己设的变量
    分别是image的大小和鼠标的位置
    如果你想全部擦除,改变Pic_X、Pic_Y的值就行了Procedure TForm1.ClearUp;
    Var
       Bmp              : TBITMAP;
    Begin
       Bmp := TBitmap.Create;               //创建位图
       Bmp.PixelFormat := Image2.Picture.Bitmap.PixelFormat; //设置位图格式
       Bmp.Width := RubberSize;             //设置位图大小
       Bmp.Height := RubberSize;
       BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
          Image2.Picture.Bitmap.Canvas.Handle, Pic_X - 5, Pic_Y -
          5, SRCCOPY);                      //从地层拷贝位图到位图,
       Image1.Canvas.Draw(Pic_X - 5, Pic_Y - 5, Bmp);  //复制位图到顶层相应位置,达到擦除效果
       Bmp.Free;
    End;记得打开image容器的DoubleBuffered 例如
    panel1.DoubleBuffered := True;  //打开双缓冲,避免闪烁
      

  11.   

    全部清除的代码var
       Bmp              : TBITMAP;
    Begin
       Bmp := TBitmap.Create;               //创建位图
       Bmp.PixelFormat := Image2.Picture.Bitmap.PixelFormat; //设置位图格式
       Bmp.Width := Image1.Width;             //设置位图大小
       Bmp.Height := Image1.Height;
       BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height,
          Image2.Picture.Bitmap.Canvas.Handle, 0,0, SRCCOPY); //从地层拷贝位图到位图,
       Image1.Canvas.Draw(0, 0, Bmp);  //复制位图到顶层相应位置,达到擦除效果
       Bmp.Free;
    end;
      

  12.   

    前一段代码是具有橡皮擦功能的根据鼠标的位置来擦除部分线但是这样有个问题就是如果你的image大小不是bmp的原始大小的话坐标会出现偏差这就需要你自己做一下坐标转换了其实也很简单,就是初中的坐标轴的缩放和平移了
      

  13.   

    image.Picture:=nil;
    image.repaint;
      

  14.   

    快是指无闪烁么?可以只针对上一次曲线经过的点做操作,但需要额外的计算量。
    array(x,y,color)
    第一次画的时候:(x,y)纪录该点,color=该点原色 XOR 画笔颜色
    下一次画之前:(x,y)点颜色=color XOR 画笔颜色