gpt4 book ai didi

delphi - 在 TThread 中将 Jpeg 保存为 base64

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

我在使用 Delphi 时遇到一些问题。

我编写了两个简单的函数来制作屏幕截图,将其转换为 jpeg 并解码为 Base64 流。如果我把它放在主流节目上,它的效果会很好。但是,如果我创建一个 TThread 类并在执行时启动此函数,Windows 将卡住,我只能重新启动我的电脑。

经过多次尝试,我发现通过程序JpegImg.SaveToStream(Input);挂起PC;如果我不将位图转换为 jpeg,它的效果很好,并且我得到图像字符串。

请帮忙。

这里是代码

procedure TEvReader.ScreenShot(DestBitmap : TBitmap) ;
var DC : HDC;
begin DC := GetDC (GetDesktopWindow) ;
try
DestBitmap.Width := GetDeviceCaps (DC, HORZRES) ;
DestBitmap.Height := GetDeviceCaps (DC, VERTRES) ;
BitBlt(DestBitmap.Canvas.Handle, 0, 0, DestBitmap.Width, DestBitmap.Height, DC, 0, 0, SRCCOPY) ;
finally
ReleaseDC (GetDesktopWindow, DC) ;
end;
end;


function TEvReader.Base64FromBitmap(Bitmap: TBitmap): string;
var
Input: TBytesStream;
Output: TStringStream;
JpegImg:TJPEGImage;
begin
Input := TBytesStream.Create;
try
JpegImg:=TJPEGImage.Create;
JpegImg.Assign(Bitmap);


JpegImg.SaveToStream(Input); {here a problem.When i replace "JpegImg" to "Bitmap" all works good }
Input.Position := 0;
Output := TStringStream.Create('', TEncoding.ASCII);
try
Soap.EncdDecd.EncodeStream(Input, Output);
Result := Output.DataString;
finally
Output.Free;
end;
finally
Input.Free;
end;
end;


procedure TOutThread.Execute;
var

bmp:TBitmap;
strrr:String;
begin

bmp:=TBitmap.Create;
mObj.ScreenShot(bmp);

strrr := mObj.Base64FromBitmap(bmp);

Form2.Memo4.Text := strrr;

end;

最佳答案

TJPEGImage 不是线程安全的。虽然 http://qc.embarcadero.com/wc/qcmain.aspx?d=55871 中提到了线程安全绘图的问题在 Delphi XE6 中有些固定(通过公开 Canvas 属性,您必须锁定自己),在您的情况下,它可能不会有太大帮助。

您必须将 TJPEGImage 处理与主线程同步。

此外,在您的代码中,您还造成了一些内存泄漏,因为您从未释放过 JpgImg 和 Bmp 对象。

尝试使用以下代码:

procedure TEvReader.ScreenShot(DestBitmap: TBitmap);
var
DC: HDC;
begin
DC := GetDC(GetDesktopWindow);
DestBitmap.Canvas.Lock;
try
DestBitmap.Width := GetDeviceCaps(DC, HORZRES);
DestBitmap.Height := GetDeviceCaps(DC, VERTRES);
BitBlt(DestBitmap.Canvas.Handle, 0, 0, DestBitmap.Width, DestBitmap.Height, DC, 0, 0, SRCCOPY);
finally
DestBitmap.Canvas.Unlock;
ReleaseDC(GetDesktopWindow, DC);
end;
end;

function TEvReader.Base64FromBitmap(Bitmap: TBitmap): string;
var
Input: TBytesStream;
Output: TStringStream;
JpegImg: TJPEGImage;
begin
Input := TBytesStream.Create;
try
JpegImg := TJPEGImage.Create;
try
TThread.Synchronize(nil,
procedure
begin
JpegImg.Assign(Bitmap);
JpegImg.SaveToStream(Input);
end);
finally
JpegImg.Free;
end;
Input.Position := 0;
Output := TStringStream.Create('', TEncoding.ASCII);
try
Soap.EncdDecd.EncodeStream(Input, Output);
Result := Output.DataString;
finally
Output.Free;
end;
finally
Input.Free;
end;
end;

procedure TOutThread.Execute;
var
mObj: TEvReader;
bmp: TBitmap;
strrr: string;
begin
mObj := TEvReader.Create;
bmp := TBitmap.Create;
try
mObj.ScreenShot(bmp);
strrr := mObj.Base64FromBitmap(bmp);
finally
bmp.Free;
mObj.Free;
end;

Synchronize(nil,
procedure
begin
Form2.Memo4.Text := strrr;
end);
end;

关于delphi - 在 TThread 中将 Jpeg 保存为 base64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27089111/

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