gpt4 book ai didi

delphi - TPaintBox 到 JPEG/BMP - 缓冲区

转载 作者:行者123 更新时间:2023-12-03 15:58:29 28 4
gpt4 key购买 nike

我有一个颜料盒,我画了一个 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)。最后一件事是“副本”的实际文件名。我想设置一个从 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;

但发生了同样的错误/异常。

最佳答案

AVI 文件...我确实想知道...我会创建一个从 TPaintBox 派生的新 Paintbox 控件。 (您可能已经这样做了?)

向其中添加一个计数器属性和代码,使用 BitBlit 将 Canvas 捕获为 Bmp,然后创建一个线程来将位图转换并保存为 jpg,并在计数器启动时递增计数器。 (您将需要对该调用使用 Synchronize)。将其命名为 CaptureCanvas。

最后添加一个名为 afterChange 或 afterTimePeriod 的方法来调用 captureCanvas。确保您尝试过...最后,确保如果保存出现任何问题,位图和 Jpeg 都会被破坏。然后它都在一个地方(在 TNewPaintbox 内,如果它落后了,那么正在创建的图像已经有了它们的索引,你不会乱序保存它们......只是一个想法:)

抱歉,本意是添加表单代码,然后将简化为:

Form1.Paintboxpaint()
begin
.
.
PaintBox.Canvas.Draw(x, y, bitmap);
Paintbox.AfterChange;
.

抱歉简洁,编辑答案,看不到原帖

关于delphi - TPaintBox 到 JPEG/BMP - 缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11103975/

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