让我们做一个试验,只有简单的2条语句
语句一: image1.picture.loadfromfile('c:/windows/desktop/test.jpg');
语句二: image2.picture.graphic:=image1.picture.bitmap;
根据上面的说法,如果Loadfromfile一个jpg图片,会自动产生一个相应的bitmap,
那么image2应该显示image1的图片,对不对?
执行结果:
如果只执行第一句,image1显示正常,如果执行第二句,两个图片均不能显示
图片.
现在我们跟踪一下delphi是怎样处理这2条语句的:
<b>语句一:</b>
//Picture的Loadfromfile函数,跟踪如下:
procedure TPicture.LoadFromFile(const Filename: string);
var
Ext: string;
NewGraphic: TGraphic;
GraphicClass: TGraphicClass;
begin
Ext := ExtractFileExt(Filename); //得到文件后缀名jpg
Delete(Ext, 1, 1);
GraphicClass := FileFormats.FindExt(Ext); //通过后缀名得到类名TJpegimage
NewGraphic := GraphicClass.Create; //相当于Tjpegimage.create
try
...
NewGraphic.LoadFromFile(Filename); //调入文件stream
except
...
end;
FGraphic.Free;
FGraphic := NewGraphic; //相当于Fgraphic:=TJpegimage.create
... //现在FGraphic是Jpageimage
//而且没有涉及任何bitmap的操作
end;
<b>语句二:</b>
//首先,因为我们访问了image1的picture.bitmap属性,
//所以首先跟踪到了Bitmap属性的read方法: GetBitmap
function TPicture.GetBitmap: TBitmap;
begin
ForceType(TBitmap); //将Graphic类型强制转换成Bitmap
Result := TBitmap(Graphic);
end;
//继续跟踪ForceType
procedure TPicture.ForceType(GraphicType: TGraphicClass);
begin
if not (Graphic is GraphicType) then //如果Graphic不是TBitmap
begin
FGraphic.Free; //释放原先的Graphic
FGraphic := nil;
FGraphic := GraphicType.Create; //相当于TBitmap.create
.... //现在FGraphic是TBitmap,
end; //而且没有内容
end;
//现在开始设置image2的graphic属性,也就是Picture.SetGraphic
procedure TPicture.SetGraphic(Value: TGraphic);
var
NewGraphic: TGraphic;
begin
NewGraphic := nil;
if Value &lt;&gt; nil then //Value应该是TBitmap
begin
NewGraphic := TGraphicClass(Value.ClassType).Create; //TBitmap.create
NewGraphic.Assign(Value);
...
end;
try
FGraphic.Free; //释放原先的Graphic
FGraphic := NewGraphic; //相当于TBitmap.create
...
except
...
end;
end;
现在基本可以看出,当我们用Picture.Loadfromfile调入一个jpg图片的时候,
并没有'自动..解压,同时把..bmp对象存放..bitmap属性中',而只有当你访问
图片的Bitmap这个属性的时候,才临时强制性地把Graphic转换成bitmap类型,
而且,这样的Bitmap根本没有内容,不能使用.
不知道我说的对不对?