我创建了一个自定义相机。当我单击应用程序中的捕获按钮时,图像已被捕获。此外,我在名为 onPictureTaken 的函数中以字节数组的形式获取数据。
我正在使用名为Glide的库将字节数组转换为位图。
我的问题是在三星设备中图像会自行旋转。我已经研究它有一段时间了。我找到了一个名为元数据提取库的库,用于从 byte[] 获取 Exif 信息并旋转其上的图像,但它在三星设备上不起作用。对于肖像图像,元数据提取库每次返回值1,这表明图像不需要旋转,但是在肖像模式下拍摄的图像始终旋转90度。
每当以肖像模式拍摄照片时,前置摄像头和后置摄像头都会旋转 90 度,并且元提取库显示值为 1。
除了元数据提取提取库之外,还有其他东西可以提取 Exif 信息流数据吗?
注意: 我无法使用 ExifInterface,因为它需要最低 Api 级别 24,而我正在 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));
那么,rotateImage 代码当然是:
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);
}
当然,我做这一切都是为了一个照片编辑、裁剪和缩放应用程序,所以你可以忽略一些额外的东西,但这应该照顾你。祝你好运。
关于Android:三星设备自动旋转图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47778512/