Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/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,我使用的是一款简单的定制相机,只需点击按钮即可拍照 相机会以错误的方向(横向)显示预览,即使手机处于纵向,图像也会显示一些缩放的图像 我在谷歌上搜索了一下,找到了很多解决这个问题的方法,我尝试了所有的方法,但是没有人能解决我的问题 我想我遗漏了一些主要的概念,我想不出来 CameraActivity.java public class CameraActivity extends AppCompatActivity { private static final String TAG =

我使用的是一款简单的定制相机,只需点击按钮即可拍照

相机会以错误的方向(横向)显示预览,即使手机处于纵向,图像也会显示一些缩放的图像

我在谷歌上搜索了一下,找到了很多解决这个问题的方法,我尝试了所有的方法,但是没有人能解决我的问题

我想我遗漏了一些主要的概念,我想不出来

CameraActivity.java

public class CameraActivity extends AppCompatActivity {
    private static final String TAG = "CameraActivity";
    private Camera mCamera;
    private CameraPreview mPreview;
    private PictureCallback mPictureCallback;
    private Context myContext;
    private FrameLayout cameraPreview;
    private boolean frontCamera = false, backCamera = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        initialize();
    }

    private void findViews() {
        cameraPreview = (FrameLayout) findViewById(R.id.camera_preview);
    }

    public void initialize() {
        findViews();
        myContext = this;
        mCamera = Camera.open(findBackFacingCamera());
        mPreview = new CameraPreview(myContext, mCamera);
        cameraPreview.addView(mPreview);
    }

    private int findFrontFacingCamera() {
        int cameraId = -1; // initialized with empty
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
                cameraId = i;
                frontCamera = true;
                break;
            }
        }
        return cameraId;
    }

    private int findBackFacingCamera() {
        int cameraId = -1; // initialized with empty
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                backCamera = true;
                break;
            }
        }
        return cameraId;
    }

    @Override
    protected void onResume() {
        super.onResume();
        //mPictureCallback=getPi
        if (!hasCamera(myContext)) {
            Log.e(TAG, "Sorry, your phone does not have a camera!");
        }
        if (mCamera == null) {
            if (findFrontFacingCamera() == 1) {
                releaseCamera();
                chooseCamera();
            }
        }
    }

    private void chooseCamera() {
        // If currently front camera is opened,then switch to back camera
        if (frontCamera) {
            int cameraId = findBackFacingCamera();
            if (cameraId > 0) {
                // Open backfacing camera
                // Set picture callback
                // refresh the preview
                mCamera = Camera.open(cameraId);
                mPictureCallback = getPictureCallBack();
                mPreview.refreshCamera(mCamera);
            }
        } else {
            int cameraId = findFrontFacingCamera();
            if (cameraId > 0) {
                mCamera = Camera.open(cameraId);
                mPictureCallback = getPictureCallBack();
                mPreview.refreshCamera(mCamera);
            }
        }
    }

    private PictureCallback getPictureCallBack() {
        PictureCallback pictureCallback = new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {


                File pictureFile = getOutputMediaFile();
                if (pictureFile == null) {
                    return;
                }
                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                    Log.e(TAG, " picture saved at " + pictureFile.getName());
                } catch (Exception e) {
                    Log.e(TAG, " getPictureCallBack  " + e);
                }
                mPreview.refreshCamera(mCamera);
            }
        };
        return pictureCallback;
    }

    private File getOutputMediaFile() {
        // make a new storage directory inside sd card
        File mediaStorage = new File("/sdcard/", "Tootle Camera");

        // if Tootle Camera directory doesn't exist
        if (!mediaStorage.exists()) {
            if (!mediaStorage.mkdirs()) {
                return null;
            } else {
                mediaStorage.mkdirs();
            }
        }

        String timeStamp = new SimpleDateFormat("dd/MM/yyy_hh:mm:ss a").format(new Date());

        // make media file
        File mediaFile = new File(mediaStorage.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        return mediaFile;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }

    public boolean hasCamera(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

        private static final String TAG = "CameraPreview";
        private SurfaceHolder mHolder;
        private Camera mCamera;
        private boolean isPreviewRunning = false;

        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
        }


        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            try {
                // create the surface and start camera previre
                if (mCamera == null) {
                    mCamera.setPreviewDisplay(mHolder);
                    mCamera.startPreview();

                }


            } catch (Exception e) {
                Log.e(TAG, " surfaceCreated " + e);
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
            //refreshCamera(mCamera);

            if (isPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters parameters = mCamera.getParameters();
            Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

            if (display.getRotation() == Surface.ROTATION_0) {
                parameters.setPreviewSize(height, width);
                mCamera.setDisplayOrientation(90);
            }

            if (display.getRotation() == Surface.ROTATION_90) {
                parameters.setPreviewSize(width, height);
            }

            if (display.getRotation() == Surface.ROTATION_180) {
                parameters.setPreviewSize(height, width);
            }

            if (display.getRotation() == Surface.ROTATION_270) {
                parameters.setPreviewSize(width, height);
                mCamera.setDisplayOrientation(180);
            }

            mCamera.setParameters(parameters);
            previewCamera();

        }

        public void refreshCamera(Camera camera) {

            if (mHolder == null) {
                // preview surface does not exist
                return;
            }
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                Log.e(TAG, " refreshCamera " + e);
            }
            setCamera(camera);
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
            } catch (Exception e) {
                Log.e(TAG, " refreshCamera " + e);
            }
        }

        private void setCamera(Camera camera) {
            //method to set a camera instance
            mCamera = camera;
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            mCamera.release();
        }

        public void previewCamera() {
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
                isPreviewRunning = true;
            } catch (Exception e) {
                Log.d(TAG, "Cannot start preview " + e);
            }
        }
    }

如果您有文件路径和位图,请使用以下方法检查旋转并修复它:

  public Bitmap checkRotation(String filePath, Bitmap scaledBitmap) {
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Log.d("EXIF", "Exif: " + orientation);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                    true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return scaledBitmap;
    }

在您的CameraPreview.java中

public class CameraActivity extends AppCompatActivity {
    private static final String TAG = "CameraActivity";
    private Camera mCamera;
    private CameraPreview mPreview;
    private PictureCallback mPictureCallback;
    private Context myContext;
    private FrameLayout cameraPreview;
    private boolean frontCamera = false, backCamera = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        initialize();
    }

    private void findViews() {
        cameraPreview = (FrameLayout) findViewById(R.id.camera_preview);
    }

    public void initialize() {
        findViews();
        myContext = this;
        mCamera = Camera.open(findBackFacingCamera());
        mPreview = new CameraPreview(myContext, mCamera);
        cameraPreview.addView(mPreview);
    }

    private int findFrontFacingCamera() {
        int cameraId = -1; // initialized with empty
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
                cameraId = i;
                frontCamera = true;
                break;
            }
        }
        return cameraId;
    }

    private int findBackFacingCamera() {
        int cameraId = -1; // initialized with empty
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                backCamera = true;
                break;
            }
        }
        return cameraId;
    }

    @Override
    protected void onResume() {
        super.onResume();
        //mPictureCallback=getPi
        if (!hasCamera(myContext)) {
            Log.e(TAG, "Sorry, your phone does not have a camera!");
        }
        if (mCamera == null) {
            if (findFrontFacingCamera() == 1) {
                releaseCamera();
                chooseCamera();
            }
        }
    }

    private void chooseCamera() {
        // If currently front camera is opened,then switch to back camera
        if (frontCamera) {
            int cameraId = findBackFacingCamera();
            if (cameraId > 0) {
                // Open backfacing camera
                // Set picture callback
                // refresh the preview
                mCamera = Camera.open(cameraId);
                mPictureCallback = getPictureCallBack();
                mPreview.refreshCamera(mCamera);
            }
        } else {
            int cameraId = findFrontFacingCamera();
            if (cameraId > 0) {
                mCamera = Camera.open(cameraId);
                mPictureCallback = getPictureCallBack();
                mPreview.refreshCamera(mCamera);
            }
        }
    }

    private PictureCallback getPictureCallBack() {
        PictureCallback pictureCallback = new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {


                File pictureFile = getOutputMediaFile();
                if (pictureFile == null) {
                    return;
                }
                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                    Log.e(TAG, " picture saved at " + pictureFile.getName());
                } catch (Exception e) {
                    Log.e(TAG, " getPictureCallBack  " + e);
                }
                mPreview.refreshCamera(mCamera);
            }
        };
        return pictureCallback;
    }

    private File getOutputMediaFile() {
        // make a new storage directory inside sd card
        File mediaStorage = new File("/sdcard/", "Tootle Camera");

        // if Tootle Camera directory doesn't exist
        if (!mediaStorage.exists()) {
            if (!mediaStorage.mkdirs()) {
                return null;
            } else {
                mediaStorage.mkdirs();
            }
        }

        String timeStamp = new SimpleDateFormat("dd/MM/yyy_hh:mm:ss a").format(new Date());

        // make media file
        File mediaFile = new File(mediaStorage.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        return mediaFile;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }

    public boolean hasCamera(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

        private static final String TAG = "CameraPreview";
        private SurfaceHolder mHolder;
        private Camera mCamera;
        private boolean isPreviewRunning = false;

        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
        }


        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            try {
                // create the surface and start camera previre
                if (mCamera == null) {
                    mCamera.setPreviewDisplay(mHolder);
                    mCamera.startPreview();

                }


            } catch (Exception e) {
                Log.e(TAG, " surfaceCreated " + e);
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
            //refreshCamera(mCamera);

            if (isPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters parameters = mCamera.getParameters();
            Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

            if (display.getRotation() == Surface.ROTATION_0) {
                parameters.setPreviewSize(height, width);
                mCamera.setDisplayOrientation(90);
            }

            if (display.getRotation() == Surface.ROTATION_90) {
                parameters.setPreviewSize(width, height);
            }

            if (display.getRotation() == Surface.ROTATION_180) {
                parameters.setPreviewSize(height, width);
            }

            if (display.getRotation() == Surface.ROTATION_270) {
                parameters.setPreviewSize(width, height);
                mCamera.setDisplayOrientation(180);
            }

            mCamera.setParameters(parameters);
            previewCamera();

        }

        public void refreshCamera(Camera camera) {

            if (mHolder == null) {
                // preview surface does not exist
                return;
            }
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                Log.e(TAG, " refreshCamera " + e);
            }
            setCamera(camera);
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
            } catch (Exception e) {
                Log.e(TAG, " refreshCamera " + e);
            }
        }

        private void setCamera(Camera camera) {
            //method to set a camera instance
            mCamera = camera;
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            mCamera.release();
        }

        public void previewCamera() {
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
                isPreviewRunning = true;
            } catch (Exception e) {
                Log.d(TAG, "Cannot start preview " + e);
            }
        }
    }
之后

写下:

mCamera.setDisplayOrientation(90);
mCamera.startPreview();

屏幕快照不是捕获的图像,而是实时相机预览。您不应使用预览曲面的大小来设置相机的预览大小。您应该迭代getSupportedPreviewSizes以获得最佳匹配。要选择摄像机实时预览的纵向方向,请使用camera.setDisplayOrientation()。