线程中的StretchDraw(149分)

  • 主题发起人 michael.ma
  • 开始时间
M

michael.ma

Unregistered / Unconfirmed
GUEST, unregistred user!
这是一个线程中的主方法,其作用是把一个jpg文件缩小为原来的一半,
循环共执行100次;
为什么程序运行时虚拟内存不断的增长,造成泄漏?
如果把Lock和UnLock方法去掉,则鼠标在主窗体上移动时则报错:out of
resorce,但这个线程只是在主线程中创建,并没有和主线程交互,为什么
会报错?
问题可能出现在StretchDraw这个方法上,
有更好的转图的方法吗?blt?请大家指教。
procedure a.Execute;
var
BmpSrc,BmpMid: TBitMap;
JpgDst: TJpegImage;
w, h, i: integer;
begin

self.FreeOnTerminate := true;
for i := 1 to 100do
begin
BmpSrc := TBitMap.Create;
BmpMid:=TBitMap.Create ;
JpgDst := TJpegImage.Create;
try
JpgDst.LoadFromFile('c:/bak/a.jpg');
BmpSrc.Assign(JpgDst);
w := BmpSrc.Width div 2;
h := BmpSrc.Height div 2;
BmpMid.Width :=w;BmpMid.Height :=h;
BmpMid.Canvas.Lock ;
BmpMid.Canvas.StretchDraw(Rect(0, 0, w, h), BmpSrc);
BmpMid.Canvas.Unlock ;
JpgDst.Assign(BmpMid);
JpgDst.SaveToFile('c:/bak/' + inttostr(i) + '.jpg');
finally
Bmpsrc.Free;
BmpMid.Free ;
JpgDst.Free;
end;
sleep(200);
end;
end;
 
VCL不是线程安全的,不要把包含VCL的代码放在Execute中,应该用Synchronize();
procedure a.mydraw;
begin
你的代码
end;
procedure a.Execute;
begin
Synchronize(mydraw);
end;
 
可视的vcl才要synchronize,bitmap不需要吧,况且bitmap没有和主窗体交互啊
 
而且上面只是一个线程,并没有多个线程;当我用鼠标单击窗体的时候,我就看到任务
管理器中的虚拟内存不停的增加(造成bitmap不能释放),但单击窗体为什么会影响到
正在执行的线程呢?太奇怪了。当然,我去掉了stretchdraw一句后无论怎样单击窗体内存也不增长。
 
用Synchronize,去掉sleep(200),没有问题,我试过了。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Jpeg;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TConvertThread = class(TThread)
private
//index : LongInt;
protected
procedure Execute;
override;
procedure MakePictures;
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TConvertThread.MakePictures;
var
BmpSrc,BmpMid: TBitMap;
JpgDst: TJpegImage;
w, h, i: integer;
begin

FreeOnTerminate := true;
for i := 1 to 100do
begin
BmpSrc := TBitMap.Create;
BmpMid:=TBitMap.Create ;
JpgDst := TJpegImage.Create;
try
JpgDst.LoadFromFile('c:/bak/a.jpg');
BmpSrc.Assign(JpgDst);
w := BmpSrc.Width div 2;
h := BmpSrc.Height div 2;
BmpMid.Width :=w;
BmpMid.Height :=h;
BmpMid.Canvas.Lock ;
BmpMid.Canvas.StretchDraw(Rect(0, 0, w, h), BmpSrc);
BmpMid.Canvas.Unlock ;
JpgDst.Assign(BmpMid);
JpgDst.SaveToFile('c:/bak/' + inttostr(i) + '.jpg');
finally
Bmpsrc.Free;
BmpMid.Free ;
JpgDst.Free;
end;
//sleep(200);
end;
end;

procedure TConvertThread.Execute;
begin
Synchronize(MakePictures);
end;

procedure TForm1.Button1Click(Sender: TObject);
var ConvertThread: TConvertThread;
begin
ConvertThread:= TConvertThread.Create(true);
ConvertThread.FreeOnTerminate := true;
ConvertThread.Resume;
end;

end.
 
接受答案了.
 

Similar threads

顶部