我正在捕捉图像并将其设置为图像视图。
public void captureImage() {
Intent intentCamera = new Intent("android.media.action.IMAGE_CAPTURE");
File filePhoto = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
imageUri = Uri.fromFile(filePhoto);
MyApplicationGlobal.imageUri = imageUri.getPath();
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intentCamera, TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intentFromCamera) {
super.onActivityResult(requestCode, resultCode, intentFromCamera);
if (resultCode == RESULT_OK && requestCode == TAKE_PICTURE) {
if (intentFromCamera != null) {
Bundle extras = intentFromCamera.getExtras();
if (extras.containsKey("data")) {
bitmap = (Bitmap) extras.get("data");
}
else {
bitmap = getBitmapFromUri();
}
}
else {
bitmap = getBitmapFromUri();
}
// imageView.setImageBitmap(bitmap);
imageView.setImageURI(imageUri);
}
else {
}
}
public Bitmap getBitmapFromUri() {
getContentResolver().notifyChange(imageUri, null);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
return bitmap;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
但问题是,某些设备上的图像每次旋转时。例如,在三星设备上,它工作得很好,但在索尼Xperia上,图像旋转了90度,在东芝Thrive(平板电脑)上旋转了180度。
下面的代码与我一起工作,它从fileUri获得位图,并在需要时进行旋转固定:
private fun getCapturedImage(selectedPhotoUri: Uri): Bitmap {
val bitmap = when {
Build.VERSION.SDK_INT < 28 -> MediaStore.Images.Media.getBitmap(
this.contentResolver,
selectedPhotoUri
)
else -> {
val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri)
ImageDecoder.decodeBitmap(source)
}
}
// If the image is rotated, fix it
return when (ExifInterface(contentResolver.run { openInputStream(selectedPhotoUri) }).getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
ExifInterface.ORIENTATION_ROTATE_90 ->
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
postRotate(90F) }, true)
ExifInterface.ORIENTATION_ROTATE_180 ->
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
postRotate(180F) }, true)
ExifInterface.ORIENTATION_ROTATE_270 ->
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
postRotate(270F) }, true)
else -> bitmap
}
}
所选的答案使用回答这个问题和类似问题的最常用方法。但是,三星的前置和后置摄像头都不能使用。对于那些正在为三星和其他主要制造商寻找可以在前置和后置摄像头上工作的解决方案的人来说,nvhausid的回答非常棒:
https://stackoverflow.com/a/18915443/6080472
对于那些不想点击的人来说,相关的魔法是使用CameraInfo而不是依赖于EXIF。
Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
Bitmap bitmap = rotate(realImage, info.orientation);
完整代码在链接中。
这里的解决方案基于上面的解决方案,但只需要上下文和图像文件作为输入
public static Bitmap rectifyImage(Context context,File imageFile){
Bitmap originalBitmap= BitmapFactory.decodeFile(imageFile.getAbsolutePath());
try{
Uri uri=Uri.fromFile(imageFile);
InputStream input = context.getContentResolver().openInputStream(uri);
ExifInterface ei;
if (Build.VERSION.SDK_INT > 23)
ei = new ExifInterface(input);
else
ei = new ExifInterface(uri.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(originalBitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(originalBitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(originalBitmap, 270);
default:
return originalBitmap;
}
}catch (Exception e){
return originalBitmap;
}
}
public static Bitmap rotateImage(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
}
你可以像文档中的谷歌那样读取摄像头传感器的方向:https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html
SENSOR_ORIENTATION
Added in API level 21
Key<Integer> SENSOR_ORIENTATION
Clockwise angle through which the output image needs to be rotated to be upright on the device screen in its native orientation.
Also defines the direction of rolling shutter readout, which is from top to bottom in the sensor's coordinate system.
Units: Degrees of clockwise rotation; always a multiple of 90
Range of valid values:
0, 90, 180, 270
This key is available on all devices.
示例代码:
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
int orientation = 0;
try {
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
}
catch (Exception e)
{
}