无法生成相机预览视图

时间:2017-06-20 17:36:32

标签: android

所以我有一个简单的相机管理器课程,我想在对话框中生成相机预览。除了相机预览未在对话框中显示的部分外,一切都有效!这是调用相机的类

经理级别:

public class CameraExample extends AnimatedViewContainer {

    private final static String TAG = "CameraExample";

    private Context mContext;
    private SurfaceView mPreview;
    public CameraExample(Context context, int i) {
        super(context, i);
        mContext = context;

    }

    @Override
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) {
        containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false);
        FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview);

        //this have been line moved here from constructor
        mPreview = (SurfaceView) findViewById(R.id.surfaceView);
        CameraPreview mgr = new CameraPreview(mContext, mPreview);
        mgr.init();

        // Add preview for inflation
        previewFrame.addView(mPreview);

    }
}

以下是Camera Manager课程:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    private static String TAG = "CameraManager";

    private Context mContext = null;
    private SurfaceView mPreview = null;
    private SurfaceHolder mHolder = null;
    private Camera mCamera = null;
    private int mFrontFaceID = -1;
    private int mBackFaceID = -1;
    private int mActualFacingID = -1;

    public CameraPreview(Context context, SurfaceView preview) {
        super(context);
        mContext = context;
        mPreview = preview;
        mHolder = mPreview.getHolder();
        mHolder.addCallback(this);
    }

    //called in onCreate
    public void init() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                mFrontFaceID = i;
            }
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                mBackFaceID = i;
            }
        }
        if (mActualFacingID == -1) {
            if (mFrontFaceID != -1) {
                mActualFacingID = mFrontFaceID;
            } else {
                mActualFacingID = mBackFaceID;
            }
        }
        //At least one one camera will be available because of manifest declaration
    }

    //called first on surface created
    public void start() {
        Log.i(TAG, "startCamera()");
        if (mCamera == null) {
            mCamera = getCameraInstance(mActualFacingID);
        }
        if (mCamera == null) {
            Log.i(TAG, "can't get camera instance");
            return;
        }
        try {
            mCamera.setPreviewDisplay(mHolder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        setCameraDisplayOrientation();
        setBestSupportedSizes();
        mCamera.startPreview();
    }

    public void stop() {
        Log.i(TAG, "stopCamera()");
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    public void switchFacing() {
        if (mFrontFaceID == -1 || mBackFaceID == -1) {
            return;
        }
        stop();
        if (mActualFacingID == mFrontFaceID) {
            mActualFacingID = mBackFaceID;
        } else {
            mActualFacingID = mFrontFaceID;
        }
        start();
    }

    public Camera getCameraInstance(int cameraID) {
        Camera c = null;
        if (cameraID != -1) {
            try {
                c = Camera.open(cameraID);
            } catch (Exception e) {
                e.printStackTrace();
                Log.i(TAG, "error opening camera: " + cameraID);
            }
        }
        return c;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated()");
        start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged()");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed()");
        stop();
    }

    private void setBestSupportedSizes() {
        if (mCamera == null) {
            return;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        List<Point> pictureSizes=getSortedSizes(parameters.getSupportedPictureSizes());

        List<Point> previewSizes=getSortedSizes(parameters.getSupportedPreviewSizes());

        Point previewResult=null;
        for (Point size:previewSizes){
            float ratio = (float) size.y / size.x;
            if(Math.abs(ratio-4/(float)3)<0.05){ //Aspect ratio of 4/3 because otherwise the image scales to much.
                previewResult=size;
                break;
            }
        }
        Log.i(TAG,"preview: "+previewResult.x+"x"+previewResult.y);
        Point pictureResult=null;
        if(previewResult!=null){
            float previewRatio=(float)previewResult.y/previewResult.x;
            for (Point size:pictureSizes){
                float ratio = (float) size.y / size.x;
                if(Math.abs(previewRatio-ratio)<0.05){
                    pictureResult=size;
                    break;
                }
            }
        }
        Log.i(TAG,"preview: "+pictureResult.x+"x"+pictureResult.y);

        if(previewResult!=null && pictureResult!=null){
            Log.i(TAG,"best preview: "+previewResult.x+"x"+previewResult.y);
            Log.i(TAG, "best picture: " + pictureResult.x + "x" + pictureResult.y);
            parameters.setPreviewSize(previewResult.y, previewResult.x);
            parameters.setPictureSize(pictureResult.y, pictureResult.x);
            mCamera.setParameters(parameters);
            mPreview.setBackgroundColor(Color.TRANSPARENT); //in the case of errors needed
        }else{
            mCamera.stopPreview();
            mPreview.setBackgroundColor(Color.BLACK);
        }
    }

    private List<Point> getSortedSizes(List<Camera.Size> sizes) {
        ArrayList<Point> list = new ArrayList<>();

        for (Camera.Size size : sizes) {
            int height;
            int width;
            if (size.width > size.height) {
                height = size.width;
                width = size.height;
            } else {
                height = size.height;
                width = size.width;
            }
            list.add(new Point(width, height));

        }

        Collections.sort(list, new Comparator<Point>() {
            @Override
            public int compare(Point lhs, Point rhs) {
                long lhsCount = lhs.x * (long) lhs.y;
                long rhsCount = rhs.x * (long) rhs.y;
                if (lhsCount < rhsCount) {
                    return 1;
                }
                if (lhsCount > rhsCount) {
                    return -1;
                }
                return 0;
            }
        });
        return list;
    }

    public void onPictureTaken(byte[] data, Camera camera) {
        //do something with your picture
    }

    //ROTATION
    private void setCameraDisplayOrientation() {
        if (mCamera != null) {
            mCamera.setDisplayOrientation((int) getRotation());
        }
    }

    @Override
    public float getRotation() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(mActualFacingID, info);
        int rotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        return result;
    }
}

最后这里是XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="@dimen/photo_example_height">
        <SurfaceView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/surfaceView" />
    </FrameLayout>
</LinearLayout>

我确实拥有所有必需的permissions,问题是编译或运行时没有错误!我的错误是全能的否认我在对话框中的预览?

1 个答案:

答案 0 :(得分:1)

我想问题就在这一行:

mPreview = (SurfaceView) findViewById(R.id.surfaceView);

您正试图从您的活动中获取它,但它并不存在。 Surfaceview实际上是在Container中。试试这个:

用以下代码替换上面的代码:

mPreview = (SurfaceView) containerViews[index].findViewById(R.id.surfaceView);

希望它能奏效!