【问题标题】:How to get frame of SurfaceView each second?如何每秒获取 SurfaceView 的帧?
【发布时间】:2016-12-02 14:47:02
【问题描述】:

我想每秒从相机预览中截取屏幕截图。

我使用 SurfaceView 显示我的相机的预览。我需要每秒预览一次(截图),但不使用拍照。

我知道mCamera.setPreviewCallbackWithBuffer 方法,但我只能从中取帧一次。为了让它每秒更新一次,我需要启动 MediaRecorder 并录制视频。但是对于视频我需要设置outputFile,这意味着它可以使用大量的内存。

 mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            Camera.Parameters parameters = camera.getParameters();
            int width = parameters.getPreviewSize().width;
            int height = parameters.getPreviewSize().height;

            YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            yuv.compressToJpeg(new Rect(0, 0, width, height), 50, out);

            byte[] bytes = out.toByteArray();
            final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

        }
    });

如何在不设置输出文件和每秒拍照的情况下做到这一点?

【问题讨论】:

    标签: android android-camera screenshot surfaceview


    【解决方案1】:

    如果您使用SurfaceView 显示您的相机预览,您可以尝试每秒调用一次Camera#takePicture

    要大约每隔一秒安排一次,您可以使用任何视图的postDelayed 方法。例如:

    private Runnable capturePreview = new Runnable() {
        @Override
        public void run() {
            camera.takePicture(null, null, callback);
    
            // Run again after approximately 1 second.
            surfaceView.postDelayed(this, 1000);
        }
    }
    
    private Camera.PictureCallback callback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    
            // Do whatever you need with your bitmap. 
    
            // Consider freeing the memory afterwards.
            bitmap.recycle();
        }
    }
    

    您可以在预览准备好时通过调用来启动它:

    surfaceView.postDelayed(capturePreview, 1000);
    

    并在不再显示预览时停止:

    surfaceView.removeCallbacks(capturePreview);
    

    如果您使用TextureView,您可以简单地使用getBitmap(),这样您就可以轻松获取其当前内容。

    因此上面的代码变成这样:

    private Runnable capturePreview = new Runnable() {
        @Override
        public void run() {
            Bitmap preview = textureView.getBitmap();
    
            // Do whatever you need with the bitmap.
    
            // Run again after approximately 1 second.
            textureView.postDelayed(this, 1000);
        }
    }, 1000);
    

    再次开始:

    textureView.postDelayed(capturePreview, 1000);
    

    然后停止:

    textureView.removeCallbacks(capturePreview);
    

    【讨论】:

    • 收到此错误:java.lang.RuntimeException: takePicture failed at android.hardware.Camera.native_takePicture(Native Method) 在行中:camera.takePicture(null, null, MainActivity.this);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多