Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android保存实时相机预览图像_Android_Android Camera - Fatal编程技术网

Android保存实时相机预览图像

Android保存实时相机预览图像,android,android-camera,Android,Android Camera,我正在尝试实时保存相机预览图像,我的目标是保存曲面视图上预览的至少1fps。 我被困在这上面了 mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() { private long timestamp=0; public synchronized void onPreviewFrame(byte[] data, Camera camera) { Log.v("Cam

我正在尝试实时保存相机预览图像,我的目标是保存曲面视图上预览的至少1fps。 我被困在这上面了

mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
        private long timestamp=0;
        public synchronized void onPreviewFrame(byte[] data, Camera camera) {
            Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
            timestamp=System.currentTimeMillis();
            try{
                FileOutputStream out;
                try {
                    Bitmap bmp=BitmapFactory.decodeByteArray(data,0,data.length);
                    out = new FileOutputStream("/mnt/sdcard/data/pippo.png");
                    bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }           
                camera.addCallbackBuffer(data);
            }catch (Exception e) {
                Log.e("CameraTest", "addCallbackBuffer error");
                return;
            }
            return;
        }
    });
我想字节数组传入了

public synchronized void onPreviewFrame(byte[] data, Camera camera)
包含原始数据图像,因此我尝试将其转换为位图并保存在SD卡上。 我的问题是:

  • 为了实现我的目标,这是休耕的正确途径吗
  • 我在log SkImageDecoder::Factory中得到这个错误返回null我想它与位图转换有关,对吗
  • 欢迎提出任何建议。 多谢各位

    下面是完整的代码:

    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import android.app.Activity;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.ImageFormat;
    import android.hardware.Camera;
    import android.hardware.Camera.ErrorCallback;
    import android.hardware.Camera.Size;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.SurfaceHolder.Callback;
    
    public class Demo extends Activity {
        SurfaceView mVideoCaptureView;
        private Camera mCamera;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
            SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
            videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            videoCaptureViewHolder.addCallback(new Callback() {
                public void surfaceDestroyed(SurfaceHolder holder) {
                }
    
                public void surfaceCreated(SurfaceHolder holder) {
                    startVideo();
                }
    
                public void surfaceChanged(SurfaceHolder holder, int format,
                        int width, int height) {
                }
            });
        }
        private void startVideo() {
            SurfaceHolder videoCaptureViewHolder = null;
            try {
                mCamera = Camera.open();
            } catch (RuntimeException e) {
                Log.e("CameraTest", "Camera Open filed");
                return;
            }
            mCamera.setErrorCallback(new ErrorCallback() {
                public void onError(int error, Camera camera) {
                }
            }); 
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewFrameRate(30);
            parameters.setPreviewFpsRange(15000,30000);
            List<int[]> supportedPreviewFps=parameters.getSupportedPreviewFpsRange();
            Iterator<int[]> supportedPreviewFpsIterator=supportedPreviewFps.iterator();
            while(supportedPreviewFpsIterator.hasNext()){
                int[] tmpRate=supportedPreviewFpsIterator.next();
                StringBuffer sb=new StringBuffer();
                sb.append("supportedPreviewRate: ");
                for(int i=tmpRate.length,j=0;j<i;j++){
                    sb.append(tmpRate[j]+", ");
                }
                Log.v("CameraTest",sb.toString());
            }
    
            List<Size> supportedPreviewSizes=parameters.getSupportedPreviewSizes();
            Iterator<Size> supportedPreviewSizesIterator=supportedPreviewSizes.iterator();
            while(supportedPreviewSizesIterator.hasNext()){
                Size tmpSize=supportedPreviewSizesIterator.next();
                Log.v("CameraTest","supportedPreviewSize.width = "+tmpSize.width+"supportedPreviewSize.height = "+tmpSize.height);
            }
    
            mCamera.setParameters(parameters);
            if (null != mVideoCaptureView)
                videoCaptureViewHolder = mVideoCaptureView.getHolder();
            try {
                mCamera.setPreviewDisplay(videoCaptureViewHolder);
            } catch (Throwable t) {
            }
    
            Log.v("CameraTest","Camera PreviewFrameRate = "+mCamera.getParameters().getPreviewFrameRate());
            Size previewSize=mCamera.getParameters().getPreviewSize();
            int dataBufferSize=(int)(previewSize.height*previewSize.width*
                                   (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
    
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);
    
            mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
                private long timestamp=0;
                public synchronized void onPreviewFrame(byte[] data, Camera camera) {
                    Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
                    timestamp=System.currentTimeMillis();
                    try{
                        FileOutputStream out;
                        try {
                            Bitmap bmp=BitmapFactory.decodeByteArray(data,0,data.length);
                            out = new FileOutputStream("/mnt/sdcard/data/pippo.png");
                            bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
                        } catch (FileNotFoundException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }           
                        camera.addCallbackBuffer(data);
                    }catch (Exception e) {
                        Log.e("CameraTest", "addCallbackBuffer error");
                        return;
                    }
                    return;
                }
            });
            try {
                mCamera.startPreview();
            } catch (Throwable e) {
                mCamera.release();
                mCamera = null;
                return;
            }
        }
        private void stopVideo() {
            if(null==mCamera)
                return;
            try {
                mCamera.stopPreview();
                mCamera.setPreviewDisplay(null);
                mCamera.setPreviewCallbackWithBuffer(null);
                mCamera.release();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            mCamera = null;
        }
        public void finish(){
            stopVideo();
            super.finish();
        };
    }
    
    import java.io.FileNotFoundException;
    导入java.io.FileOutputStream;
    导入java.io.IOException;
    导入java.util.Iterator;
    导入java.util.List;
    导入android.app.Activity;
    导入android.graphics.Bitmap;
    导入android.graphics.BitmapFactory;
    导入android.graphics.ImageFormat;
    导入android.hardware.Camera;
    导入android.hardware.Camera.ErrorCallback;
    导入android.hardware.Camera.Size;
    导入android.os.Bundle;
    导入android.util.Log;
    导入android.view.SurfaceHolder;
    导入android.view.SurfaceView;
    导入android.view.SurfaceHolder.Callback;
    公共类演示扩展活动{
    SurfaceView mVideoCaptureView;
    私人摄像机麦卡梅拉;
    @凌驾
    创建时的公共void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mVideoCaptureView=(SurfaceView)findviewbyd(R.id.video\u capture\u surface);
    SurfaceHolder videoCaptureViewHolder=mvideCaptureView.getHolder();
    videoCaptureViewHolder.setType(SurfaceHolder.SURFACE类型推送缓冲区);
    videoCaptureViewHolder.addCallback(新回调(){
    公共空间表面覆盖(表面覆盖物持有人){
    }
    已创建的公共空白表面(表面持有人){
    startVideo();
    }
    公共无效表面更改(表面文件夹持有者,整数格式,
    整数宽度,整数高度){
    }
    });
    }
    私有void startVideo(){
    SurfaceHolder videoCaptureViewHolder=null;
    试一试{
    mCamera=Camera.open();
    }捕获(运行时异常e){
    Log.e(“摄像机测试”、“摄像机开放文件”);
    返回;
    }
    setErrorCallback(新的ErrorCallback(){
    公共无效onError(内部错误,摄像头){
    }
    }); 
    Camera.Parameters=mCamera.getParameters();
    参数。setPreviewFrameRate(30);
    参数。setPreviewFpsRange(1500030000);
    列出supportedPreviewFps=参数。getSupportedPreviewFpsRange();
    迭代器supportedPreviewfpsierator=supportedPreviewFps.Iterator();
    while(supportedPreviewfpsierator.hasNext()){
    int[]tmpRate=supportedPreviewFpsIterator.next();
    StringBuffer sb=新的StringBuffer();
    某人附加(“supportedPreviewRate:”);
    
    对于(int i=tmpRate.length,j=0;jBitmapFactory不知道如何解码来自摄影机的预览数据,因为它是一个原始像素数组,没有标识信息。这就是它引发异常的原因

    您必须自己将数据转换/解释为RGB格式,并从中构造位图。默认情况下,相机以该格式提供预览数据。您可以找到有关NV21的更多详细信息。要创建全彩RGB图像,您需要对两个色度通道进行上采样,然后将结果转换为RGB


    如果您可以保存JPEG,也可以使用该类进行保存。

    BitmapFactory不知道如何解码来自相机的预览数据,因为它是一个原始像素数组,没有标识信息。这就是它引发异常的原因

    您必须自己将数据转换/解释为RGB格式,并从中构造位图。默认情况下,相机以该格式提供预览数据。您可以找到有关NV21的更多详细信息。要创建全彩RGB图像,您需要对两个色度通道进行上采样,然后将结果转换为RGB

    如果您同意保存JPEG,也可以使用该类来保存