在下面的代码中,我清除了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;
答案 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;