2015-09-30 17 views
0

我的應用程序需要從yuv格式的相機預覽中獲取每個幀並壓縮爲jpeg。它適用於API8,但在Android> 4上它表示在主線程和框架上跳過了太多的工作。所有其他作品,但圖像處理都被視爲過於昂貴。對我來說,如果它凍結UI,那麼它更重要。我可以升級優先級或禁止幀跳過?我試圖在其他線程上移動處理,但是如何將yuv圖像從相機發送到其他線程進行處理。我發送的字節數組捆綁,但吃內存,只工作了幾秒鐘 這裏是我的代碼:如何將圖像處理移動到非主線程

public void surfaceCreated(SurfaceHolder holder){ 
    try{ 
     mCamera.setPreviewDisplay(holder); 
     mCamera.setPreviewCallback(new Camera.PreviewCallback() { 
             @TargetApi(Build.VERSION_CODES.FROYO) 
             @Override 
             public void onPreviewFrame(byte[] data, Camera camera) { 
              if (serverActivity.IPAddress != null) { 
               Camera.Parameters parameters = camera.getParameters(); 
               int imageFormat = parameters.getPreviewFormat(); 
               if (imageFormat == ImageFormat.NV21) { 
                Rect rect = new Rect(0, 0, width, height); 
                //YuvImage appeared only in API8 - Froyo 
                YuvImage img = new YuvImage(data, ImageFormat.NV21, width, height, null); 

                bytearray = new ByteArrayOutputStream(20000); 
                try { 
                 img.compressToJpeg(rect, 30, bytearray); 
                 dataimage = bytearray.toByteArray(); 

                 serverActivity.send2thread(dataimage); 
                } catch (Exception e) { 
                 e.printStackTrace(); 
                } 
               } 
              } 
             } 
            } 
     ); 
     mCamera.startPreview(); 
    } catch(IOException e){ 
     Toast.makeText(getContext(),"error setting camera preview: "+e.getMessage(),Toast.LENGTH_LONG).show(); 
    } 
} 

onPreviewFrame每秒運行約15倍,如果我通過包發送數據[]到其他線程我得到嚴重的內存泄漏。在處理線程時,我對模糊內存的處理有着模糊的理解。

回答

0

你是不是正確的,它應該是在一個單獨的線程,但有可能是一對夫婦的事情,你可以優化做到這一點。

  1. 確保您一次只處理一個圖像。也就是說,不要處理你得到的每一個圖像,只有在前一個任務結束後才處理。 (我認爲這可能是問題,因爲阻塞UI線程會阻止你同時處理並看到對mem和cpu的影響)
  2. 回收任何你不再需要的位圖。
  3. 您是否發送一個實際的android.os.Bundle到線程而不是byte[],或者只是短語?無論哪種方式,我希望原始byte[]更快。
  4. 根據您對圖像所做的處理,如果質量不是非常重要,則可能需要縮減比例。
+0

我看不出我如何使用asyncTask。我需要每秒向該線程發送十幾次byte []。我使用處理程序併發送捆綁。凱文,謝謝你的提示,我不知道如何發送沒有捆綁的字節[]。我確定第二張圖像正在等待當前完成,但沒有解決。我不知道如何回收位圖。 – asanovrus

+0

'bitmap.recycle();'應該沒問題,請注意,如果您不再需要該位圖,則只應執行此操作。你可以創建一個自定義的'Thread'或'Runnable'類,它在構造函數或方法參數等中使用'byte []'參數。 – Kevin