really confused with setPreviewCallback in Android

2019-01-23 09:33发布

问题:

I'm building an application on Android to take frames from the camera, process them, and then display the frame on a surfaceView, as well as drawing on the SurfaceView via the canvas and drawbitmap and all.

Just to check, is SurfaceView and Bitmaps and Canvases the best way to do it ? I'm after speed.

Assuming the answer to the above is Yes, the question would be: Where should I place the following function

camera_object.setPreviewCallback(new PreviewCallback()
     public void onPreviewFrame(byte[] data, Camera camera){

should I place it in onCreate() or should I place it in surfaceCreated() or surfaceChanged() ?

I declared my mainactivity class as follows:

public class MainActivity extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback
{

and in that class Eclipse forces me to create an override function for onpreviewframe in the MainActivity class as follows

public void onPreviewFrame(byte[] data, Camera camera){
}

but it never gets called. Should I try to use this function ? is it better to use it ? or is it just an Eclipse thing ?

Please advise

回答1:

Are you calling setPreviewDisplay(), startPreview() and setPreviewCallback(this) from the app? Without that you will not get any calls to onPreviewFrame(). In fact if you are using SurfaceView, then the callback preview buffers are a copy of the actual buffers that are being displayed on the screen. So if you want to display these copied buffers, you need to create a new view and overwrite it. This would be inefficient. I would suggest you use SurfaceTexture instead and use 'onFrameAvailable' callback to get the frames and then draw & display manually. An example of this can be found in the PanoramaActivity code of the default Android Camera App.



回答2:

Without camera_object.setPreviewDisplay(surface_holder); you cannot receive camera callbacks; don't forget also

surface_view.setVisibility(View.VISIBLE);
surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

You can hide the camera preview under another view; on 3.0 and higher you can even push the surface out of the screen (display it below the bottom of the screen). I am not sure if the latter trick works on 2.3.6.