Photo rotated from camera (SAMSUNG device)

时间秒杀一切 提交于 2019-12-22 06:01:28

问题


i hate this company. All them devices have a lot of bugs. Ok question : Im trying to fix stupid problem (which as i know exist more than 5 years) Its photo taken from camera - rotated on 90 degree. I have two devices :

  Nexus 5p and Samsung j2  
  Nexus - work perfect. Everything fine. 
  Samsung - photo rotated

For example :

Photo size - nexus : Portrate : width 1000, height 1900.  Landscape :
width 1900 , height 1000

Lets see on samsung device :

Photo size  - Portrate: width 1900(?????) height - 1000(????)
rotate to landscape : width 1900 height 1000

After some testing : if make photo in landscape mode on samsung device - than everything ok. Photo not rotated

If make photo in PORTRATE - photo rotated on 90 degree. (BUT size of photo as on landscape (HOW ITS POSSIBLE) ?

Anyone know how to fix this stupid bug ? Maybe any can tell me how to detect orientation for camera ? Im using IntentActivity for photo :

String _path = Environment.getExternalStorageDirectory()
                                    + File.separator + "camera_img.jpg";
                            File file = new File(_path);
                            Uri outputFileUri = Uri.fromFile(file);
                            Intent intent = new Intent(
                                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
                            startActivityForResult(intent, CAMERA_REQUEST);

Any help ? I also add a checker , if its samsung device than rotate. But rotation good only if we create photo in portrate mode. In landscape everything fine. So i need somehow detected in which orientation photo was created. Any one know ?


回答1:


UPD 29.08.2018 Hello guys, i detect that this method does't work with samsung device based on android 8+. I dont have samsung s8 (for example) and can't understand why this again not work there. If someone can test and check why this not work - lets try to fix this together.

I found how to fix : well its realy stupid and very hard for me

First step get activity result

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {

            String _path = Environment.getExternalStorageDirectory() + File.separator + "TakenFromCamera.jpg";
            String p1 = Environment.getExternalStorageDirectory().toString();
            String fName = "/TakenFromCamera.jpg";
            final int rotation = getImageOrientation(_path);
            File file = resaveBitmap(p1, fName, rotation);
            Bitmap mBitmap = BitmapFactory.decodeFile(_path);

main stesps its : getImageOrientation before changes in file.

1) getImageOrientation (by path)
2) resave file (if need send to server, if you need only for preview we can skip this step)
3) get correct bitmap from file

for preview enough only step 1 and 3, and using this function - just rotate bitmap.

private Bitmap checkRotationFromCamera(Bitmap bitmap, String pathToFile, int rotate) {
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return rotatedBitmap;
    }

getImageOrientation

public static int getImageOrientation(String imagePath) {
    int rotate = 0;
    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return rotate;
}

and resaveBitmap if need

private File resaveBitmap(String path, String filename, int rotation) { //help for fix landscape photos
        String extStorageDirectory = path;
        OutputStream outStream = null;
        File file = new File(filename);
        if (file.exists()) {
            file.delete();
            file = new File(extStorageDirectory, filename);
        }
        try {
            // make a new bitmap from your file
            Bitmap bitmap = BitmapFactory.decodeFile(path + filename);
            bitmap = checkRotationFromCamera(bitmap, path + filename, rotation);
            bitmap = Bitmap.createScaledBitmap(bitmap, (int) ((float) bitmap.getWidth() * 0.3f), (int) ((float) bitmap.getHeight() * 0.3f), false);
            bitmap = Utils.getCircleImage(bitmap);
            outStream = new FileOutputStream(path + filename);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

thats all :) and everything work fine




回答2:


If you want to rotate an image but you only have the byte array, you can use this:

private byte[] rotationFromCamera(byte[] data) {
    int rotation = Exif.getOrientation(data);
    if(rotation == 0) return data;
    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, null);
    Matrix matrix = new Matrix();
    matrix.postRotate(rotation);
    Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    return stream.toByteArray();
}

and this exif util from this answer

This is a bit slow if the image is large.




回答3:


Found this here, works for me Samsung S8.

static final String[] CONTENT_ORIENTATION = new String[] {
            MediaStore.Images.ImageColumns.ORIENTATION
    };


public static int getExifOrientation(Context context, Uri uri) {
    ContentResolver contentResolver = context.getContentResolver();
    Cursor cursor = null;
    try {
        String id = DocumentsContract.getDocumentId(uri);
        id = id.split(":")[1];
        cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                CONTENT_ORIENTATION, MediaStore.Images.Media._ID + " = ?", new String[] { id }, null);
        if (cursor == null || !cursor.moveToFirst()) {
            return 0;
        }
        return cursor.getInt(0);
    } catch (RuntimeException ignored) {
        // If the orientation column doesn't exist, assume no rotation.
        return 0;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

This works when I get the image from Gallery Intent.ACTION_GET_CONTENT.

Tested it with MediaStore.ACTION_IMAGE_CAPTURE, and it returned 0. But maybe I'm doing something wrong.




回答4:


Are you taking the picture yourself with the camera API ? If so you can get the orientation with: Camera1 API :

CameraInfo cameraInfo = new CameraInfo();
int sensorOrientation = cameraInfo.orientation;

Camera2 API :

CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = mCameraCharacteristics;
int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);



回答5:


Using Glide lib could solve the issue

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_PICK_PHOTO_FOR_PROFILE && resultCode == RESULT_OK && data != null && data.getData() != null) {
        try {
           Glide.with(this).load(data.getData()).into(mProfileFragment.mProfileImage);
        } catch (Exception e) {
            Utils.handleException(e);
        }
}


来源:https://stackoverflow.com/questions/47261434/photo-rotated-from-camera-samsung-device

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!