захваченное изображение вращается в некоторых устройствах [дубликат]

Если вы не возражаете против использования сторонних библиотек, AOL cyclops-react lib, раскрытие :: Я являюсь автором, имеет класс ExceptionSoftener , который может помочь здесь .

 s.filter(softenPredicate(a->a.isActive()));

263
задан Peter Mortensen 10 December 2016 в 11:56
поделиться

17 ответов

Большинство телефонных камер - это пейзаж, а это означает, что если вы сделаете фотографию на портрете, полученные снимки будут повернуты на 90 градусов. В этом случае программное обеспечение камеры должно заполнить данные Exif с ориентацией, в которой должна просматриваться фотография.

Обратите внимание, что решение ниже зависит от производителя программного обеспечения камеры / устройства заполняя данные Exif, поэтому он будет работать в большинстве случаев, но он не является 100% -ным надежным решением.

ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                     ExifInterface.ORIENTATION_UNDEFINED);

Bitmap rotatedBitmap = null;
switch(orientation) {

    case ExifInterface.ORIENTATION_ROTATE_90:
        rotatedBitmap = rotateImage(bitmap, 90);
        break;

    case ExifInterface.ORIENTATION_ROTATE_180:
        rotatedBitmap = rotateImage(bitmap, 180);
        break;

    case ExifInterface.ORIENTATION_ROTATE_270:
        rotatedBitmap = rotateImage(bitmap, 270);
        break;

    case ExifInterface.ORIENTATION_NORMAL:
    default:
        rotatedBitmap = bitmap;
}

Вот метод rotateImage:

public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
                               matrix, true);
}
322
ответ дан Jason Robinson 18 August 2018 в 18:42
поделиться
  • 1
    Из кода @JasonRobinson я узнаю, как получить фактическую ориентацию и объединив с этот код , я успешно управляю ориентацией. – Raditya Kurnianto 21 September 2014 в 05:31
  • 2
    Вторая опция exif.getAttributeInt с использованием ExifInterface.ORIENTATION_UNDEFINED почти такая же, как и второй параметр по умолчанию, если функция не может обеспечить значение. – Darpan 4 September 2015 в 10:32
  • 3
    Этот код предназначен для изображения, уже записанного на диск, не так ли? Я не получаю результатов, используя этот метод для растрового изображения, который должен быть записан на диск. – Thracian 3 April 2017 в 13:07
  • 4
    @FatihOzcan выглядит как ExitInterface поддерживает File и InputStream, поэтому вы можете создать InputStream . – Jason Robinson 3 April 2017 в 17:54
  • 5
    @Jason Robinson, этот код очень полезен для получения изображения с диска и вращения его соответственно, но когда вы делаете сложную работу, как и я, я получаю изображение 4k с камеры и объединяю его с холст-рисунком после масштабирования чертежа с предварительного просмотра камеры до 4k , и сохраните его на диск. Открытие потока снова неэффективно, вращая растровое изображение с методом postRotate () matix перед сохранением изображения, достаточного для меня. В моем случае пользователь должен выбрать поворот вручную – Thracian 3 April 2017 в 18:56

Я потратил много времени на поиск решения для этого. И, наконец, удалось это сделать. Не забывайте повышать голос @ Джейсона Робинсона, потому что мой основанный на его.

Итак, сначала вы знаете, что с Android 7.0 мы должны использовать FileProvider и что-то, называемое ContentUri, иначе вы получите раздражающую ошибку, пытающуюся вызвать ваш Intent. Это пример кода:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getUriFromPath(context, "[Your path to save image]"));
startActivityForResult(intent, CAPTURE_IMAGE_RESULT);

Метод getUriFromPath(Context, String) в пользовательской версии Android создает FileUri (file://...) или ContentUri (content://...), и там это:

public Uri getUriFromPath(Context context, String destination) {
    File file =  new File(destination);

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        return FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
    } else {
        return Uri.fromFile(file);
    }
}

После onActivityResult вы можете поймать это uri, где изображение сохраняется камерой, но теперь вам нужно определить поворот камеры, здесь мы будем использовать moddified @Jason Robinson answer:

Сначала нам нужно создать ExifInterface на основе Uri

@Nullable
public ExifInterface getExifInterface(Context context, Uri uri) {
    try {
        String path = uri.toString();
        if (path.startsWith("file://")) {
            return new ExifInterface(path);
        }
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (path.startsWith("content://")) {
                InputStream inputStream = context.getContentResolver().openInputStream(uri);
                return new ExifInterface(inputStream);
            }
        }
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Выше код можно упростить, но я хочу показать все. Поэтому из FileUri мы можем создать ExifInterface на основе String path, но из ContentUri мы не можем, Android не поддерживает это.

В этом случае мы должны использовать другой конструктор на основе InputStream. Помните, что этот конструктор недоступен по умолчанию, вам нужно добавить дополнительную библиотеку:

compile "com.android.support:exifinterface:XX.X.X"

Теперь мы можем использовать метод getExifInterface для получения нашего угла:

public float getExifAngle(Context context, Uri uri) {
    try {
        ExifInterface exifInterface = getExifInterface(context, uri);
        if(exifInterface == null) {
            return -1f;
        }

        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_UNDEFINED);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                return 90f;
            case ExifInterface.ORIENTATION_ROTATE_180:
                return 180f;
            case ExifInterface.ORIENTATION_ROTATE_270:
                return 270f;
            case ExifInterface.ORIENTATION_NORMAL:
                return 0f;
            case ExifInterface.ORIENTATION_UNDEFINED:
                return -1f;
            default:
                return -1f;
        }
    }
    catch (Exception e) {
        e.printStackTrace();
        return -1f;
    }
}

Теперь у вас есть Угол для правильного поворота изображения:).

4
ответ дан Artur Szymański 18 August 2018 в 18:42
поделиться

Это, возможно, само собой разумеется, но всегда помните, что вы можете обрабатывать некоторые из этих проблем с обработкой изображений на своем сервере. Я использовал ответы, подобные тем, которые содержатся в этом потоке, чтобы обрабатывать немедленное отображение изображения. Однако мое приложение требует, чтобы изображения хранились на сервере (это, вероятно, является общим требованием, если вы хотите, чтобы изображение сохранялось, когда пользователи переключают телефоны).

Решения, содержащиеся во многих потоках, относящихся к этой теме, Обсудите отсутствие настойчивости данных EXIF, которые не выдержат сжатия изображения Bitmap, а это означает, что вам нужно будет поворачивать изображение каждый раз, когда ваш сервер загружает его. В качестве альтернативы вы можете отправить данные ориентации EXIF ​​на свой сервер, а затем, если необходимо, повернуть изображение.

Мне было проще создать постоянное решение на сервере, потому что мне не пришлось беспокоиться о секретных файлах файлов Android.

1
ответ дан Braden Holt 18 August 2018 в 18:42
поделиться
  • 1
    Можете ли вы повернуть его один раз во время захвата изображения и сохранить его таким образом, чтобы его больше не нужно было поворачивать? – jk7 6 September 2017 в 17:30
  • 2
    Да, вы можете, и это на самом деле процесс, который я в конечном итоге воплотил в жизнь. Мне не удалось получить путь к файлу с изображения на телефоне Android, который позволил бы мне это сделать. Это ответ, который помог: stackoverflow.com/a/36714242/5443056 – Braden Holt 6 September 2017 в 21:55

Обычно рекомендуется решить проблему с помощью ExifInterface , как это делал Джейсон Робинсон. Если этот подход не работает, вы можете попытаться найти Ориентацию последнего снятого изображения ...

private int getImageOrientation(){
    final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION };
    final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
    Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            imageColumns, null, null, imageOrderBy);

    if(cursor.moveToFirst()){
        int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
        cursor.close();
        return orientation;
    } else {
        return 0;
    }
}
4
ответ дан Chris Conway 18 August 2018 в 18:42
поделиться
  • 1
    Я думаю, что этот код только определяет, в какой степени произошел поворот. Теперь я могу это сделать, но не могу в следующей задаче, то есть повернуть изображение. – S H 3 January 2013 в 12:31
  • 2
    Вы правы, но вы не просили поворота в этой теме, поэтому давайте держать его в чистоте;) Вот почему я поставил свой ответ на вашу вращающуюся проблему в вашу другую тему ... Надеюсь, что это помогает, это работает me: stackoverflow.com/questions/14123809/… – Chris Conway 3 January 2013 в 13:36

В выбранном ответе используется наиболее распространенный метод ответа на этот и подобные вопросы. Однако он не работает с передней и задней камерами Samsung. Для тех, кто ищет решение, которое работает как на передней, так и на задней камерах для Samsung и других крупных производителей, этот ответ nvhausid является удивительным:

https://stackoverflow.com/a/18915443/ 6080472

Для тех, кто не хочет щелкнуть, соответствующее волшебство - использовать CameraInfo, а не полагаться на EXIF.

Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
Bitmap bitmap = rotate(realImage, info.orientation);

Полный код в ссылке.

2
ответ дан Community 18 August 2018 в 18:42
поделиться
  • 1
    нет, неправильное вращение под разными углами (samsung s7). Я имею в виду галерею, конечно – djdance 1 December 2016 в 21:39
  • 2
    Этот комментарий мне нужен. Чувак, большое спасибо. – Joel Nieman 4 May 2017 в 22:19
// Try this way,hope this will help you to solve your problem...

activity_main.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center">
        <ImageView
            android:id="@+id/imgFromCameraOrGallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:src="@drawable/ic_launcher"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btnCamera"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="Camera"/>
        <Button
            android:id="@+id/btnGallery"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_marginLeft="5dp"
            android:layout_height="wrap_content"
            android:text="Gallery"/>

    </LinearLayout>
</LinearLayout>

MainActivity.java

    public class MainActivity extends Activity {

    private ImageView imgFromCameraOrGallery;
    private Button btnCamera;
    private Button btnGallery;

    private String imgPath;
    final private int PICK_IMAGE = 1;
    final private int CAPTURE_IMAGE = 2;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imgFromCameraOrGallery = (ImageView) findViewById(R.id.imgFromCameraOrGallery);
        btnCamera = (Button) findViewById(R.id.btnCamera);
        btnGallery = (Button) findViewById(R.id.btnGallery);

        btnCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
                startActivityForResult(intent, CAPTURE_IMAGE);
            }
        });

        btnGallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == CAPTURE_IMAGE) {
                setCapturedImage(getImagePath());
            } else if (requestCode == PICK_IMAGE) {
                imgFromCameraOrGallery.setImageBitmap(BitmapFactory.decodeFile(getAbsolutePath(data.getData())));
            }
        }

    }

    private String getRightAngleImage(String photoPath) {

        try {
            ExifInterface ei = new ExifInterface(photoPath);
            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            int degree = 0;

            switch (orientation) {
                case ExifInterface.ORIENTATION_NORMAL:
                    degree = 0;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
                case ExifInterface.ORIENTATION_UNDEFINED:
                    degree = 0;
                    break;
                default:
                    degree = 90;
            }

            return rotateImage(degree,photoPath);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return photoPath;
    }

    private String rotateImage(int degree, String imagePath){

        if(degree<=0){
            return imagePath;
        }
        try{
            Bitmap b= BitmapFactory.decodeFile(imagePath);

            Matrix matrix = new Matrix();
            if(b.getWidth()>b.getHeight()){
                matrix.setRotate(degree);
                b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(),
                        matrix, true);
            }

            FileOutputStream fOut = new FileOutputStream(imagePath);
            String imageName = imagePath.substring(imagePath.lastIndexOf("/") + 1);
            String imageType = imageName.substring(imageName.lastIndexOf(".") + 1);

            FileOutputStream out = new FileOutputStream(imagePath);
            if (imageType.equalsIgnoreCase("png")) {
                b.compress(Bitmap.CompressFormat.PNG, 100, out);
            }else if (imageType.equalsIgnoreCase("jpeg")|| imageType.equalsIgnoreCase("jpg")) {
                b.compress(Bitmap.CompressFormat.JPEG, 100, out);
            }
            fOut.flush();
            fOut.close();

            b.recycle();
        }catch (Exception e){
            e.printStackTrace();
        }
        return imagePath;
    }

    private void setCapturedImage(final String imagePath){
        new AsyncTask<Void,Void,String>(){
            @Override
            protected String doInBackground(Void... params) {
                try {
                    return getRightAngleImage(imagePath);
                }catch (Throwable e){
                    e.printStackTrace();
                }
                return imagePath;
            }

            @Override
            protected void onPostExecute(String imagePath) {
                super.onPostExecute(imagePath);
                imgFromCameraOrGallery.setImageBitmap(decodeFile(imagePath));
            }
        }.execute();
    }

    public Bitmap decodeFile(String path) {
        try {
            // Decode deal_image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, o);
            // The new size we want to scale to
            final int REQUIRED_SIZE = 1024;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;
            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeFile(path, o2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getAbsolutePath(Uri uri) {
        if(Build.VERSION.SDK_INT >= 19){
            String id = "";
            if(uri.getLastPathSegment().split(":").length > 1)
                id = uri.getLastPathSegment().split(":")[1];
            else if(uri.getLastPathSegment().split(":").length > 0)
                id = uri.getLastPathSegment().split(":")[0];
            if(id.length() > 0){
                final String[] imageColumns = {MediaStore.Images.Media.DATA };
                final String imageOrderBy = null;
                Uri tempUri = getUri();
                Cursor imageCursor = getContentResolver().query(tempUri, imageColumns, MediaStore.Images.Media._ID + "=" + id, null, imageOrderBy);
                if (imageCursor.moveToFirst()) {
                    return imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                }else{
                    return null;
                }
            }else{
                return null;
            }
        }else{
            String[] projection = { MediaStore.MediaColumns.DATA };
            Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } else
                return null;
        }

    }

    private Uri getUri() {
        String state = Environment.getExternalStorageState();
        if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED))
            return MediaStore.Images.Media.INTERNAL_CONTENT_URI;

        return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    }

    public Uri setImageUri() {
        Uri imgUri;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/",getString(R.string.app_name) + Calendar.getInstance().getTimeInMillis() + ".png");
            imgUri = Uri.fromFile(file);
            imgPath = file.getAbsolutePath();
        }else {
            File file = new File(getFilesDir() ,getString(R.string.app_name) + Calendar.getInstance().getTimeInMillis()+ ".png");
            imgUri = Uri.fromFile(file);
            this.imgPath = file.getAbsolutePath();
        }
        return imgUri;
    }

    public String getImagePath() {
        return imgPath;
    }
}
10
ответ дан Haresh Chhelana 18 August 2018 в 18:42
поделиться

Существует более простая команда для исправления этой ошибки.

Просто добавьте после yourImageView.setBitmap (bitmap); this yourImageView.setRotation (90);

Эта неподвижная шахта. Надеюсь, это поможет!

1
ответ дан Jenrielle G. 18 August 2018 в 18:42
поделиться
  • 1
    Как заявлял ОП, некоторые устройства не поворачивают изображение, некоторые поворачивают его на 90 градусов, около 180, ..с. Поэтому всегда вращение в 90 было бы некорректным в некоторых случаях. – jk7 6 September 2017 в 17:33

Самое простое решение для этой проблемы:

captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,
                   characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));

Я сохраняю изображение в формате jpg.

0
ответ дан Pang 18 August 2018 в 18:42
поделиться

Объединив Jason Robinson ответ с Felix 's ответ и заполнив недостающие части, здесь это окончательное решение для этой проблемы, которое будет выполнено после тестирования на Android Android & nbsp; 4.1 ( Jelly Bean ), Android 4.4 ( KitKat ) и Android 5.0 ( Lollipop ).

Шаги

  1. Уменьшить масштаб изображение, если оно больше 1024x1024.
  2. Вращайте изображение только вправо только , если оно вращается на 90, 180 или 270 градусов.
  3. Переработка повернутое изображение для целей памяти.

Вот часть кода:

Вызовите следующий метод с текущим Context и изображением URI, которое вы хотите исправить

/**
 * This method is responsible for solving the rotation issue if exist. Also scale the images to
 * 1024x1024 resolution
 *
 * @param context       The current context
 * @param selectedImage The Image URI
 * @return Bitmap image results
 * @throws IOException
 */
public static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
        throws IOException {
    int MAX_HEIGHT = 1024;
    int MAX_WIDTH = 1024;

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
    BitmapFactory.decodeStream(imageStream, null, options);
    imageStream.close();

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    imageStream = context.getContentResolver().openInputStream(selectedImage);
    Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

    img = rotateImageIfRequired(context, img, selectedImage);
    return img;
}

Вот метод CalculateInSampleSize из предварительно упомянутого источника :

/**
  * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
  * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
  * the closest inSampleSize that will result in the final decoded bitmap having a width and
  * height equal to or larger than the requested width and height. This implementation does not
  * ensure a power of 2 is returned for inSampleSize which can be faster when decoding but
  * results in a larger bitmap which isn't as useful for caching purposes.
  *
  * @param options   An options object with out* params already populated (run through a decode*
  *                  method with inJustDecodeBounds==true
  * @param reqWidth  The requested width of the resulting bitmap
  * @param reqHeight The requested height of the resulting bitmap
  * @return The value to be used for inSampleSize
  */
private static int calculateInSampleSize(BitmapFactory.Options options,
                                         int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
        // with both dimensions larger than or equal to the requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

        // This offers some additional logic in case the image has a strange
        // aspect ratio. For example, a panorama may have a much larger
        // width than height. In these cases the total pixels might still
        // end up being too large to fit comfortably in memory, so we should
        // be more aggressive with sample down the image (=larger inSampleSize).

        final float totalPixels = width * height;

        // Anything more than 2x the requested pixels we'll sample down further
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }
    }
    return inSampleSize;
}

Затем идет метод, который будет проверять текущая ориентация изображения для определения угла поворота

 /**
 * Rotate an image if required.
 *
 * @param img           The image bitmap
 * @param selectedImage Image URI
 * @return The resulted Bitmap after manipulation
 */
private static Bitmap rotateImageIfRequired(Context context, Bitmap img, Uri selectedImage) throws IOException {

InputStream input = context.getContentResolver().openInputStream(selectedImage);
ExifInterface ei;
if (Build.VERSION.SDK_INT > 23)
    ei = new ExifInterface(input);
else
    ei = new ExifInterface(selectedImage.getPath());

    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotateImage(img, 90);
        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotateImage(img, 180);
        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotateImage(img, 270);
        default:
            return img;
    }
}

Наконец, метка вращения (/ g23)

private static Bitmap rotateImage(Bitmap img, int degree) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
    img.recycle();
    return rotatedImg;
}

-Не забудьте проголосовать за ответы этих парней за свои усилия и Shirish Herwade , которые задали этот полезный вопрос.

114
ответ дан Pei 18 August 2018 в 18:42
поделиться

Попробуйте следующее, если у вас возникла проблема с S4.

android:configChanges="locale|touchscreen|orientation|screenLayout|screenSize|keyboardHidden|uiMode"
34
ответ дан Peter Mortensen 18 August 2018 в 18:42
поделиться
  • 1
    извините, не работает. Фактически на вкладке, каждый раз после завершения выполнения onActivityResult, странно onCreate вызывается. – S H 28 December 2012 в 14:00
  • 2
    извините, проблема в том, что она – S H 2 January 2013 в 15:40
  • 3
    Что такое метод calculateInSampleSize здесь – madhu kotagiri 14 July 2014 в 07:54
  • 4
    @madhukotagiri здесь у вас есть пример реализации для расчетаInSampleSize: gist.github.com/anonymous/b7ea25fc2bbc54e43616 – Felix 14 July 2014 в 16:43
  • 5
    Спасибо, человек, ты определенно один! Мне просто интересно, насколько будет изменяться размер, если операция выполняется только изредка. – marino 13 August 2014 в 23:46
  • 6
    Параметр Uri selectedImage не используется в методе getRotation (...). Как нам его использовать? Спасибо. – anivaler 6 February 2015 в 16:22
  • 7
    rotateImageIfRequired(img, selectedImage); вы передаете два параметра, тогда как в определении вашего метода вы определили три private static Bitmap rotateImageIfRequired(Context context,Bitmap img, Uri selectedImage), что я передаю в качестве контекста из своей активности? – Romantic Electron 23 April 2015 в 05:42
  • 8
    при фотосъемке приложение предназначено для камеры. вы не можете управлять камерой, добавив тег в манифест. – milad zahedi 27 November 2016 в 13:04
  • 9
    Благодарю. это решает мою проблему – ayesh don 1 June 2017 в 09:31
  • 10
    Этот работал для меня. Спасибо! – Zack Kaytranada 5 March 2018 в 11:27

К сожалению, ответ jason-robinson выше не работал для меня.

Хотя функция вращения работает отлично:

public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix,
            true);
}

Мне нужно было сделать следующее, чтобы получить ориентацию, поскольку ориентация Exif всегда была 0

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode,resultCode,data);
    if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null) {
            Uri selectedImage = data.getData();
            String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
            Cursor cur = managedQuery(imageUri, orientationColumn, null, null, null);
            int orientation = -1;
            if (cur != null && cur.moveToFirst()) {
                    orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
            }
            InputStream imageStream = getContentResolver().openInputStream(selectedImage);
            Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
            switch(orientation) {
                    case 90:
                            bitmap = rotateImage(chosen_image_bitmap, 90);
                            break;
                    case 180:
                            bitmap = rotateImage(chosen_image_bitmap, 180);
                            break;
                    case 270:
                            bitmap = rotateImage(chosen_image_bitmap, 270);
                            break;
                    default:
                            break;
            }
            imageView.setImageBitmap(bitmap );
3
ответ дан rharvey 18 August 2018 в 18:42
поделиться

Ответ Джейсона Робинсона и Сами Эльтамави ответ превосходны.

Просто улучшение для завершения aproach, вы должны использовать совместимость ExifInterface.

com.android.support:exifinterface:${lastLibVersion}

Вы сможете создать экземпляр ExifInterface (pior API & lt; 24) с помощью InputStream (из ContentResolver) вместо путей uri, избегая «Исключенные файлы исключений» "

https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html

1
ответ дан Ricard 18 August 2018 в 18:42
поделиться

Однолинейное решение:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

Или

Picasso.with(context).load("file:" + photoPath).into(imageView);

Это автоматически определит вращение и поместит изображение в правильной ориентации

Picasso - очень мощный библиотека для обработки изображений в вашем приложении включает в себя: сложные преобразования изображений с минимальным использованием памяти.

15
ответ дан voytez 18 August 2018 в 18:42
поделиться
  • 1
    Интересное решение – Bhavik Mehta 16 May 2016 в 15:20
  • 2
    Он просто загружает изображение в представление, он не дает вам растрового изображения или файла, который вы можете манипулировать или загружать на сервер. – Mickaël A. 12 July 2016 в 11:54
  • 3
    Его отображаемое изображение щелкнуло так, как есть. Он не вращается по мере необходимости. – seema 24 February 2017 в 09:24
  • 4
    @Flawyte вы можете сделать это, загрузив файл в цель вместо представления с обратным вызовом, который возвращает обрезанное / измененное растровое изображение: Picasso.with (this) .load (cropUriToLoad.resize (1080, 810) .centerInside (). В (target); где target = new Target () {Override public void onBitmapLoaded (растровое изображение растрового изображения, Picasso.LoadedFrom from) { – voytez 9 August 2017 в 21:30
2
ответ дан Community 7 September 2018 в 03:01
поделиться
35
ответ дан Peter Mortensen 7 September 2018 в 03:01
поделиться
2
ответ дан Community 30 October 2018 в 07:11
поделиться
35
ответ дан Peter Mortensen 30 October 2018 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: