Android camera resulted image should be rotated after the capture?

后端 未结 4 1859
攒了一身酷
攒了一身酷 2020-12-15 17:29

I\'m writing an Android application that uses the camera. I\'m setting camera display orientation to 90, my activity is in a portrait orientation:

camera.se         


        
相关标签:
4条回答
  • 2020-12-15 17:55

    Try this

    try {
            File f = new File(imagePath);
            ExifInterface exif = new ExifInterface(f.getPath());
            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
    
            int angle = 0;
    
            if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
                angle = 90;
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
                angle = 180;
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
                angle = 270;
            }
    
            Matrix mat = new Matrix();
            mat.postRotate(angle);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
    
            Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
                    null, options);
            bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                    bmp.getHeight(), mat, true);
            ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100,
                    outstudentstreamOutputStream);
            imageView.setImageBitmap(bitmap);
    
        } catch (IOException e) {
            Log.w("TAG", "-- Error in setting image");
        } catch (OutOfMemoryError oom) {
            Log.w("TAG", "-- OOM Error in setting image");
        }
    

    It will work

    0 讨论(0)
  • 2020-12-15 17:56

    Problem is the camera orientation is a complete disaster (as is capturing an image) because OEMs do not adhere to the standard. HTC phones do things one way, Samsung phones do it a different way, the Nexus line seems to adhere no matter which vendor, CM7 based ROMs I think follow the standard no matter which hardware, but you get the idea. You sort of have to determine what to do based on the phone/ROM. See discussion here: Android camera unexplainable rotation on capture for some devices (not in EXIF)

    0 讨论(0)
  • 2020-12-15 17:56
    camera.setDisplayOrientation(90);
    

    I have coded the app for only Portrait Mode.

    Will make the Camera to rotate to 90 degree and This may result in not suitable for all devices in android In order to get the Correct Preview for all android devices use the following code which is refereed in developers site.

    Below you have to send your activity, cameraId = back is 0 and for Front camera is 1

    public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().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;
        //int currentapiVersion = android.os.Build.VERSION.SDK_INT;
            // do something for phones running an SDK before lollipop
            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;
            }
    
        camera.setDisplayOrientation(result);
    } 
    

    This is how to set the setDisplayOrientation for camera

    Now you may have trouble is saving the captured Image in Correct Orientation, which is bug in Camera API to support all devices in android .you can overcome using the Steps below

    PLS NOTE EXIF VALUE WILL NOT GIVE YOU CORRECT VALUE IN ALL DEVICES , So this would help you

    int CameraEyeValue = setPhotoOrientation(CameraActivity.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back
    

    By using the same concept we used before for DisplayOrientation

    public int setPhotoOrientation(Activity activity, int cameraId) {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().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;
        // do something for phones running an SDK before lollipop
        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;
    }
    

    So your final PictureCallBack method should look like

    private PictureCallback getPictureCallback() {
        PictureCallback picture = new PictureCallback() {
    
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                //make a new picture file
                File pictureFile = getOutputMediaFile();
    
                if (pictureFile == null) {
                    return;
                }
                try {
                    //write the file
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    Bitmap bm=null;
    
                    // COnverting ByteArray to Bitmap - >Rotate and Convert back to Data
                    if (data != null) {
                        int screenWidth = getResources().getDisplayMetrics().widthPixels;
                        int screenHeight = getResources().getDisplayMetrics().heightPixels;
                        bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
    
                        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                            // Notice that width and height are reversed
                            Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
                            int w = scaled.getWidth();
                            int h = scaled.getHeight();
                            // Setting post rotate to 90
                            Matrix mtx = new Matrix();
    
                            int CameraEyeValue = setPhotoOrientation(AndroidCameraExample.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back
                            if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation
                                if (CameraEyeValue == 270) {
                                    mtx.postRotate(90);
                                } else if (CameraEyeValue == 90) {
                                    mtx.postRotate(270);
                                }
                            }else{
                                    mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation
                            }
    
                            bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
                        }else{// LANDSCAPE MODE
                            //No need to reverse width and height
                            Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth, screenHeight, true);
                            bm=scaled;
                        }
                    }
                    // COnverting the Die photo to Bitmap
    
    
    
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                    byte[] byteArray = stream.toByteArray();
                    fos.write(byteArray);
                    //fos.write(data);
                    fos.close();
    
                    Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG);
                    toast.show();
    
                } catch (FileNotFoundException e) {
                } catch (IOException e) {
                }
    
                //refresh camera to continue preview
                mPreview.refreshCamera(mCamera);
                mPreview.setCameraDisplayOrientation(CameraActivity.this,GlobalCameraId,mCamera);
            }
        };
        return picture;
    }
    

    As the Works only for Portrait mode using Front and Back camera The Picture is rotated to only portrait mode with correct portrait Orientation in all android devices .

    For LandScape you can Make this as reference and make changes in the below block

       if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation
             if (CameraEyeValue == 270) {
                 mtx.postRotate(90); //change Here 
              } else if (CameraEyeValue == 90) {
                 mtx.postRotate(270);//change Here 
               }
            }else{
               mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation //change Here 
            }
    
    0 讨论(0)
  • 2020-12-15 18:18

    I had the same problem like you, but i've fix it.
    You should use the same code:

    Camera.Parameters parameters = camera.getParameters();
    parameters.setRotation(90);
    camera.setParameters(parameters);
    

    I hope you can use this code too.

    0 讨论(0)
提交回复
热议问题