Android中的视频帧捕获

Android中的视频帧捕获,android,video-capture,Android,Video Capture,我正在尝试实现一个Android应用程序,它每秒捕获大约1张图片,对每张图片执行一些处理,并将输出发送到一个文件进行存储。我的第一次尝试如下: public class MainActivity extends Activity { ... Handler loopHandler = new Handler(); Runnable loopRunnable = new Runnable() { @Override public void

我正在尝试实现一个Android应用程序,它每秒捕获大约1张图片,对每张图片执行一些处理,并将输出发送到一个文件进行存储。我的第一次尝试如下:

public class MainActivity extends Activity {

    ...
    Handler loopHandler = new Handler();
    Runnable loopRunnable = new Runnable() {

        @Override
        public void run() {
            Thread pictureThread = new Thread(pictureRunnable);
            pictureThread.start();
            loopHandler.postDelayed(this, 1000);
        }
    };

    Runnable pictureRunnable = new Runnable() {
        @Override
        public void run() {
            mCamera.takePicture(null, null, mPicture);
        }    
    };

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
        ... My processing code ...
        }
    }
该应用程序在以这种方式拍摄了大约4张照片后冻结。所以,我猜这可能是一种过于天真的方法,但我希望能更深入地理解为什么这样做行不通


有没有办法不直接与视频打交道就可以做到这一点,或者我最终必须创建一些从视频流中提取帧的东西

您可以使用OpenCV来实现这一点。它允许您对从相机接收到的每个帧执行操作

最好的办法是更深入地研究您的代码,准确地了解是什么导致应用程序冻结。也许这与你发布的代码无关,而是与图像的实际处理有关

另一种在过去似乎对我更有效的方法是完全跳过
PictureCallback
。相反,您可以使用
PreviewCallback
()。此回调在每个帧上都会被触发,因此您只需在该帧内检查自上次处理图像以来是否已超过1秒,如果是,则在另一个线程上执行图像处理

我没有测试过这个,但是类似这样的东西:

myCamera.setPreviewCallback(new PreviewCallback() {

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

        // previousTime is defined as a member variable
        long timeElapsed = System.currentTimeMillis() - previousTime;

        if(timeElapsed > 1000) {

            // reset values for the next run
            previousTime = System.currentTimeMillis();

            // process the image (just an example, you should do this inside an AsyncTask)
            Size previewSize = myCamera.getParameters().getPreviewSize();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            YuvImage yuvImage = new YuvImage(data, myCamera.getParameters().getPreviewFormat(), previewSize.width,previewSize.height, null);
            yuvImage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, out);
            byte[] imageBytes = out.toByteArray();

            Options options = new Options();
            options.inSampleSize = 1;
            Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options);

            // you now have the image bitmap which you can use to apply your processing ...
        }

    }
});

它不起作用。在使用代码时,帧速率下降了很多。。。有什么帮助吗?