Capture image in every 42 millisecond previewed in surface View

时间:2017-12-18 06:57:34

标签: android

I want to capture image previewed in surfaceView.Capturing time is every 42 millisecond.While capturing I want to send these images to the server as byteArray at this moment.For security reason, photo cant is saved to sd.I must use this for making a video call.Can anyone help me?Pls

Button take;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PictureCallback jpegCallback;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    checkPermission();
    surfaceView = (SurfaceView) findViewById(R.id.surface);
    surfaceHolder = surfaceView.getHolder();

    take = (Button) findViewById(R.id.take);
    take.setOnClickListener(this);
    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    surfaceHolder.addCallback(this);

    // deprecated setting, but required on Android versions prior to 3.0
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    jpegCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
            try {
                outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();
                Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Toast.makeText(getApplicationContext(), "Picture Saved", Toast.LENGTH_SHORT).show();
            refreshCamera();
        }
    };
}

public void captureImage() throws IOException {
    //take the picture
    camera.takePicture(null, null, jpegCallback);
}


@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
    try {
        // open the camera
        camera = Camera.open();
    } catch (RuntimeException e) {
        // check for exceptions
        System.err.println(e);
        return;
    }
    Camera.Parameters param;
    param = camera.getParameters();

    // modify parameter
    List<Camera.Size> sizes = param.getSupportedPreviewSizes();
    Camera.Size selected = sizes.get(0);
    param.setPreviewSize(selected.width,selected.height);
    camera.setParameters(param);
    try {
        // The Surface has been created, now tell the camera where to draw
        // the preview.
        camera.setDisplayOrientation(90);
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    } catch (Exception e) {
        // check for exceptions
        System.err.println(e);
        return;
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    refreshCamera();
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    // stop preview and release camera
    camera.stopPreview();
    camera.release();
    camera = null;
}

public void refreshCamera() {
    if (surfaceHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here
    // start preview with new settings
    try {
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    } catch (Exception e) {

    }
}

private void requestPermission() {

    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}

private boolean checkPermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

    if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            } else {

            }
            break;
    }

}


@Override
public void onPointerCaptureChanged(boolean hasCapture) {

}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.take:{
            try {
                captureImage();
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;
        }
    }

}

So while previewing in SurfaceView I must get every 42 millis photo as byteArray and send it

1 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法。我已经通过setPreviewCallbackWithBuffer修复了一个onPreviewFrame.There不需要处理程序和计时器......

private Camera camera;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private ImageView endCallBtn;
private ImageView micBtn;
private ImageView visibilityBtn;
private ImageView cameraBtn;
private Boolean clickedForMic = false;
private Boolean clickedForCamera = false;
private Boolean clickedForVisiblity = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_video_call);
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView);

    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkPermission()) {
            Log.e("permission", "Permission already granted.");
        } else {
            requestPermission();
        }
    }


    endCallBtn = (ImageView) findViewById(R.id.endCallBtn);
    endCallBtn.setOnClickListener(this);
    micBtn = (ImageView) findViewById(R.id.micBtn);
    micBtn.setImageResource(R.drawable.ic_mic_white_48px);
    micBtn.setOnClickListener(this);
    visibilityBtn = (ImageView) findViewById(R.id.visibilityBtn);
    visibilityBtn.setImageResource(R.drawable.ic_visibility_white_48px);
    visibilityBtn.setOnClickListener(this);
    cameraBtn = (ImageView) findViewById(R.id.cameraBtn);
    cameraBtn.setImageResource(R.drawable.ic_camera_rear_white_48px);
    cameraBtn.setOnClickListener(this);

}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.cameraBtn: {
            if (clickedForCamera == false) {
                if (clickedForVisiblity == true) {
                    Toast.makeText(VideoCallActivity.this, "Видимость камеры заблокирована", Toast.LENGTH_SHORT).show();
                } else {
                    stopCamera();
                    startCameraBack();
                    cameraBtn.setImageResource(R.drawable.ic_camera_front_white_48px);
                    clickedForCamera = true;
                }
            } else {
                if (clickedForVisiblity == true) {
                    Toast.makeText(VideoCallActivity.this, "Видимость камеры заблокирована", Toast.LENGTH_SHORT).show();
                } else {
                    stopCamera();
                    startCameraFront();
                    cameraBtn.setImageResource(R.drawable.ic_camera_rear_white_48px);
                    clickedForCamera = false;
                }
            }
            break;
        }
        case R.id.micBtn: {

            if (clickedForMic == false) {
                micBtn.setImageResource(R.drawable.ic_mic_off_white_48px);
                micBtn.setColorFilter(Color.parseColor("#00897B"));
                clickedForMic = true;
            } else {
                micBtn.setImageResource(R.drawable.ic_mic_white_48px);
                micBtn.setColorFilter(Color.parseColor("#ffffff"));

                clickedForMic = false;
            }
            break;
        }
        case R.id.endCallBtn: {
            stopCamera();
            finish();
            overridePendingTransition(R.anim.window3, R.anim.window4);
            break;
        }

        case R.id.visibilityBtn: {
            if (clickedForVisiblity == false) {
                camera.stopPreview();
                visibilityBtn.setImageResource(R.drawable.ic_visibility_off_white_48px);
                visibilityBtn.setColorFilter(Color.parseColor("#00897B"));
                clickedForVisiblity = true;
            } else {
                camera.startPreview();
                visibilityBtn.setImageResource(R.drawable.ic_visibility_white_48px);
                visibilityBtn.setColorFilter(Color.parseColor("#ffffff"));
                clickedForVisiblity = false;
            }
            break;
        }
    }
}


private void requestPermission() {

    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}

private boolean checkPermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

    if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            } else {

            }
            break;
    }

}

private void stopCamera() {
    camera.stopPreview();
    camera.release();

}

private void startCameraFront() {
    if (checkPermission()) {

        try {
            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
        } catch (Exception e) {
            return;
        }
        Camera.Parameters param;
        camera.setDisplayOrientation(90);
        param = camera.getParameters();

        param.setPreviewFrameRate(24);
        param.setPreviewFpsRange(22000, 30000);


        camera.setParameters(param);

        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (Exception e) {
            return;
        }
        Log.v("CameraTest", "Camera PreviewFrameRate = " + camera.getParameters().getPreviewFrameRate());
        Camera.Size previewSize = camera.getParameters().getPreviewSize();
        int dataBufferSize = (int) (previewSize.height * previewSize.width *
                (ImageFormat.getBitsPerPixel(camera.getParameters().getPreviewFormat()) / 8.0));
        camera.addCallbackBuffer(new byte[dataBufferSize]);
        camera.addCallbackBuffer(new byte[dataBufferSize]);
        camera.addCallbackBuffer(new byte[dataBufferSize]);
        camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
            private long timestamp = 0;

            public synchronized void onPreviewFrame(byte[] data, Camera camera) {
                //Log.v("CameraTest", "Time Gap = " + (System.currentTimeMillis() - timestamp));
                Log.v("CameraTest", " data: " + String.valueOf(data.length));
                timestamp = System.currentTimeMillis();
                try {
                    camera.addCallbackBuffer(data);
                } catch (Exception e) {
                    Log.e("CameraTest", "addCallbackBuffer error");
                    return;
                }
                return;
            }
        });
        camera.startPreview();


    }

}


private void startCameraBack() {
    if (checkPermission()) {
        try {
            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        } catch (Exception e) {
            return;
        }
        Camera.Parameters param;
        camera.setDisplayOrientation(90);
        param = camera.getParameters();
        //modify parameter

        param.setPreviewFrameRate(30);
        camera.setParameters(param);
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
        } catch (Exception e) {
            Log.d("Problema", e.toString());
            return;
        }
    }
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
    startCameraFront();
}


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}