简体   繁体   English

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

[英]After assigning nil to TImage.Picture.Graphic to clear the picture, how can I use it again?

In the code below, I clear the Picture in btnSaveClick, later in btnLoadClick I want to assign a picture to the image, but it gives an AV because the Graphic object does not exist. 在下面的代码中,我清除btnSaveClick中的图片,稍后在btnLoadClick中我想为图像分配图片,但它给出了AV,因为Graphic对象不存在。

How can I accomplish the task? 我怎样才能完成任务?

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;

If you're loading from a file with an extension which corresponds with a registered image class you can simply do: 如果您从具有与注册图像类对应的扩展名的文件加载,您可以简单地执行以下操作:

Picture.LoadFromFile(FileName);

Otherwise you can create an instance of a specific TGraphic descendant (depending on what type of graphic you're using) in code and assign it to Graphic property, eg for JPEG: 否则,您可以在代码中创建特定TGraphic后代的实例(取决于您正在使用的图形类型)并将其分配给Graphic属性,例如对于JPEG:

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

Instead doing 相反做

Image1.Picture.Graphic := nil;

You could do: 你可以这样做:

Image1.Visible:= false;

or 要么

Image1.Picture.Assign(HiddenImage2.Picture);

Where HiddenImage2 is a blank TImage. 其中HiddenImage2是一个空白的TImage。

You have to tell TPicture what TGraphic class to use before you can load data into it. 您必须告诉TPicture在将数据加载到其中之前要使用的TGraphic类。 If you only have 1 graphic type you use, then you can hard-code it, eg: 如果您只使用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; 

However, If you use multiple graphic types, then you have to store the image type in the file and read it back so you can create the correct class object, eg: 但是,如果使用多种图形类型,则必须将图像类型存储在文件中并将其读回,以便创建正确的类对象,例如:

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; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM