gpt4 book ai didi

multithreading - 如何通过多线程绘画到 TBitmap

转载 作者:行者123 更新时间:2023-12-03 19:30:52 27 4
gpt4 key购买 nike

为了加快在 Delphi XE2 中绘制位图,我决定采用以下方式

a)创建一个例如。 10 x 线程并仅在线程类内绘制一层位图
b)一旦所有线程完成,使用bitblt函数逐层合并位图

我做了以下实验代码

unit Unit_BitmapThread;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Data.Win.ADODB, ActiveX;



type PaintBitmapThread = class(TThread)

private

FBitmap : TBitmap;
FConnection : TAdoConnection;
fserver, fdatabasename, ftablename, fsqlstr : String;
protected
procedure Execute; override;
public
constructor Create ( bmp_width, bmp_height : Integer; server, databasename, tablename, sqlstr : String; ThreadId : Integer );
destructor destroy ; override;

end;



type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
FAdoConnection : TAdoConnection;
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i : Integer;
aPaintBitmapThread : PaintBitmapThread;
begin
for i := 1 to 10 do
begin
aPaintBitmapThread :=PaintBitmapThread.Create(100,100,'server','database','table','select *',1);
end;
end;

{ PaintBitmapThread }

constructor PaintBitmapThread.Create(bmp_width, bmp_height: Integer;
server, databasename, tablename, sqlstr: String; ThreadId: Integer);
begin
FBitmap :=TBitmap.create;
FConnection :=TAdoConnection.Create(nil);
end;

destructor PaintBitmapThread.destroy;
begin
FBitmap.Free;
FConnection.Free;
inherited;
end;

procedure PaintBitmapThread.Execute;
var
ThreadQuery : TADOQuery;
k : integer;
begin
inherited;

CoInitialize(nil) ; //CoInitialize was not called

ThreadQuery := TADOQuery.Create(nil) ;
try
// ADO DB THREAD MUST USE OWN CONNECTION
ThreadQuery.Connection := FConnection;
// ThreadQuery.ConnectionString := '????';
// ThreadQuery.CursorLocation := clUseServer;
// ThreadQuery.LockType := ltReadOnly;
// ThreadQuery.CursorType := ctOpenForwardOnly;
ThreadQuery.SQL.Text := FSQLStr;

// ThreadQuery.Open;
while NOT ThreadQuery.Eof and NOT Terminated do
begin



//Canvas Does NOT Allow Drawing if not called through Synchronize
//Synchronize(RefreshCount) ;

ThreadQuery.Next;
end;
finally
ThreadQuery.Free;
end;

CoUninitialize()
end;
end.

Q : a) 10 条涂装线全部完成后如何检测?
b)如何访问线程[i]并将位图获取到主程序(VCL)进行合并?

最好的解决方案是
if Thread[1] and Thread[2] finished -> newBMP :=  Bitblt( bmp1, bm2);

if also Thread[3]finished -> newBMP := Bitblt( newBMP, bm3);
unit all threads-Bitmaps are merged

最佳答案

a) How to detect once all 10 painting threads are finished and b) How to access the thread[i] and get the bitmap to the main program (VCL) for merging?



添加 OnTerminate每个线程的事件处理程序。这将在主线程上执行。合并此事件处理程序中的位图。因为它在主线程上执行,所以需要注意同步。

如果事件处理程序是线程类的方法,那么它可以访问线程的私有(private)位图对象。

或者,如果您不想使用事件处理程序,请覆盖 DoTerminate并从那里同步合并方法。

关于multithreading - 如何通过多线程绘画到 TBitmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24274279/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com