我有一个油漆盒,我画了一个像这样的 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。我必须首先考虑一些挑战。第一件事是我想将 JPEG 或 BMP 保存到支持 WidePath/WideFileName 的文件中。我使用 Delphi 7 和 .SaveToFile 程序只支持 AnsiPaths/AnsiFileNames。接下来是我想制作一个独立于“MainGUI Thread”的副本。因此,当 GUI 将副本保存在后台时(所以没有 TTimer),GUI 应该仍然处于活动状态并绘制到画框。最后一件事是“副本”的实际文件名。我想设置一个从 1.jpg ... 到 2.jpg ... 到 N.jpg 的计数器 问题是整数的计数,由于每个函数都试图增加计数器,这可能导致访问冲突。
我的想法如下:
保存线程的结构:
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;
它拍了几张照片就好了,但是调试器向我显示了一个异常:
调试器故障通知项目 C:....exe 出现错误消息:“应用程序定义的异常(代码 0x0eedfade)在 0x759d9617”。进程停止。使用 Step 或 Run 继续。
有没有“更好的方法”来做到这一点?同时保存和绘图...?!
谢谢你的帮助。
编辑:
然后我还考虑只制作 1 个线程来代替 TTimer,如下所示:
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;
但会发生相同的错误/异常。