미디어 갤러리의 이미지를 비트 맵에로드하면 휴대폰을 세로로 잡고 카메라로 촬영 한 사진이 회전되어 세로로 표시 되더라도 항상 가로 사진을 볼 수 있다는 점을 제외하면 모든 것이 제대로 작동합니다. 갤러리. 그 이유는 무엇이며 올바르게로드하려면 어떻게해야합니까?
답변
이미지의 EXIF 데이터를 보셨습니까? 사진을 촬영할 때 카메라의 방향을 알 수 있습니다.
답변
예를 들어 …
먼저 ExifInterface를 만들어야합니다.
ExifInterface exif = new ExifInterface(filename);
그런 다음 이미지의 방향을 잡을 수 있습니다.
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
방향 값의 의미는 다음과 같습니다.
http://sylvana.net/jpegcrop/exif_orientation.html
따라서 가장 중요한 값은 3, 6 및 8 ExifInterface.ORIENTATION_ROTATE_90
입니다. 예를 들어 방향 이 6 인 경우 이미지를 다음과 같이 회전 할 수 있습니다.
Matrix matrix = new Matrix();
matrix.postRotate(90);
rotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
그래도 간단한 예일뿐입니다. 실제 회전을 수행하는 다른 방법이 있다고 확신합니다. 그러나 StackOverflow에서도 찾을 수 있습니다.
답변
이것은 완전한 솔루션입니다 (Facebook SDK의 Hackbook 예제에 있음). 파일 자체에 액세스 할 필요가 없다는 이점이 있습니다. 콘텐츠 리졸버에서 이미지를로드 할 때 (예 : 앱이 공유 사진 의도에 응답하는 경우) 매우 유용합니다.
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);
누군가의 시간을 절약하기를 바랍니다!
답변
유틸리티를 사용하여 헤비 리프팅을 수행하십시오.
9 는 EXIF 데이터를 처리하고 이미지를 올바른 방향으로 회전시키는 힘든 작업을 처리하는 간단한 유틸리티를 만들었습니다.
유틸리티 코드는 https://gist.github.com/9re/1990019 에서 찾을 수 있습니다.
간단히 이것을 다운로드하여 프로젝트 src
디렉토리에 추가 ExifUtil.rotateBitmap()
하고 올바른 방향을 얻는 데 사용하십시오.
String imagePath = photoFile.getAbsolutePath(); // photoFile is a File class.
Bitmap myBitmap = BitmapFactory.decodeFile(imagePath);
Bitmap orientedBitmap = ExifUtil.rotateBitmap(imagePath, myBitmap);
답변
갤러리가 회전 된 이미지를 올바르게 표시하지만 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가 항상 작동하는 것 같지만 파일 경로를 얻는 것이 어려웠습니다. 내가 찾은 코드는 4.4 이전과 4.4 이후의 API를 다르게 만듭니다. 기본적으로 4.4+의 그림 URI에는 “com.android.providers”가 포함되어 있습니다. 이 유형의 URI의 경우 코드는 DocumentsContract를 사용하여 그림 ID를 가져온 다음 ContentResolver를 사용하여 쿼리를 실행하지만 이전 SDK의 경우 코드는 ContentResolver를 사용하여 URI를 쿼리합니다.
다음은 코드입니다 (죄송합니다 누가 게시했는지 신용 할 수 없습니다).
/**
* 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);
}
}