将nil分配给TImage.Picture.Graphic以清除图片后,我该如何再次使用它?

时间:2011-08-25 13:14:45

标签: delphi

在下面的代码中,我清除了btnSaveClick中的图片,稍后在btnLoadClick中我想为图片分配图片,但它提供了一个AV,因为Graphic对象不存在。

我该如何完成任务?

procedure TForm1.btnSaveClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  buf: TBytes;
  z:  integer;
begin
  fs := TFileStream.Create('c:\temp\a.my', fmCreate);
  s  := TMemoryStream.Create;
  try
    Image1.Picture.Graphic.SaveToStream(s);
    z := s.Size;
    SetLength(buf, z);
    s.Position := 0;
    s.ReadBuffer(buf[0], z);

    fs.WriteBuffer(z, SizeOf(integer));
    fs.WriteBuffer(buf[0], z);
  finally
    s.Free;
    fs.Free;
  end;

  ShowMessage('ok');

  Image1.Picture.Graphic := nil;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  buf: TBytes;
  z:  integer;
  gc: TGraphicClass;
begin
  fs := TFileStream.Create('c:\temp\a.my', fmOpenRead);
  s  := TMemoryStream.Create;
  try
    fs.ReadBuffer(z, SizeOf(integer));
    SetLength(buf, z);
    fs.ReadBuffer(buf[0], z);
    s.WriteBuffer(buf[0], z);
    s.Position := 0;

    Image1.Picture.RegisterFileFormat('jpg', 'jpeg files', gc);
  //  Image1.Picture.Graphic.LoadFromStream(s);  <-- AV here. Whats the proper way to do it?

  finally
    s.Free;
    fs.Free;
  end;

  ShowMessage('ok');

end;

3 个答案:

答案 0 :(得分:4)

如果您从一个扩展名与已注册图像类相对应的文件中加载,您只需执行以下操作:

Picture.LoadFromFile(FileName);

否则,您可以在代码中创建特定TGraphic后代的实例(取决于您使用的图形类型)并将其分配给Graphic属性,例如对于JPEG:

var
  Graphic: TJpegImage;
begin
  Graphic := TJpegImage.Create;
  try
    Graphic.LoadFromFile(FileName);
    Picture.Graphic := Graphic;
  finally
    Graphic.Free;
  end;
end;

答案 1 :(得分:2)

反而做

Image1.Picture.Graphic := nil;

你可以这样做:

Image1.Visible:= false;

Image1.Picture.Assign(HiddenImage2.Picture);

HiddenImage2是空白的TImage。

答案 2 :(得分:2)

你必须告诉TPicture在你可以加载数据之前要使用什么TGraphic类。如果您只使用1种图形类型,则可以对其进行硬编码,例如:

procedure TForm1.btnSaveClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  z:  integer;
begin
  s := TMemoryStream.Create;
  try
    Image1.Picture.Graphic.SaveToStream(s);
    fs := TFileStream.Create('c:\temp\a.my', fmCreate);
    try
      z := s.Size;
      fs.WriteBuffer(z, SizeOf(integer));
      s.Position := 0;
      fs.CopyFrom(s, z);
    finally
      fs.Free;
    end;
  finally
    s.Free;
  end;
  ShowMessage('ok');
  Image1.Picture.Graphic := nil;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  z:  integer;
  jpg: TJPEGImage;
begin
  s := TMemoryStream.Create;
  try
    fs := TFileStream.Create('c:\temp\a.my', fmOpenRead);
    try
      fs.ReadBuffer(z, SizeOf(integer));
      s.CopyFrom(fs, z);
    finally
      fs.Free;
    end;
    jpg := TJPEGImage.Create;
    try
      s.Position := 0;
      jpg.LoadFromStream(s);
      Image1.Picture.Graphic := jpg;
    finally
      jpg.Free;
    end;
  finally
    s.Free;
  end;
  ShowMessage('ok');
end; 

但是,如果使用多种图形类型,则必须将图像类型存储在文件中并将其读回,以便创建正确的类对象,例如:

procedure TForm1.btnSaveClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  z:  integer;
  str: AnsiString;
begin
  str := Image1.Picture.Graphic.ClassName;
  s := TMemoryStream.Create;
  try
    Image1.Picture.Graphic.SaveToStream(s);
    fs := TFileStream.Create('c:\temp\a.my', fmCreate);
    try
      z := Length(str);
      fs.WriteBuffer(z, SizeOf(integer));
      fs.WriteBuffer(Str[1], z);
      z := s.Size;
      fs.WriteBuffer(z, SizeOf(integer));
      s.Position := 0;
      fs.CopyFrom(s, z);
    finally
      fs.Free;
    end;
  finally
    s.Free;
  end;
  ShowMessage('ok');
  Image1.Picture.Graphic := nil;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
var
  fs: TFileStream;
  s:  TMemoryStream;
  z:  integer;
  str: AnsiString;
  g:  TGraphic;
begin
  s := TMemoryStream.Create;
  try
    fs := TFileStream.Create('c:\temp\a.my', fmOpenRead);
    try
      fs.ReadBuffer(z, SizeOf(integer));
      SetLength(str, z);
      fs.ReadBuffer(str[1], z);
      fs.ReadBuffer(z, SizeOf(integer));
      s.CopyFrom(fs, z);
    finally
      fs.Free;
    end;
    g := TGraphicClass(FindClass(str)).Create;
    try
      s.Position := 0;
      g.LoadFromStream(s);
      Image1.Picture.Graphic := g;
    finally
      g.Free;
    end;
  finally
    s.Free;
  end;
  ShowMessage('ok');
end;