我刚刚在我的应用中实现了相机。但是,当我拍摄照片并将所述照片设置为图像视图时,图像旋转。为什么会这样呢?当我垂直拍摄照片时,图像视图将水平显示,而当我水平拍摄照片时,图像视图将垂直显示。这是相机代码:
private fun openCamera() {
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE,"New Picture")
values.put(MediaStore.Images.Media.DESCRIPTION,"From the Camera")
image_uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values)
//camera intent
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri)
startActivityForResult(cameraIntent,IMAGE_CAPTURE_CODE)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
//called when user presses alow or deny from premissio request
when(requestCode){
PERMISSION_CODE ->{
if(grantResults.size > 0 && grantResults[0]== PackageManager.PERMISSION_GRANTED){
//PERMISSION FROM POPUP WAS GRANTED
openCamera()
}else{
//permisson from popup was denied
Toast.makeText(this,"Permission denied", Toast.LENGTH_SHORT).show()
}
}
}
}
@SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
//called when image was captured from camera intet
if(resultCode==Activity.RESULT_OK){
//set image captured to image view
image_view.setImageURI(image_uri)
//get location
//stop compass
}
}
这是我的图像视图布局:
<ImageView
android:id="@+id/image_view"
android:layout_width="283dp"
android:layout_height="331dp"
android:layout_marginTop="100dp"
android:background="@drawable/image1"
android:scaleType="centerCrop"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.515" />
这是在所有设备上发生,还是仅在某些设备上发生?据我认为,这并非应该在所有设备上都发生。你测试过吗?
您可以尝试以下解决方案。发生这种情况是因为大多数电话摄像头都是横向的,这意味着如果您以人像拍摄照片,则生成的照片将旋转90度。在这种情况下,相机软件应以查看照片的方向填充Exif数据。
此解决方案应该有效,但并非100%可靠,因为它取决于电话制造商的devive /相机Exif数据。
ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Bitmap rotatedBitmap = null;
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatedBitmap = rotateImage(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatedBitmap = rotateImage(bitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatedBitmap = rotateImage(bitmap, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
default:
rotatedBitmap = bitmap;
}
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);
}
注意:如果此解决方案不适合您,我可能会提供另一个解决方案。
几个月前,我遇到了同样的问题,我可以给你一种我使用过的方法,它可以那样工作。 Android Pie之前和之后都有一些差异。无论如何,通过这种方法,您将从photoUri获取位图,并且可以使用位图最终填充imageView。如果您有任何疑问,请在这里与我联系。
// Getting captured image as a bitmap
@TargetApi(Build.VERSION_CODES.P)
private fun getCapturedImage(selectedPhotoUri: Uri): Bitmap {
val bitmap = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.P -> MediaStore.Images.Media.getBitmap(
context?.contentResolver,
selectedPhotoUri
)
else -> {
val source = ImageDecoder.createSource(context!!.contentResolver, selectedPhotoUri)
ImageDecoder.decodeBitmap(source)
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {}, true)
} else {
MediaStore.Images.Media.getBitmap(context?.contentResolver, context?.let { getImageUri(it, bitmap) })
}
}
// Getting image Uri from the bitmap, its needed for android level 6 (sdk 23)
private fun getImageUri(inContext: Context, inImage: Bitmap): Uri {
val outImage: Bitmap = if (inImage.width > inImage.height) {
Bitmap.createScaledBitmap(inImage, 2560, 1440, true)
} else {
Bitmap.createScaledBitmap(inImage, 1440, 2560, true)
}
val path = MediaStore.Images.Media.insertImage(inContext.contentResolver, outImage, "Title", null)
return Uri.parse(path)
}