我创建了一个自定义相机。当我单击应用程序中的捕获按钮时,已拍摄图像。此外,我以字节数组的形式获取了名为 onpicturetaken 的函数。
。我使用称为 Glide 的库将字节数组转换为位图。
我的问题是,在三星设备中,图像自身旋转。我已经对此进行了很长时间的研究。我发现该库称为元数据提取库,以从字节[]获取EXIF信息并在其上旋转图像,但在三星设备上没有工作。元数据提取库每次返回肖像映像的值1时,这表明图像不需要旋转,但是,肖像模式下的图像始终为90度旋转。
每当以肖像模式拍摄照片时,它的前后摄像头和元提取库以90度的角度旋转。
的值为1。还有其他内容,然后是元数据提取提取库,这些库会提取Exif信息流数据?
注意:我不能使用exifinterface,因为它需要24的最小API级别,而我在API级别进行测试22
我尝试了许多解决方案,但是什么都没有起作用。有什么解决方案吗?
代码如下:
public void onPictureTaken(byte[] data, Camera camera) {
mCamera.stopPreview();
Glide.with(this).load(data)
.asBitmap().centerCrop().animate(R.anim.abc_fade_in)
.into(new SimpleTarget<Bitmap>(width, height) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
camera_view.setVisibility(View.INVISIBLE);
int w = resource.getWidth();
int h = resource.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
try {
InputStream is = new ByteArrayInputStream(data);
Metadata metadata = ImageMetadataReader.readMetadata(is);
final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
switch (exifOrientation) {
case 6:
mtx.postRotate(90);
break; // top left
case 3:
mtx.postRotate(180);;
break; // top right
case 8:
mtx.postRotate(270);
break; // bottom right
}
photo = Bitmap.createBitmap(resource, 0, 0, w, h, mtx, true);
/* Work on exifOrientation */
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我正在使用三星J5进行测试。
您不需要库。这是我写的几种方法,应该为您效果。
public static int getCapturedImageOrientation(Context context, Uri imageUri){
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imageUri.getPath());
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Log.i("RotateImage", "Exif orientation: " + orientation);
Log.i("RotateImage", "Rotate value: " + rotate);
} catch (Exception e) {
Log.e(TAG, "Error getting rotation of image");
}
return rotate;
}
public static int GetRotateAngle(Context context, Uri imageUri) {
String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION };
Cursor cursor = context.getContentResolver().query(imageUri, columns, null, null, null);
if (cursor == null) {
//If null, it is not in the gallery, so may be temporary image
return getCapturedImageOrientation(context, imageUri);
}
cursor.moveToFirst();
int orientationColumnIndex = cursor.getColumnIndex(columns[1]);
int orientation = cursor.getInt(orientationColumnIndex);
cursor.close();
return orientation;
}
我将它们包裹在称为ImageHelper的课程中。您可以这样使用:
rotateImage(ImageHelper.GetRotateAngle(Context, mCropImageUri));
当然,旋转代码是:
private void rotateImage(int degrees) {
Matrix mat = new Matrix();
mat.postRotate(degrees);
mCropImage = Bitmap.createBitmap(mCropImage, 0, 0, mCropImage.getWidth(), mCropImage.getHeight(), mat, true);
setImageForCropping(mCropImage);
}
当然,我正在为照片编辑,裁剪和缩放应用程序做所有这一切,因此您可以忽略一些附加功能,但这应该照顾好您。goodluck。
几乎在所有三星设备中,图像旋转问题很常见,在我的情况下,我正在使用三星注3,并且发生了同样的问题,但是我使用以下代码来解决此问题
public static Bitmap decodeFile(String path) { // this method is for avoiding the image rotation
int orientation;
try {
if (path == null) {
return null;
}
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 4;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeFile(path, o2);
Bitmap bitmap = bm;
ExifInterface exif = new ExifInterface(path);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.e("orientation", "" + orientation);
Matrix m = new Matrix();
if ((orientation == 3)) {
m.postRotate(180);
m.postScale((float) bm.getWidth(), (float) bm.getHeight());
// if(m.preRotate(90)){
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
return bitmap;
} else if (orientation == 6) {
m.postRotate(90);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
return bitmap;
} else if (orientation == 8) {
m.postRotate(270);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
return bitmap;
}
return bitmap;
} catch (Exception e) {
}
return null;
}
此代码对我有用,所以我希望这对您有帮助
可以使用Google提供的Exifinterface轻松修复。
您可以将其添加到您的项目中:
implementation "androidx.exifinterface:exifinterface:1.1.0"
之后,从图像中旋转并将其应用于映像视图:
// uri of the image
val inputStream = contentResolver.openInputStream(Uri.parse(uri))
val exifInterface = ExifInterface(requireNotNull(inputStream))
var rotation = 0
when (exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotation = 90
ExifInterface.ORIENTATION_ROTATE_180 -> rotation = 180
ExifInterface.ORIENTATION_ROTATE_270 -> rotation = 270
}