2015-12-12 70 views
1

我創建了一個簡單的FireMonkey截屏獲取在Android和Windows ..正常工作:Delphi Firemonkey TControl.MakeScreenshot可以在一個線程中工作嗎?

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; 

後來增加。基於通過入佛門爵士和塞巴斯蒂安ž建議,這解決了這個問題,並允許使用一個線程:

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; 
+2

你不應該一起使用* Delphi *,'TThread'和'TBitmap'(你只會面對錯誤)...並且你必須在主線程上下文中訪問UI控件,否則你只會產生一個隨機骰子的應用程序(可能工作與否) –

回答

2

MakeScreenShot不是線程安全的,所以你不能安全地在一個線程中使用它。如果這在Windows中工作,那麼我會說你是幸運的。我建議你在線程外部截取屏幕截圖,並僅使用線程將屏幕截圖保存爲png。繪畫應該很快,而編碼到PNG需要更多的資源。所以你仍然應該從線程中獲益很多。

+0

如果這種工作一致,位圖不是線程安全的(除非他們最近修復),我會感到驚訝。 –

+0

確實,您無法同時從兩個線程訪問位圖。這裏圖像被傳輸到線程進行保存,然後沒有其他人訪問它。這並不意味着沒有任何錯誤可以防止這種情況發生(XE5中存在一些問題)。 –

+0

不,您無法從線程訪問FMX位圖,因爲它與主線程中的內務管理衝突。訪問位圖的唯一可靠方法來自主線程。再說一遍,除非他們最近重寫了所有這些(我懷疑並且肯定從未在修訂清單中注意過)。我知道這很瘋狂。 –

相關問題