Android 照相方向说明
前置摄像头的坐标系相对于竖屏手机坐标系逆时针旋转了270度,拍摄的image展示时先逆时针旋转了270度,因此需要再旋转90度与设备相同
后置摄像头的坐标系相对于竖屏手机坐标系顺时针旋转了90度,拍摄的image展示时逆时针旋转设备旋转的角度,因此如果设备顺时针旋转90度,那么image就不用做调整了(这个设备旋转角度是按照人面对后置摄像头,顺时针旋转)
前置摄像头:后置摄像头:
前置摄像头预览是承镜像关系的。
因为摄像头坐标系与设备是固定关系的,当旋转设备时,相应的摄像头坐标系也相应旋转。例如:
使用后置摄像头,设备逆时针旋转90度,即设备横屏拍摄,则摄像头坐标系也逆时针旋转90度,随后拍照图片坐标系会旋转270度,再逆时针旋转90度后调整正常
对于后置摄像头,imageBuffer是逆时针旋转设备已旋转的角度,前置摄像头则是顺时针设备已旋转的角度(设备旋转顺时针为正)。
private fun showImage(reader: ImageReader){
val image = reader.acquireNextImage()
val buffer = image.planes[0].buffer
val bytes = ByteArray(buffer.remaining())
buffer.get(bytes)
val characteristics = cameraManager!!.getCameraCharacteristics(cameraId!!)
val displayRotation: Int = windowManager.defaultDisplay.rotation
val degree = getJpegOrientation(characteristics,currentDeviceOrientation)
val matrix = Matrix()
.apply {
postRotate(degree.toFloat())
}
var bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.size)
bitmap = Bitmap.createBitmap(bitmap,0,0, bitmap.width ,bitmap.height,matrix,false)
if (null != bitmap){
binding.imageview.setImageBitmap(bitmap)
}
image.close()//需要关闭image,否则多次拍照会有问题
}
/**
* 根据设备旋转方向计算bitmap应该旋转的角度 为90的倍数
*
* @param c
* @param deviceOrientation 设备实时的旋转角度
* @return
*/
private fun getJpegOrientation(c: CameraCharacteristics, deviceOrientation: Int): Int {
var orientation = deviceOrientation
if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return 0
val sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION)!!
// Round device orientation to a multiple of 90
orientation = (orientation + 45) / 90 * 90
// Reverse device orientation for front-facing cameras
val facingFront =
c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT
if (facingFront) orientation = -orientation
// Calculate desired JPEG orientation relative to camera orientation to make
// the image upright relative to the device orientation
return (sensorOrientation + orientation + 360) % 360
}