如何将图像处理移动到非主线程

时间:2015-09-30 13:49:27

标签: android multithreading memory-management camera preview

我的应用程序从yuv格式的相机预览中获取每一帧并压缩为jpeg。它适用于API8,但在Android> 4上它表示在主线程和跳过的帧上完成了太多的工作。其他一切工作,但图像处理被视为太昂贵。对我来说,如果它冻结UI,那就更重要了。我可以升级优先级或smth来停止跳帧吗?我试图在其他线程上移动处理但是如何将yuv图像从相机发送到其他线程进行处理。我发送了带有bundle的字节数组但它吃了内存并且只工作了几秒钟 这是我的代码:

   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次,如果我通过bundle将data []发送到其他线程,我会得到严重的内存泄漏。在使用线程时,我对内存处理的理解很模糊。

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

你说得对,它应该在一个单独的线程上,但可能有一些你可以优化的东西。

  1. 确保您一次只处理一张图片。即,不处理您获得的每个图像,仅在前一个任务结束后处理。 (我认为这可能是个问题,因为阻止UI线程会阻止你同时处理并看到对mem和cpu的影响)
  2. 回收您不再需要的任何位图。
  3. 您是将实际的android.os.Bundle发送到主题而不是byte[],还是仅仅是短语?无论哪种方式,我都希望原始byte[]更快。
  4. 根据您对图像的处理情况,如果质量不是非常重要的话,可能值得缩减它。