갤러리에서 이미지를 가져오는 Android가 회전합니다.
사용자가 갤러리에서 프로필 사진을 선택할 수 있도록 하려고 합니다. 내 문제는 일부 사진이 오른쪽으로 회전된 것처럼 나온다는 것입니다.
다음과 같이 이미지 선택기를 시작합니다.
Intent photoPickerIntent = new Intent();
photoPickerIntent.setType("image/*");
photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(photoPickerIntent, "Select profile picture"), Global.CODE_SELECT_PICTURE);
다음과 같이 onActivityResult에서 이미지를 가져옵니다.
Uri selectedPicture = data.getData();
profilePic = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), selectedPicture);
이미지가 회전하지 않도록 하려면 어떻게 해야 합니까?
업데이트:
내가 받은 몇 가지 유용한 답변에 따라 다음과 같은 작업 솔루션을 만들 수 있었습니다(잘 작성되지 않은 작업 코드일 뿐입니다). 개선할 수 있는 방법에 대한 피드백을 받고 싶습니다!
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == Global.CODE_SELECT_PICTURE) {
// Get selected gallery image
Uri selectedPicture = data.getData();
// Get and resize profile image
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = activity.getContentResolver().query(selectedPicture, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = null;
try {
File pictureFile = new File(picturePath);
exif = new ExifInterface(pictureFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
int orientation = ExifInterface.ORIENTATION_NORMAL;
if (exif != null)
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
loadedBitmap = rotateBitmap(loadedBitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
loadedBitmap = rotateBitmap(loadedBitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
loadedBitmap = rotateBitmap(loadedBitmap, 270);
break;
}
}
}
public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
ExifInterface 를 사용 하여 방향을 수정할 수 있습니다 .
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
URI에서 이미지의 절대 경로를 얻으려면 이 답변을 확인 하십시오.
2 Picasso 및 글라이드 라이브러리를 사용하는 한 줄 솔루션
이미지 회전 문제에 대한 많은 솔루션으로 많은 시간을 보낸 후 마침내 두 가지 간단한 솔루션을 찾았습니다. 추가 작업을 수행할 필요가 없습니다.
Picasso 라이브러리 사용 https://github.com/square/picasso
Picasso.with(context).load("http url or sdcard url").into(imageView);
글라이드 라이브러리 사용 https://github.com/bumptech/glide
Glide.with(this).load("http url or sdcard url").into(imgageView);
Picasso 및 Glide는 앱 포함에서 이미지를 처리하기 위한 매우 강력한 라이브러리입니다. 이미지 EXIF 데이터를 읽고 이미지를 자동 회전합니다.
나는 이러한 정적 방법을 사용합니다. 첫 번째는 방향을 결정하고 두 번째는 이미지를 회전하여 필요에 따라 축소합니다.
public static int getOrientation(Context context, Uri photoUri) {
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor == null || cursor.getCount() != 1) {
return 90; //Assuming it was taken portrait
}
cursor.moveToFirst();
return cursor.getInt(0);
}
/**
* Rotates and shrinks as needed
*/
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri, int maxWidth)
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) {
Log.d("ImageUtil", "Will be rotated");
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
Log.d("ImageUtil", String.format("rotatedWidth=%s, rotatedHeight=%s, maxWidth=%s",
rotatedWidth, rotatedHeight, maxWidth));
if (rotatedWidth > maxWidth || rotatedHeight > maxWidth) {
float widthRatio = ((float) rotatedWidth) / ((float) maxWidth);
float heightRatio = ((float) rotatedHeight) / ((float) maxWidth);
float maxRatio = Math.max(widthRatio, heightRatio);
Log.d("ImageUtil", String.format("Shrinking. maxRatio=%s",
maxRatio));
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
Log.d("ImageUtil", String.format("No need for Shrinking. maxRatio=%s",
1));
srcBitmap = BitmapFactory.decodeStream(is);
Log.d("ImageUtil", String.format("Decoded bitmap successful"));
}
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;
}
나는 이것을 이렇게 한다:
public void browseClick(View view) {
view.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.button_animation));
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
방향을 확인한 결과가 가장 흥미로울 것입니다.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath);
Matrix matrix = new Matrix();
Bitmap scaledBitmap;
if (loadedBitmap.getWidth() >= loadedBitmap.getHeight()){
matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 400, 300), Matrix.ScaleToFit.CENTER);
scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true);
} else{
matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 300, 400), Matrix.ScaleToFit.CENTER);
scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true);
}
File file = new File(getExternalCacheDir(), "image.jpg");
try {
FileOutputStream out = new FileOutputStream(file);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
Log.e("Image", "Convert");
}
imageView.setImageBitmap(scaledBitmap);
}
}
다음은 Kotlin으로 작성된 ExifInterface 접근 방식입니다.
fun modifyOrientation(bitmap: Bitmap, image_absolute_path: String): Bitmap {
val ei = ExifInterface(image_absolute_path)
val orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
return when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(bitmap, 90f)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(bitmap, 180f)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(bitmap, 270f)
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> flipImage(bitmap, true, false)
ExifInterface.ORIENTATION_FLIP_VERTICAL -> flipImage(bitmap, false, true)
else -> bitmap
}
}
private fun rotateImage(bitmap: Bitmap, degrees: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(degrees)
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
private fun flipImage(bitmap: Bitmap, horizontal: Boolean, vertical: Boolean): Bitmap {
val matrix = Matrix()
matrix.preScale((if (horizontal) -1 else 1).toFloat(), (if (vertical) -1 else 1).toFloat())
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
피카소 사용:
Picasso.get().load("이미지 경로").into(Imageview);
Picasso.with(this) 는 이제 다음으로 대체됩니다.
피카소.get()
피카소 라이브러리 : https://github.com/square/picasso
추가: build.gradle 파일에 'com.squareup.picasso:picasso:2.71828' 구현
Picasso는 이미지 자동 회전을 처리합니다.
ReferenceURL : https://stackoverflow.com/questions/31925712/android-getting-an-image-from-gallery-comes-rotated
'IT이야기' 카테고리의 다른 글
AF네트워킹 및 백그라운드 전송 (0) | 2021.10.16 |
---|---|
Sklearn, gridsearch: 실행 중 진행 상황을 인쇄하는 방법 (0) | 2021.10.15 |
-XX:-TieredCompilation (0) | 2021.10.15 |
Swift - 프로토콜 확장 - 속성 기본값 (0) | 2021.10.15 |
ggmap 오류: GeomRasterAnn이 호환되지 않는 버전의 ggproto로 빌드되었습니다. (0) | 2021.10.15 |