2011-12-27 111 views
2

我的目标是获得尽可能高的FPS。我会很满意BW的小型框架,但FPS应该是最大的。 HTC WildFire S上的 getSupportedPreviewFpsRange返回(9,30)。但是当我尝试使用最简单的处理来绘制预览图像时,它的视觉效果最高可达12-15 FPS。 设置参数和startPreview()方法调用后,我这样做:获得实时计算机视觉处理高FPS的方法

camera.setPreviewCallback(new Camera.PreviewCallback() { 
      @Override 
      public void onPreviewFrame(byte[] bytes, Camera camera) { 
      Bitmap bitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888); 
      int[] colors = new int[size.width * size.height]; 
      for (int i=0; i < colors.length; i++){ 
       colors[i] = getBWColor(bytes[i]); 
      } 
      bitmap.setPixels(colors, 0, size.width, 0, 0, size.width, size.height); 
      secondView.setImageBitmap(bitmap); 
      } 
     }); 
     } 

private static int getBWColor(byte b){ 
    int res = 255; 
    for(int i=0;i<3;i++){ 
     res = (res << 8) + b; 
    } 
    return res; 
    } 

有没有办法得到它尽可能快的? =(

+0

有人建议“你可以给媒体记录器提供插口,并且它会写入实时数据 - 这样你就可以在保存数据之前捕获数据(但它已经被压缩了)”但我并不真正了解去做吧。 – 2011-12-27 22:19:16

回答

5

首先,使用setPreviewCallbackWithBuffer(),它重新使用一个缓冲区,并且不必在每个帧上分配新的缓冲区。检查我的older answer,有一个示例如何使用它。

比onPreviewFrame()中不要做任何昂贵的操作,数据的时间是有限的,它被重写在每个新的帧上。你应该在另一个线程中进行处理。

当然,不要在每一帧上创建新的位图颜色数组,只做一次。

+0

我看到了使用不同线程和人们在此处建议的其他内容的示例。我积累了所有的建议,而不是写我做了什么。谢谢你和其他评论员! – 2011-12-29 13:52:00

1

我不完全确定你的目标是什么这个应用程序,但我在相机功能添加的方式创建了一个自定义surfaceView类,并在那里设置我的相机后,我选择了前面(如果可用)或我设置了参数,然后调用了setPreviewDisplay并传入了我创建的SurfaceHolder(代码如下)。之后,只需调用startpreview(),并且一切都很好,我对它有很好的帧率,看起来一切正常。你要我更详细地说明或张贴一些代码,让我知道。

SufaceHolder mHolder; 
mHolder = getHolder(); 
mHolder.addCallback(this); // this is the SurfaceView class 
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
mHolder.setKeepScreenOn(true); 
3

我真的不明白你在做什么,但我猜你正在扼杀自己处理。

1)不要每次都创建一个新的位图。重用1位图。 2)用NDK在C/C++中操作你的位图。看看“等离子”的例子。它比Java快得多。不是因为它的C++真的,而是因为Java版本的API倾向于在每次为像素推入数据数组时都转换整个事物。在C++版本中,您可以直接操作像素值。