Android - 相机表面错误

标签 android android-camera

我的应用程序有这段代码,它没有显示任何错误,但每次我在手机上运行它时,它都会崩溃。 有人对此有什么想法吗?谢谢

public class CameraView extends Activity implements SurfaceHolder.Callback,OnClickListener {
        static final int FOTO_MODE = 0;
        private static final String TAG = "CameraTest";
        Camera mCamera;
        boolean mPreviewRunning = false;
        private Context mContext = this;

        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);

            Log.e(TAG, "onCreate");

            Bundle extras = getIntent().getExtras();

            getWindow().setFormat(PixelFormat.TRANSLUCENT);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.camera_surface);
            mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
            mSurfaceView.setOnClickListener(this);
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        //private SurfaceView mSurfaceView;
        //private SurfaceHolder mSurfaceHolder;

        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
        }

        Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
            public void onPictureTaken(byte[] imageData, Camera c) {

                if (imageData != null) {

                    Intent mIntent = new Intent();

                    StoreByteImage(mContext, imageData, 50,
                            "ImageName");
                    mCamera.startPreview();

                    setResult(FOTO_MODE, mIntent);
                    finish();

                }
            }
        };

        protected void onResume() {
            Log.e(TAG, "onResume");
            super.onResume();
        }

        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
        }

        protected void onStop() {
            Log.e(TAG, "onStop");
            super.onStop();
        }

        public void surfaceCreated(SurfaceHolder holder) {
            Log.e(TAG, "surfaceCreated");
            mCamera = Camera.open();

        }

        private Camera.Size getBestPreviewSize(int width, int height)
        {
            Camera.Size result=null;    
            Camera.Parameters p = mCamera.getParameters();
            for (Camera.Size size : p.getSupportedPreviewSizes()) {
                if (size.width<=width && size.height<=height) {
                    if (result==null) {
                        result=size;
                    } else {
                        int resultArea=result.width*result.height;
                        int newArea=size.width*size.height;

                        if (newArea>resultArea) {
                            result=size;
                        }
                    }
                }
            }
            return result;
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            Log.e(TAG, "surfaceChanged");

            // XXX stopPreview() will crash if preview is not running
            if (mPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters p = mCamera.getParameters();
            Camera.Size bestSize = getBestPreviewSize(w, h);
            p.setPreviewSize(bestSize.width, bestSize.height);
            mCamera.setParameters(p);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.e(TAG, "surfaceDestroyed");
            mCamera.stopPreview();
            mPreviewRunning = false;
            mCamera.release();
        }

        private SurfaceView mSurfaceView;
        private SurfaceHolder mSurfaceHolder;

        public void onClick(View arg0) {

            mCamera.takePicture(null, mPictureCallback, mPictureCallback);

        }

        public static boolean StoreByteImage(Context mContext, byte[] imageData,
                int quality, String expName) {

            File sdImageMainDirectory = new File("/sdcard");
            FileOutputStream fileOutputStream = null;
            String nameFile;
            try {

                BitmapFactory.Options options=new BitmapFactory.Options();
                options.inSampleSize = 5;

                Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
                        imageData.length,options);


                fileOutputStream = new FileOutputStream(
                        sdImageMainDirectory.toString() +"/image.jpg");


                BufferedOutputStream bos = new BufferedOutputStream(
                        fileOutputStream);

                myImage.compress(CompressFormat.JPEG, quality, bos);

                bos.flush();
                bos.close();

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return true;
        }

        /*@Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceChanged");

            // XXX stopPreview() will crash if preview is not running
            if (mPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;
        }

        @Override
        public void surfaceCreated(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceCreated");
            mCamera = Camera.open();

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceDestroyed");
            mCamera.stopPreview();
            mPreviewRunning = false;
            mCamera.release();

        }*/
}

最佳答案

您知道错误实际发生在哪里吗(即您在 logcat 窗口中看到什么输出?)

我的疯狂猜测是这一行导致了问题:

p.setPreviewSize(w, h)

您只能将预览尺寸设置为您的设备支持的尺寸之一 - 检查 Camera.Parameters 中的 getSupportedPreviewSizes() 方法并选择与您的 View 最接近的匹配:

private Camera.Size getBestPreviewSize(int width, int height)
{
    Camera.Size result=null;    
    Camera.Parameters p = camera.getParameters();
    for (Camera.Size size : p.getSupportedPreviewSizes()) {
        if (size.width<=width && size.height<=height) {
            if (result==null) {
                result=size;
            } else {
                int resultArea=result.width*result.height;
                int newArea=size.width*size.height;

                if (newArea>resultArea) {
                    result=size;
                }
            }
        }
    }
    return result;
}

(上面的代码来自@seantron:Picture distorted with Camera and getOptimalPreviewSize)

关于Android - 相机表面错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5802681/

相关文章:

java - Android Studio : GridLayout doens´t work in v. 3.5

Android:在不连接到预配置网络的情况下检查wifi密码有效性

android - 您可以从 Html 5 Web 应用程序启动 native 相机应用程序吗?

android - 如何根据屏幕分辨率更改点的位置?

java - Android Studio - build.gradle 未捕获翻译错误 ExecutionException OutOfMemory 中的问题

java - 由 : java. io.NotSerializedException : android.net.Uri$StringUri 引起

Android 12(SDK > 29)ACTION_IMAGE_CAPTURE 的 Extra_Output 不起作用

java - 如何从服务中定期捕获相机照片?

android - 如何在设备的相机 View 中显示位置标记

android - 为 Android 相机预览添加效果