Android: растровые изображения, загруженные из галереи, вращаются в ImageView
когда я загружаю изображение из медиа-галереи в растровое изображение, все работает нормально, за исключением того, что фотографии, которые были сняты с помощью камеры, удерживая телефон вертикально, поворачиваются так, что я всегда получаю горизонтальное изображение, даже если оно кажется вертикальным в галерее. Почему это и как я могу загрузить его правильно?
18 ответов:
Так, в качестве примера...
сначала вам нужно создать ExifInterface:
ExifInterface exif = new ExifInterface(filename);
затем вы можете захватить ориентация изображения:
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
вот что означают значения ориентации: http://sylvana.net/jpegcrop/exif_orientation.html
Итак, наиболее важными значениями являются 3, 6 и 8. Если ориентация равна 6, например, вы можете повернуть изображение следующим образом:
Matrix matrix = new Matrix(); matrix.postRotate(90); rotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
Это просто быстрый пример, хотя. Я уверен, что есть и другие способы выполнения фактического вращения. Но вы также найдете их на StackOverflow.
это полное решение (найдено в Примере Hackbook из Facebook SDK). Он имеет то преимущество, что ему не нужен доступ к самому файлу. Это чрезвычайно полезно, если вы загружаете изображение из устройства разрешения содержимого (например, если ваше приложение отвечает на намерение поделиться фотографией).
public static int getOrientation(Context context, Uri photoUri) { /* it's on the external media. */ Cursor cursor = context.getContentResolver().query(photoUri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor.getCount() != 1) { return -1; } cursor.moveToFirst(); return cursor.getInt(0); }
и затем вы можете получить повернутое растровое изображение следующим образом. Этот код также уменьшает масштаб изображения (к сожалению, плохо) до MAX_IMAGE_DIMENSION. В противном случае вы можете запустить из память.
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(context, photoUri); if (orientation == 90 || orientation == 270) { rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) { float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION); float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION); float maxRatio = Math.max(widthRatio, heightRatio); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { srcBitmap = BitmapFactory.decodeStream(is); } is.close(); /* * if the orientation is not 0 (or -1, which means we don't know), we * have to do a rotation. */ if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } return srcBitmap; }
решил это в моем случае с этим кодом, используя помощь этого поста:
Bitmap myBitmap = getBitmap(imgFile.getAbsolutePath()); try { ExifInterface exif = new ExifInterface(imgFile.getAbsolutePath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); Log.d("EXIF", "Exif: " + orientation); Matrix matrix = new Matrix(); if (orientation == 6) { matrix.postRotate(90); } else if (orientation == 3) { matrix.postRotate(180); } else if (orientation == 8) { matrix.postRotate(270); } myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); // rotating bitmap } catch (Exception e) { } ImageView img = (ImageView) findViewById(R.id.imgTakingPic); img.setImageBitmap(myBitmap);
надеюсь, что это экономит чье-то время!
используйте утилиту, чтобы сделать тяжелый подъем.
9re создана простая утилита для обработки тяжелой работы с данными EXIF и поворота изображений в их правильную ориентацию.
вы можете найти код утилиты здесь:https://gist.github.com/9re/1990019
просто загрузите это, добавьте его в свой проект
это потому, что галерея правильное отображение повернутых изображений, но не ImageView посмотрите сюда:
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(),optionss); ExifInterface exif = new ExifInterface(selectedImagePath); int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); int rotationInDegrees = exifToDegrees(rotation); deg = rotationInDegrees; Matrix matrix = new Matrix(); if (rotation != 0f) { matrix.preRotate(rotationInDegrees); myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); }
и вам нужно это:
private static int exifToDegrees(int exifOrientation) { if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; } return 0; }
получил его на работу, после многих попыток, благодаря посту я больше не могу найти :-(
Exif, кажется, работает всегда, трудность заключалась в том, чтобы получить путь к файлу. Код, который я нашел, отличается между API старше 4.4 и после 4.4. В основном изображение URI для 4.4+ содержит " com.андроид.услуги поставщиков." Для этого типа URI код использует DocumentsContract для получения идентификатора изображения, а затем выполняет запрос с помощью ContentResolver, в то время как для более старого SDK код идет прямо к запросу URI с ContentResolver.
вот код (извините, я не могу кредитовать, кто его разместил):
/** * Handles pre V19 uri's * @param context * @param contentUri * @return */ public static String getPathForPreV19(Context context, Uri contentUri) { String res = null; String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); if(cursor.moveToFirst()){; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); res = cursor.getString(column_index); } cursor.close(); return res; } /** * Handles V19 and up uri's * @param context * @param contentUri * @return path */ @TargetApi(Build.VERSION_CODES.KITKAT) public static String getPathForV19AndUp(Context context, Uri contentUri) { String wholeID = DocumentsContract.getDocumentId(contentUri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; String[] column = { MediaStore.Images.Media.DATA }; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver(). query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null); String filePath = ""; int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } public static String getRealPathFromURI(Context context, Uri contentUri) { String uriString = String.valueOf(contentUri); boolean goForKitKat= uriString.contains("com.android.providers"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && goForKitKat) { Log.i("KIKAT","YES"); return getPathForV19AndUp(context, contentUri); } else { return getPathForPreV19(context, contentUri); } }
вы можете просто прочитать путь с sd-карты и сделать следующее code...it замените существующую фотографию после ее поворота..
нет: Exif не работает на большинстве устройств,он дает неправильные данные, поэтому хорошо жестко кодировать вращение перед сохранением в любой степени, которую вы хотите, вам просто нужно изменить значение угла в postRotate на любое, что вы хотите.
String photopath = tempphoto.getPath().toString(); Bitmap bmp = BitmapFactory.decodeFile(photopath); Matrix matrix = new Matrix(); matrix.postRotate(90); bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); FileOutputStream fOut; try { fOut = new FileOutputStream(tempphoto); bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
я улучшил ответ Тео Инке. Он больше не вращает изображение, если это действительно необходимо. Это также легче читать, и должен работать быстрее.
// Load Image Bitmap bitmap = BitmapFactory.decodeFile(filePath); // Rotate Image if Needed try { // Determine Orientation ExifInterface exif = new ExifInterface(filePath); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); // Determine Rotation int rotation = 0; if (orientation == 6) rotation = 90; else if (orientation == 3) rotation = 180; else if (orientation == 8) rotation = 270; // Rotate Image if Necessary if (rotation != 0) { // Create Matrix Matrix matrix = new Matrix(); matrix.postRotate(rotation); // Rotate Bitmap Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); // Pretend none of this ever happened! bitmap.recycle(); bitmap = rotated; rotated = null; } } catch (Exception e) { // TODO: Log Error Messages Here } // TODO: Use Result Here xxx.setBitmap(bitmap);
первое, что вам нужно, это реальный путь к файлу Если у вас это здорово, если вы используете URI, то используйте этот метод, чтобы получить реальный путь:
public static String getRealPathFromURI(Uri contentURI,Context context) { String path= contentURI.getPath(); try { Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null); cursor.moveToFirst(); String document_id = cursor.getString(0); document_id = document_id.substring(document_id.lastIndexOf(":") + 1); cursor.close(); cursor = context.getContentResolver().query( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null); cursor.moveToFirst(); path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); cursor.close(); } catch(Exception e) { return path; } return path; }
извлеките растровое изображение, например:
try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); } catch (IOException e) { Log.e("IOException",e.toString()); }
вы можете использовать decodeFile() вместо этого, если вы хотите.
теперь, когда у вас есть растровое изображение и реальный путь получить ориентацию изображения:
private static int getExifOrientation(String src) throws IOException { int orientation = 1; ExifInterface exif = new ExifInterface(src); String orientationString=exif.getAttribute(ExifInterface.TAG_ORIENTATION); try { orientation = Integer.parseInt(orientationString); } catch(NumberFormatException e){} return orientation; }
и, наконец, поверните его в нужное положение так:
public static Bitmap rotateBitmap(String src, Bitmap bitmap) { try { int orientation = getExifOrientation(src); if (orientation == 1) { return bitmap; } Matrix matrix = new Matrix(); switch (orientation) { case 2: matrix.setScale(-1, 1); break; case 3: matrix.setRotate(180); break; case 4: matrix.setRotate(180); matrix.postScale(-1, 1); break; case 5: matrix.setRotate(90); matrix.postScale(-1, 1); break; case 6: matrix.setRotate(90); break; case 7: matrix.setRotate(-90); matrix.postScale(-1, 1); break; case 8: matrix.setRotate(-90); break; default: return bitmap; } try { Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); bitmap.recycle(); return oriented; } catch (OutOfMemoryError e) { e.printStackTrace(); return bitmap; } } catch (IOException e) { e.printStackTrace(); } return bitmap; }
вот и все, ты Теперь поверните растровое изображение в нужное положение.
ваше здоровье.
это работает, но, вероятно, не лучший способ сделать это, но это может помочь кому-то.
String imagepath = someUri.getAbsolutePath(); imageview = (ImageView)findViewById(R.id.imageview); imageview.setImageBitmap(setImage(imagepath, 120, 120)); public Bitmap setImage(String path, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; // Get exif orientation try { ExifInterface exif = new ExifInterface(path); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); if (orientation == 6) { orientation_val = 90; } else if (orientation == 3) { orientation_val = 180; } else if (orientation == 8) { orientation_val = 270; } } catch (Exception e) { } try { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust extents int sourceWidth, sourceHeight; if (orientation_val == 90 || orientation_val == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // Rotate the bitmap if required if (orientation_val > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation_val); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { } return bitmap; }
используйте следующий код для правильного поворота изображения:
private Bitmap rotateImage(Bitmap bitmap, String filePath) { Bitmap resultBitmap = bitmap; try { ExifInterface exifInterface = new ExifInterface(filePath); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); Matrix matrix = new Matrix(); if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_90); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_180); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_270); } // Rotate the bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (Exception exception) { Logger.d("Could not rotate the image"); } return resultBitmap; }
может быть, это поможет (поворот на 90 градусов) (это сработало для меня)
private Bitmap rotateBitmap(Bitmap image){ int width=image.getHeight(); int height=image.getWidth(); Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig()); for (int y=width-1;y>=0;y--) for(int x=0;x<height;x++) srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y)); return srcBitmap; }
курсор должен быть закрыт после его открытия.
вот пример.
public static int getOrientation(Context context, Uri selectedImage) { int orientation = -1; Cursor cursor = context.getContentResolver().query(selectedImage, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor.getCount() != 1) return orientation; cursor.moveToFirst(); orientation = cursor.getInt(0); cursor.close(); // ADD THIS LINE return orientation; }
улучшение решения выше по Timmmm, чтобы добавить дополнительное масштабирование в конце, чтобы гарантировать, что изображение вписывается в рамки:
public static Bitmap loadBitmap(String path, int orientation, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; try { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust extents int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // Rotate the bitmap if required if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { } return bitmap; }
методы ниже масштабирует и поворачивает растровое изображение в соответствии с ориентацией:
public Bitmap scaleAndRotateImage(String path, int orientation, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; try { // Check the dimensions of the Image final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust the Width and Height int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // We need to rotate the bitmap (if required) int orientationInDegrees = exifToDegrees(orientation); if (orientation > 0) { Matrix matrix = new Matrix(); if (orientation != 0f) { matrix.preRotate(orientationInDegrees); }; bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { Logger.d("Could not rotate the image"); Logger.d(e.getMessage()); } return bitmap; }
пример:
public void getPictureFromDevice(Uri Uri,ImageView imageView) { try { ExifInterface exifInterface = new ExifInterface(Uri.getPath()); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Bitmap bitmap = scaleAndRotateImage(Uri.getPath(), orientation, imageView.getWidth(), imageView.getHeight()); imageView.setImageBitmap(bitmap); } catch (OutOfMemoryError outOfMemoryError) { Logger.d(outOfMemoryError.getLocalizedMessage()); Logger.d("Failed to load image from filePath (out of memory)"); Logger.d(Uri.toString()); } catch (Exception e) { Logger.d("Failed to load image from filePath"); Logger.d(Uri.toString()); } }
Я расплавил @Timmmm ответ и @Manuel. Если вы сделаете это решение,вы не получите исключение Run Out of Memory.
этот метод извлекает ориентацию изображения:
private static final int ROTATION_DEGREES = 90; // This means 512 px private static final Integer MAX_IMAGE_DIMENSION = 512; public static int getOrientation(Uri photoUri) throws IOException { ExifInterface exif = new ExifInterface(photoUri.getPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: orientation = ROTATION_DEGREES; break; case ExifInterface.ORIENTATION_ROTATE_180: orientation = ROTATION_DEGREES * 2; break; case ExifInterface.ORIENTATION_ROTATE_270: orientation = ROTATION_DEGREES * 3; break; default: // Default case, image is not rotated orientation = 0; } return orientation; }
поэтому вы должны использовать этот метод для изменения размера изображения перед загрузкой его в память. Таким образом, вы не получите исключение памяти.
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(photoUri); if (orientation == 90 || orientation == 270) { rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) { float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION); float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION); float maxRatio = Math.max(widthRatio, heightRatio); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { srcBitmap = BitmapFactory.decodeStream(is); } is.close(); // if the orientation is not 0, we have to do a rotation. if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } return srcBitmap; }
это прекрасно работает для меня. Я надеюсь, что это поможет кому-то еще
Я решил проблему со следующим обходным путем. Обратите внимание, что я также масштабирую изображение, которое было необходимо, чтобы избежать OutOfMemoryExceptions.
остерегайтесь, что это решение не будет работать должным образом с портретными изображениями или opside-down изображений (спасибо Timmmm за замечание). Решение Timmmm выше может быть лучшим выбором, если это требуется, и оно выглядит более элегантным:https://stackoverflow.com/a/8914291/449918
File path = // ... location of your bitmap file int w = 512; int h = 384; // size that does not lead to OutOfMemoryException on Nexus One Bitmap b = BitmapFactory.decodeFile(path); // Hack to determine whether the image is rotated boolean rotated = b.getWidth() > b.getHeight(); Bitmap resultBmp = null; // If not rotated, just scale it if (!rotated) { resultBmp = Bitmap.createScaledBitmap(b, w, h, true); b.recycle(); b = null; // If rotated, scale it by switching width and height and then rotated it } else { Bitmap scaledBmp = Bitmap.createScaledBitmap(b, h, w, true); b.recycle(); b = null; Matrix mat = new Matrix(); mat.postRotate(90); resultBmp = Bitmap.createBitmap(scaledBmp, 0, 0, h, w, mat, true); // Release image resources scaledBmp.recycle(); scaledBmp = null; } // resultBmp now contains the scaled and rotated image
Ура