Saat saya memuat gambar dari galeri media ke dalam Bitmap, semuanya berfungsi dengan baik, kecuali gambar yang diambil dengan kamera sambil memegang telepon secara vertikal, diputar sehingga saya selalu mendapatkan gambar horizontal meskipun tampak vertikal di galeri. Mengapa demikian dan bagaimana cara memuatnya dengan benar?
138
Jawaban:
Sudahkah Anda melihat data EXIF dari gambar? Mungkin mengetahui orientasi kamera saat gambar diambil.
sumber
Jadi, sebagai contoh ...
Pertama, Anda perlu membuat ExifInterface:
ExifInterface exif = new ExifInterface(filename);
Anda kemudian dapat mengambil orientasi gambar:
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Inilah arti dari nilai orientasi: http://sylvana.net/jpegcrop/exif_orientation.html
Jadi, nilai yang paling penting adalah 3, 6 dan 8. Jika orientasinya
ExifInterface.ORIENTATION_ROTATE_90
(yaitu 6), misalnya, Anda dapat memutar gambar seperti ini:Matrix matrix = new Matrix(); matrix.postRotate(90); rotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
Itu hanya contoh singkat. Saya yakin ada cara lain untuk melakukan rotasi sebenarnya. Tetapi Anda juga akan menemukannya di StackOverflow.
sumber
OutOfMemoryError
saat menggunakan pendekatan ini saat Anda menyimpan dua bitmap dalam memori pada saat yang bersamaan.Ini adalah solusi lengkap (ditemukan dalam contoh Hackbook dari Facebook SDK). Ini memiliki keuntungan karena tidak membutuhkan akses ke file itu sendiri. Ini sangat berguna jika Anda memuat gambar dari pemecah konten (misalnya jika aplikasi Anda merespons maksud berbagi foto).
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); }
Dan kemudian Anda bisa mendapatkan Bitmap yang dirotasi sebagai berikut. Kode ini juga menurunkan ukuran gambar (sayangnya) menjadi MAX_IMAGE_DIMENSION. Jika tidak, Anda mungkin kehabisan memori.
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; }
sumber
ExifInterface exif = new ExifInterface(photoUri.getPath());
dan kemudianexif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1)
mendapatkan orientasi (misalnyaORIENTATION_ROTATE_90
,ORIENTATION_ROTATE_180
)Selesaikan dalam kasus saya dengan kode ini menggunakan bantuan posting ini:
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);
Semoga dapat menghemat waktu seseorang!
sumber
Gunakan Utilitas untuk melakukan Pengangkatan Berat.
9re membuat utilitas sederhana untuk menangani pekerjaan berat menangani data EXIF dan memutar gambar ke orientasi yang benar.
Anda dapat menemukan kode utilitas di sini: https://gist.github.com/9re/1990019
Cukup unduh ini, tambahkan ke
src
direktori proyek Anda dan gunakanExifUtil.rotateBitmap()
untuk mendapatkan orientasi yang benar, seperti:String imagePath = photoFile.getAbsolutePath(); // photoFile is a File class. Bitmap myBitmap = BitmapFactory.decodeFile(imagePath); Bitmap orientedBitmap = ExifUtil.rotateBitmap(imagePath, myBitmap);
sumber
Itu karena galeri benar menampilkan gambar yang diputar tetapi tidak tampilan ImageView di sini:
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); }
dan Anda membutuhkan ini:
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; }
sumber
Berhasil setelah banyak upaya berkat pos yang tidak dapat saya temukan lagi :-(
Exif tampaknya selalu berfungsi, kesulitannya adalah mendapatkan jalur file. Kode yang saya temukan membuat perbedaan antara API yang lebih lama dari 4.4 dan setelah 4.4. Pada dasarnya gambar URI untuk 4.4+ berisi "com.android.providers". Untuk jenis URI ini, kode tersebut menggunakan DocumentsContract untuk mendapatkan id gambar dan kemudian menjalankan kueri menggunakan ContentResolver, sedangkan untuk SDK yang lebih lama, kode tersebut langsung meminta URI dengan ContentResolver.
Ini kodenya (maaf saya tidak bisa memberi kredit siapa yang mempostingnya):
/** * 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); } }
sumber
Anda tinggal membaca jalur dari kartu sd dan melakukan kode berikut ... itu akan Mengganti foto yang ada setelah memutarnya ..
Catatan: Exif tidak berfungsi pada sebagian besar perangkat, ini memberikan data yang salah sehingga sebaiknya kode keras berputar sebelum menyimpan ke tingkat apa pun yang Anda inginkan, Anda hanya perlu mengubah nilai sudut di postRotate ke nilai yang Anda inginkan.
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(); } }
sumber
Kode Kotlin:
if (file.exists()){ val bitmap = BitmapFactory.decodeFile(file.absolutePath) val exif = ExifInterface(file.absoluteFile.toString()) val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) val matrix = Matrix() when(orientation){ ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90F) ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180F) ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270F) } val rotatedBitmap = Bitmap.createBitmap(bitmap, 0,0 , bitmap.width, bitmap.height, matrix, true) bitmap.recycle() iv_capture.setImageBitmap(rotatedBitmap) }
sumber
Saya memperbaiki jawaban dari Teo Inke. Itu tidak lagi memutar gambar kecuali itu benar-benar diperlukan. Ini juga lebih mudah dibaca, dan seharusnya berjalan lebih cepat.
// 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);
sumber
Hal pertama yang Anda butuhkan adalah jalur File yang sebenarnya. Jika Anda memilikinya, jika Anda menggunakan URI, gunakan metode ini untuk mendapatkan Path yang sebenarnya:
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; }
ekstrak Bitmap Anda misalnya:
try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); } catch (IOException e) { Log.e("IOException",e.toString()); }
Anda dapat menggunakan decodeFile () sebagai gantinya jika Anda mau.
Sekarang setelah Anda memiliki Bitmap dan Path yang sebenarnya, dapatkan Orientation of the Image:
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; }
dan terakhir putar ke posisi yang benar seperti ini:
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; }
Itu saja, Anda sekarang memiliki bitmap yang diputar ke posisi yang benar.
Bersulang.
sumber
Ini berhasil, tetapi mungkin bukan cara terbaik untuk melakukannya, tetapi mungkin membantu seseorang.
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; }
sumber
mungkin ini akan membantu (putar 90 derajat) (ini berhasil untuk saya)
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; }
sumber
Metode di bawah menskalakan DAN memutar bitmap sesuai dengan orientasi:
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; }
Contoh:
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()); } }
sumber
Kursor harus ditutup setelah membukanya.
Berikut ini contohnya.
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; }
sumber
Saya telah mencairkan jawaban @Timmmm dan @Manuel. Jika Anda melakukan solusi ini, Anda tidak akan mendapatkan Pengecualian Kehabisan Memori.
Metode ini mengambil orientasi gambar:
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; }
Oleh karena itu, Anda akan menggunakan metode ini untuk mengubah ukuran gambar sebelum memuatnya ke memori. Dengan demikian, Anda tidak akan mendapatkan Pengecualian Memori.
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; }
Ini bekerja dengan sempurna untuk saya. Saya harap ini membantu orang lain
sumber
Memperbaiki solusi di atas oleh Timmmm untuk menambahkan beberapa penskalaan ekstra di bagian akhir untuk memastikan bahwa gambar sesuai dengan batasan:
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; }
sumber
Gunakan kode berikut untuk memutar gambar dengan benar:
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; }
sumber
Saya memecahkan masalah dengan solusi berikut. Perhatikan bahwa saya juga menskalakan gambar, yang diperlukan untuk menghindari OutOfMemoryExceptions.
Berhati-hatilah karena solusi ini tidak akan berfungsi dengan baik dengan gambar potret atau gambar terbalik (terima kasih Timmmm untuk catatannya). Solusi Timmmm di atas mungkin menjadi pilihan yang lebih baik jika diperlukan dan terlihat lebih elegan juga: 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
Bersulang
sumber