Can Delphi Firemonkey TControl.MakeScreenshot work

2019-08-11 05:39发布

问题:

I've created a simple FireMonkey screenshot capture that works fine on Android and 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;

end;

when I moved it to a thread as below, it works fine in Windows but in Android I get the exception 'bitmap too big' from the call to MakeScreenshot. Are there additional steps needed to employ MakeScreenshot in a thread?

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;

Later addition. Based on suggestions by Sir Rufo and Sebastian Z, this solved the problem and allowed use of a thread:

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;

回答1:

MakeScreenShot is not thread safe, so you cannot safely use it in a thread. If this works in Windows then I'd say you were just lucky. I'd suggest that you take the screenshot outside of the thread and only use the thread for saving the screenshot to png. Painting should be fast while encoding to png needs a lot more resources. So you should still benefit pretty much from the thread.