我想從我的Renderer的onDrawFrame函數捕獲我的Android應用程序的屏幕截圖。但是它會放棄框架並凍結應用程序直到過程完成。我試圖在不同的線程上做,但沒有成功。是否有可能在不同的線程上獲得屏幕截圖。是否有可能從Android的另一個線程採取GLSurfaceView屏幕截圖?
回答
您不能從另一個線程執行glReadPixels()
,因爲EGL上下文一次只能在一個線程中處於當前狀態,並且您無法使用GLSurfaceView控制它。
然而,花了抓住從GLES屏幕截圖的時間95 +%用於PNG/JPEG壓縮和磁盤I/O。因此,如果您從onDrawFrame()
撥打電話glReadPixels()
,然後將數據交給一個新線程,那麼在屏幕快照在後臺處理時應該可以繼續運行。
如前所述的直接讀取可從另一個線程是不可能的,但也有其他方式。
代替直接繪製場景的表面的視圖可能它繪製到幀緩衝器的對象(FBO)附有紋理,然後重新繪製紋理到主緩衝區。這是用於後期處理的非常標準的過程,並且不具有高性能影響。爲了實現這一點,您實際上只需要研究如何創建FBO,在繪圖開始之前將其綁定,並且其餘代碼應該保持原樣。然後,通過綁定主緩衝區(索引0應該這樣做),添加代碼來重畫屏幕上的FBO紋理。
對於一個單獨的線程,你現在需要創建一個新的線程,並且是在該線程設置一個新的上下文的屏幕截圖。新的背景必須與主背景共享(我相信有一個構造函數接受主背景),所以你可以共享紋理。現在有趣的部分:當您想要截取屏幕截圖時,您需要創建一個新紋理,將新紋理附加到FBO,分離舊紋理。通過這樣做,您可以竊取內容被繪製的紋理,並且您可以隨心所欲地執行任何您想要的任何線程。因此,把它放到你的輔助線程中,在這個上下文中你可以創建另一個FBO,將它綁定並在該線程上讀取它的像素。不要忘記清理。
有些謹慎,雖然建議。當您製作相對較少量的屏幕截圖時,這種過程可能會很好。如果一個截圖在另一個截圖開始之前沒有完全完成,那麼您的內存使用量將會膨脹,並且您的應用很可能會崩潰。所以要小心不要這樣做,創建某種鎖定機制或限制正在進行的截圖處理的數量。這不僅適用於openGL,簡單編碼圖像數據時可能會出現同樣的問題。
而就在你最初的想法記:即使你可以使用一個單獨的線程的表面視圖和讀取它的主緩衝區像素您可能沒有想到你會得到一個好的結果。讀取時緩衝區可能會被吸引,因此您可能會從不同的幀獲得大量數據。這仍然是理論上的,因爲事實是緩衝區會被鎖定,並且您的應用程序在嘗試訪問時會崩潰。所以這是不可能的,即使它的結果是不可預測的。
小心 - 在不同線程的上下文之間共享紋理可能存在競爭條件。我在Grafika得到了這個錯誤;請參閱https://github.com/google/grafika/issues/36。 – fadden
這就是爲什麼我說你需要「偷走」紋理。您需要將您繪製的當前紋理替換爲新紋理。你實際上可以使用2個紋理進行雙緩衝。 –
- 1. iOS採取多個屏幕截圖
- 2. 是否有可能停止從iPhone屏幕截圖
- 3. 是否可以從Firefox的Android擴展中截取屏幕截圖?
- 4. 重啓Android和採取當前屏幕的截屏編程
- 5. xna 4採取桌面屏幕截圖
- 6. iPhone - UIImagePickerController採取屏幕截圖?
- 7. 是否可以從adb調用ICS屏幕截圖功能?
- 8. 採取屏幕的特定部分的屏幕截圖
- 9. 是否有可能從Android服務獲取屏幕內容
- 10. 如何採取屏幕截圖和截屏保存在相冊
- 11. 有沒有辦法採取的屏幕截圖的MPMoviePlayerController播放
- 12. 合併兩個圖像,並採取佈局android的屏幕截圖android
- 13. 是否有可能從另一個線程喚醒uv_loop?
- 14. WPF是否有可能從另一個線程託管控件?
- 15. 是否可以使用Selenium/Capybara截取整個頁面的屏幕截圖?
- 16. android屏幕截圖
- 17. 編寫一個Android應用程序以獲取屏幕截圖
- 18. C++截取屏幕截圖
- 19. 截取屏幕截圖
- 20. 採取網站的屏幕截圖,只有網址
- 21. android中的屏幕截圖功能
- 22. 採取整個網頁的屏幕截圖
- 23. 試圖採取視圖的屏幕截圖和它的孩子
- 24. Android的活動 - 從一個屏幕到另一個屏幕
- 25. SpriteKit屏幕截圖的屏幕截圖
- 26. 如何製作一個應用程序,可以採用編程方式截取android設備的整個屏幕?
- 27. 是否有可能從android中的另一個應用程序獲取數據?
- 28. iOS - 在應用程序崩潰之前採取屏幕截圖
- 29. 如何在沒有root的Android 2.3.3中截取屏幕截圖?
- 30. 是否可以從另一個線程取消同步的NSURLConnection?
發表一些代碼,多線程這種情況應該是可能的,這取決於你是如何做的。 – zgc7009