我的目标是获得尽可能高的FPS。我对BW小帧很满意,但FPS应该是最大的。getSupportedPreviewFpsRange
对HTC野火S的回报(9,30)。但是当我尝试用最简单的处理来绘制预览图像时,它的视觉效果大约是12-15 FPS。在设置参数和startPreview()
方法调用之后,我这样做:
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;
}
有办法尽快得到它吗?= (
首先,使用setPreviewCallbackWithBuffer(),它重用一个缓冲区,而不必在每一帧上分配新的缓冲区。查看我以前的答案,这里有一个如何使用它的例子。
然后,不要在onPreviewFrame()中做任何昂贵的操作,数据的时间是有限的,它在每个新帧上被重写。您应该在另一个线程中执行此处理。
当然,不要在每一帧上创建新的位图和颜色数组,只做一次。
我真的不明白你在做什么,但我猜你在处理过程中自杀了。
1)不要每次都创建新的位图。重用1位图。2)使用NDK在C/c++中操作您的位图。看看"等离子体"的例子。它比Java快得多。这并不是因为它实际上是c++,而是因为Java版本的API倾向于在您为像素输入数据数组时转换整个东西。在c++版本中,您可以直接操作像素值。
我不太确定你的目标是这个应用程序,但我在相机功能中添加的方式是创建一个自定义的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);