ペイントボックスがあり、次のように TBitmap を描画します。
procedure MyForm.PaintBoxPaint(Sender: TObject); // ONPAINT
begin
PaintBox.Canvas.Lock;
MyBitMap.Canvas.Lock;
PaintBox.Canvas.Draw(0, 0, MyBitMap);
PaintBox.Canvas.UnLock;
MyBitMap.Canvas.UnLock;
end;
PaintBox から JPEG または BMP を「マップ」/「コピー」したいと思います。最初に考えなければならない課題がいくつかあります。まず、WidePath/WideFileName をサポートするファイルに JPEG または BMP を保存したいと考えています。私は Delphi 7 を使用しており、.SaveToFile プロシージャは AnsiPaths/AnsiFileNames のみをサポートしています。次は「MainGUIスレッド」から独立したコピーを作りたいということです。そのため、バックグラウンドでコピーを保存している間、GUI は引き続きアクティブで、ペイントボックスに描画する必要があります (したがって、TTimer ではありません)。最後は「コピー」の実際のファイル名です。1.jpg ... から 2.jpg ... から N.jpg になるカウンターを設定したいと思います。問題は、関数がカウンターをインクリメントしようとするたびにアクセス違反が発生する可能性がある Integer のカウントです。
私のアイデアは次のとおりです。
保存スレッドの構造:
type
PTRTSaveImage = ^TSaveImage;
TSaveImage = record
Number : Integer;
Pic : TBitMap;
end;
実際の SaveImageThread:
function SaveImageToHDD ( p : pointer ) : Integer; stdcall;
var
jpg : TJpegImage;
jpgStr : TStringStream;
_infos : TSaveImage;
begin
CopyMemory(@_infos, p, SizeOf(_infos));
jpg := TJpegImage.Create;
jpgStr := TStringStream.Create ('');
jpg.assign (_infos.Pic);
_infos.Pic.Free;
jpg.SaveToStream(jpgStr);
jpg.Free;
StrToFile ('C:\' + inttostr(_infos.Number) + '.jpg',0,jpgStr.DataString); // for WidePath/WideFileName Support.
jpgStr.Free;
end;
それが私がスレッドを呼び出す方法です:
procedure MyForm.PaintBoxPaint(Sender: TObject); // ONPAINT
var
Saving : PTRTSaveImage;
BackUp : TBitMap;
begin
PaintBox.Canvas.Lock;
MyBitMap.Canvas.Lock;
PaintBox.Canvas.Draw(0, 0, MyBitMap);
BackUp := TBitMap.Create;
BackUp.Assign (MyBitMap); // Immediate copy of the actual drawing!
Saving := PTRTSaveImage(LocalAlloc(LPTR, SizeOf(TSaveImage)));
Saving^.Pic := BackUp;
Saving^.Number := Counter;
inc (Counter);
PaintBox.Canvas.UnLock;
MyBitMap.Canvas.UnLock;
end;
数枚の写真は問題なく撮れますが、デバッガーは例外を表示します:
Debugger Fault Notification プロジェクト C:....exe がメッセージで失敗しました: 'アプリケーション定義の例外 (コード 0x0eedfade) at 0x759d9617'。プロセスが停止しました。Step または Run を使用して続行します。
これを行う「より良い方法」はありますか?保存と描画が同時に…!?
ご協力いただきありがとうございます。
編集:
次に、次のような TTimer の代わりに 1 つのスレッドを作成することも考えました。
function SaveImages ( p : TMyForm ) : Integer; stdcall
var
jpg : TJpegImage;
jpgStr : TStringStream;
begin
while true do begin // ---> constant LOOP that saves pictures in the intervall
sleep (1000); // Intervall
jpg := TJpegImage.Create;
jpg.assign (p.MyBitMap);
jpgStr := TStringStream.Create ('');
jpg.SaveToStream(jpgStr);
jpg.Free;
StrToFile ('C:\' + inttostr(p.Counter) + '.jpg',0,jpgStr.DataString); // for WidePath/WideFileName Support.
inc (p.Counter);
jpgStr.Free;
end;
end;
しかし、同じエラー/例外が発生します。