【问题标题】:Can Delphi Firemonkey TControl.MakeScreenshot work in a thread?Delphi Firemonkey TControl.MakeScreenshot 可以在线程中工作吗?
【发布时间】:2016-03-18 06:41:07
【问题描述】:

我创建了一个简单的 FireMonkey 屏幕截图,可以在 Android 和 Windows 上正常运行。..:

procedure Capture;
var
  B : TBitmap;
begin
  try
    B := Layout1.MakeScreenshot;
    try
      B.SaveToFile( ..somefilepath.png );
    finally
      B.Free;
    end;
  except
    on E:Exception do
      ShowMessage( E.Message );
  end;
end;

结束;

当我将它移至如下线程时,它在 Windows 中运行良好,但在 Android 中,我从调用 MakeScreenshot 中得到异常“位图太大”。在线程中使用 MakeScreenshot 是否需要额外的步骤?

procedure ScreenCaptureUsingThread;
begin
   TThread.CreateAnonymousThread(
   procedure ()
   var
     B : TBitmap;
   begin
     try
       B := Layout1.MakeScreenshot;
       try
         B.SaveToFile( '...somefilepath.png' );
       finally
         B.Free;
       end;
     except
       on E:Exception do
         TThread.Synchronize( nil,
           procedure ()
           begin
             ShowMessage( E.Message );
           end );
        end).Start;
    end;

稍后添加。根据 Sir Rufo 和 Sebastian Z 的建议,这解决了问题并允许使用线程:

procedure Capture;
begin
  TThread.CreateAnonymousThread(
    procedure ()
    var
      S : string;
      B : TBitmap;
    begin
      try
        // Make a file name and path for the screen shot
        S := '...SomePathAndFilename.png';     
        try
          // Take the screenshot
          TThread.Synchronize( nil,
            procedure ()
            begin
              B := Layout1.MakeScreenshot;
              // Show an animation to indicate success
              SomeAnimation.Start;
            end );

          B.SaveToFile( S );
        finally
          B.Free;
        end;
      except
        on E:Exception do
          begin
          TThread.Synchronize( nil,
            procedure ()
            begin
              ShowMessage( E.Message );
            end );
          end;
      end;
    end).Start;
end;

【问题讨论】:

  • 你不应该同时使用DelphiTThreadTBitmap(你只会面临错误)......并且你必须在主线程上下文,否则您将只生成一个随机骰子应用程序(可能有效或无效)

标签: android multithreading delphi screenshot firemonkey


【解决方案1】:

MakeScreenShot 不是线程安全的,因此您不能在线程中安全地使用它。如果这在 Windows 中有效,那么我会说你很幸运。我建议您在线程之外截取屏幕截图,并且仅使用线程将屏幕截图保存为 png。绘画应该很快,而编码为 png 需要更多资源。所以你仍然应该从这个线程中受益匪浅。

【讨论】:

  • 我会感到惊讶,因为位图不是线程安全的(除非他们最近修复了)。
  • 确实不能同时从两个线程访问位图。在这里,图像被传输到线程进行保存,然后没有其他人访问它。这并不意味着没有任何错误可以阻止这种情况(XE5 中存在一些问题)。
  • 不,您根本无法从线程访问 FMX 位图,因为它与主线程中的内务管理冲突。访问位图的唯一可靠方法是从主线程。同样,除非他们最近重写了所有内容(我对此表示怀疑并且肯定从未在修订列表中注意到)。这太疯狂了,我知道。
猜你喜欢
  • 2016-02-06
  • 2020-08-11
  • 1970-01-01
  • 2013-03-09
  • 2020-08-08
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多