在写一个简单的通过onPreviewFrame获取摄像头当前预览的图像再发送出去的程序。
但是运行的时候发现完全就没有调用这个函数。
用debug逐步调试的时候发现走到
camera.setPreviewCallback(MainActivity.this);这句就直接跳到设置变量的Camera camera;这句话然后就没有了完全没有调用onPreviewFrame这个函数网上有人说用了surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);就无法调用onPreviewFrame。但是在eclipse里面那段代码提醒说是deprecated。
我去掉这条代码(应该是不能去掉的吧?)就直接程序崩坏。
究竟是怎么回事呀,各位求方法。求解答啊。
怎么才可以调用这个onPreviewFrame呢

解决方案 »

  1.   

    代码package com.example.testfordraw;  
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;import javax.security.auth.callback.Callback;import android.app.Activity;  
    import android.content.Context;  
    import android.content.pm.ActivityInfo;
    import android.graphics.Canvas;  
    import android.graphics.Color;  
    import android.graphics.Paint;  
    import android.graphics.PixelFormat;
    import android.graphics.Rect;  
    import android.graphics.YuvImage;
    import android.hardware.Camera;
    import android.hardware.Camera.Size;
    import android.media.MediaRecorder;
    import android.os.Bundle;  
    import android.os.Environment;
    import android.util.AttributeSet;
    import android.view.Menu;
    import android.view.SurfaceHolder;  
    import android.view.SurfaceView;  
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    public class MainActivity extends Activity implements SurfaceHolder.Callback,Camera.PreviewCallback{ private Camera camera;
    public static ByteArrayOutputStream outputstream = null;
    private SurfaceView msurfaceview;
    private Button buttonstart;
    private Button buttonstop;
    private MediaRecorder recorder;
    private SurfaceHolder surfaceholder;
    private File savefile;
    private File SDfile;
    private String savepath;
    private File recfile;
    private int Width = 320;
    private int Height = 240;
    private boolean isRecording = false ;
    private boolean istrans = false ;
    private int videoformat=0;
    private int VideoQuality=85;
    private float VideoWidthRatio=1;
     private float VideoHeightRatio=1;
    private String username= "wh";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setFormat(PixelFormat.TRANSLUCENT);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
    setContentView(R.layout.activity_main);
    msurfaceview = (SurfaceView) findViewById(R.id.mysurfaceview);
    buttonstart = (Button) findViewById(R.id.start);
    SDfile = Environment.getExternalStorageDirectory();
    savepath = SDfile.getAbsolutePath()+File.separator+"mvideo"+File.separator;
    savefile = new File(savepath);
    buttonstart.setText("start");
    buttonstart.setOnClickListener(new buttonstartlistener());

    if (!savefile.exists())
    {
    savefile.mkdirs();
    }

    }
    class buttonstartlistener implements OnClickListener{ @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    if(istrans==false)
    {
    //record();
    istrans = true;
    camera.setPreviewCallback(MainActivity.this);
    }else{
    //Stoprecording();
    istrans =false;
    }
    if(istrans == false)
    {
    buttonstart.setText("start");
    }else{
    buttonstart.setText("stop");
    }
    }

    }
    public void Stoprecording() {
    if(recorder!= null){
    recorder.stop();
    recorder.reset();
    recorder.release();
    recorder = null;
    isRecording = false ;
    }
    try{
    camera.reconnect();
    }catch(IOException e ){
    Toast.makeText(this, "reconect fail", 0).show();
    e.printStackTrace();
    }
    }
    public void record()
    {
    try{

    camera.unlock();
    isRecording = true ;
    recorder = new MediaRecorder();
    recfile = File.createTempFile("Video",".3gp",savefile);
    recorder.setCamera(camera);
    recorder.reset();
    recorder.setCamera(camera);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setOutputFile(recfile.getAbsolutePath());
    recorder.setVideoSize(320,480);
    recorder.setVideoFrameRate(20);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setPreviewDisplay(surfaceholder.getSurface());
    recorder.prepare();
    recorder.start();
    }catch(IOException e){
    e.printStackTrace();
    }
    } @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
    }
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
    // TODO Auto-generated method stub
    if(istrans == false){
    return;
    }
    if(data!=null)
    {
    try{
    YuvImage image = new YuvImage(data, videoformat, Width, Height, null);
    if(image!=null){
     ByteArrayOutputStream outstream = new  ByteArrayOutputStream();
     Rect rect = new Rect(0,0,(int)(VideoWidthRatio*Width),(int)(VideoHeightRatio*Height));
     image.compressToJpeg(rect, VideoQuality, outstream);
     outputstream = outstream;
     outstream.flush(); }
    }catch(Exception e){}
    }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format,
    int width, int height) {
    if(camera != null){
    return;
    }
    camera.stopPreview();
    camera.setPreviewCallback(MainActivity.this);

    Camera.Parameters parameters = camera.getParameters();
    Size size = parameters.getPreviewSize();
    Width = size.width;
    Height = size.height;
    videoformat = parameters.getPreviewFormat();
    camera.startPreview();
    // TODO Auto-generated method stub

    }
    @Override
    protected void onStart() {
    // TODO Auto-generated method stub
    surfaceholder = msurfaceview.getHolder();
    surfaceholder.addCallback(this);
    surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    VideoWidthRatio=VideoWidthRatio/100f;
        VideoHeightRatio=VideoHeightRatio/100f;
    super.onStart();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    try{
    camera.setPreviewDisplay(surfaceholder);
    }catch (IOException e){
    e.printStackTrace();
    }
    camera.startPreview();
    Camera.Parameters parameters = camera.getParameters();
    Size size = parameters.getPreviewSize();
    Width = size.width;
    Height = size.height;
    videoformat = parameters.getPreviewFormat();
    } @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    if(camera !=null){
    camera.setPreviewCallback(null);
    camera.stopPreview();
    camera.release();
    camera = null;
    }
    }

    }为什么别人的都可以调用,就我的不行呢。。camera.setPreviewCallback有写啊
      

  2.   

    不知道在SurfaceChanged 里面是否能去处理。。后面我试试看。。
      

  3.   

    使用到MediaRecorder时需要camera.unlock();导致了onPreviewFrame()不会被调用到,所以在录制视频时不能同时形成帧图片,我现在也是这个问题想要同时录制视频和形成帧图片,如果楼主解决了,能联系一下我吗?求提示帮忙