delphi控件Image加载图片问题

在加载大图片的时候怎么判断图片已经加载完成,能提供代码更加感谢……... 在加载大图片的时候怎么判断图片已经加载完成,能提供代码更加感谢…… 展开
 我来答
至少让我看一眼
2013-12-29 · TA获得超过451个赞
知道小有建树答主
回答量:188
采纳率:0%
帮助的人:241万
展开全部

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;
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式