1个回答
展开全部
Delphi的TImage控件在加载图片的时候,采用的是同步加载的方式。也就是主线程会一直处于阻塞状态,直到TImage.Picture.LoadFromFile加载完毕为止。也就是说,如果你的代码运行到了LoadFromFile之后就代表图片已经加载完成了。当然,因为是同步加载,所以主线程在加载图片时,完全没有机会重绘窗口。所以加载大图片时可能会有卡顿。
如果你确信你需要加载的图片的体积非常大(图片至少要大于5MB)以上,需要异步地加载图片。你可以创建一个新线程,并在这个线程里创建一个TPicture,然后使用TPicture.LoadFromFile(Stream)来加载图片。然后再这个新线程运行完成后,再经由TImage.Picture := 你在线程中创建的Picture; 的方式来将加载完成的图片对象。
示例代码如下:
const
CM_LoadComplete = WM_USER + 20;
type
TLoadThread = class(TThread)
protected
AnycPic: TPicture;
procedure Execute; override;
public
destructor Destroy; override;
end;
TfrmMain = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FThread: TLoadThread;
procedure CMLoadComplete(var Message: TMessage); message CM_LoadComplete;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
uses
jpeg, pngimage;
{$R *.dfm}
{ TfrmMain }
procedure TfrmMain.Button1Click(Sender: TObject);
begin
//开始用线程异步加载图像
if not Assigned(FThread) then
begin
FThread := TLoadThread.Create(True); FThread.Resume;
end
else
ShowMessage('图像正在加载中...');
end;
procedure TfrmMain.CMLoadComplete(var Message: TMessage);
begin
//TPicture异步加载完成,将其设置为Image1的Picture
Image1.Picture := FThread.AnycPic;
//终止线程
FThread.WaitFor; FreeAndNil(FThread);
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
if Assigned(FThread) then
begin
FThread.WaitFor; FThread.Free;
end;
end;
{ TLoadThread }
destructor TLoadThread.Destroy;
begin
AnycPic.Free; inherited;
end;
procedure TLoadThread.Execute;
begin
AnycPic := TPicture.Create;
AnycPic.LoadFromFile('D:\test1.jpg');
//如果图像是jpeg则先进行解码工作
if AnycPic.Graphic is TJPEGImage then
(AnycPic.Graphic as TJPEGImage).DIBNeeded;
//将图像提交至主线程,不要使用Synchronize函数,可能会导致主线程锁死
PostMessage(frmMain.Handle,CM_LoadComplete,0,0);
end;
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询