Delphi:无法在Panel的画布上绘制

时间:2015-02-13 01:26:14

标签: image delphi canvas draw

我正在尝试在此面板的过程中在TPanel的Canvas上绘制图像。当我在Panel的Paint Method中执行此操作时,它工作正常,但是当我尝试在另一个过程或构造函数中绘制Canvas时,没有任何反应。

这是我在Paint Procedure中绘制Panel的画布的方法:

procedure TFeld.Paint;
var bmp : TBitmap;
begin
  inherited;
  bmp := TBitmap.Create;
  try
    bmp.LoadFromFile('textures\ground.bmp');
    self.Canvas.Draw(0,0,bmp);
  finally
    bmp.Free;
  end;
end;

这就是我尝试在另一个程序中使用它的方法:

procedure TFeld.setUnsichtbar;
var bmp : TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.LoadFromFile('textures\invisible.bmp');
    self.Canvas.Draw(0,0,bmp);
  finally
    bmp.Free;
  end;
end;

但Panel的Canvas仍然是我在Paint程序中应用的图像。

我已经尝试将绘图从Paint过程移动到无效的构造函数。

路径也正确,切换路径,现在面板上有'invisible.bmp'图像。

全班/单位:http://pastebin.com/YhhDr1F9

知道为什么这不起作用?

1 个答案:

答案 0 :(得分:0)

看着你的全班我想你想要根据某种条件控制哪个图像在哪个时间显示。正确?

如果是这种情况,您需要的第一件事就是让您的班级有一个用于存储图像数据的字段。在上面的示例中,您只使用bmp文件,因此TBitmap就足够了。但是,如果你正在使用其他图片类型,你可能想要使用TPicture字段,因为这个将所有支持的图片图片加载为你也尝试使用组件的TImage。

然后你改变组件的Paint方法,使用上面提到的字段来获取图片数据,而不是每次都像现在一样创建本地图片数据变量。
事实上,你现在正在做的事情非常糟糕,因为你每次渲染组件时都强迫你的应用程序将文件中的图像数据读入内存。这可能会导致糟糕的表现。

最后,当您想要更改组件上显示的图片时,只需在图片区域中加载不同的图片。

因此,通过上述更改,您的类应该如下所示:

type 
  TFeld=class(TPanel)
  protected
    procedure Paint;override;
    procedure BitmapChange(Sender: TObject);
  private
    zSichtbar : Boolean;
    zPosHor,zPosVer : Integer; // Position im Array
    zEinheit  : TEinheit;
    Bitmap: TBitmap; //Field for storing picture data
  public

//    hImage    : TImage;

    constructor Create(pX,pPosHor,pY,pPosVer,pHoehe,pBreite:integer;pImgPath:String;pForm:Tform); virtual;
    destructor Destroy;
    procedure ChangeImage(pImgPath: String);
  end;

...

implementation

constructor TFeld.Create(pX,pPosHor,pY,pPosVer,pHoehe,pBreite:integer;pImgPath:String;pForm:Tform);
begin
  inherited create(pForm);

  ...

  //Creater internal component for storing image data
  Bitmap := TBitmap.Create;
  //Assign proper method to Bitmaps OnChange event
  Bitmap.OnChange := BitmapChange;
  //Load initial image data
  Bitmap.LoadFromFile(pImgPath);

  ....

end;

destructor Destroy;
begin
  //We need to destroy the internal component for storing image data before 
  //we destory our own component in order to avoid memory leaks
  Bitmap.Free;
end;

procedure TFeld.Paint;
begin
  inherited;
  //Use local image field to tell the Paint method of what to render
  self.Canvas.Draw(0,0,Bitmap);
end;

procedure TFeld.BitmapChange(Sender: TObject);
begin
  //Force redrawing of the component on bitmap change
  self.Invalidate;
end;

procedure TFeld.ChangeImage(pImgPath: String);
begin
  //Load different image into image field
  Bitmap.LoadFromFile(pImgPath);
end;

编辑:添加必要的代码以在位图更改后强制重新绘制组件。